Separate logical ownership, render publication, and GPU retirement across live entities, landblocks, particles, textures, mesh arenas, portal/UI teardown, and per-frame scratch storage. Add bounded DAT/texture caches, upload budgets, three-frame fence retirement, exact-incarnation appearance reconciliation, frame pacing, and extensive lifetime conformance coverage.\n\nThe seven-destination connected route now cuts peak working/private memory roughly in half, returns Caul to 125-153 FPS locally, and produces no WER or AMD reset.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
36 lines
1.3 KiB
C#
36 lines
1.3 KiB
C#
namespace AcDream.Core.World;
|
|
|
|
/// <summary>
|
|
/// Allocates stable, collision-free local ids for dat-authored
|
|
/// <c>LandBlockInfo.Objects</c> and building shells.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The top nibble is fixed at <c>0xC</c>. The remaining 28 bits encode the
|
|
/// complete landblock X byte, Y byte, and a 12-bit per-landblock counter:
|
|
/// <c>0xCXXYYIII</c>. The former <c>0xC0XXYYII</c> packing had only eight
|
|
/// counter bits, so a legitimate dense retail landblock aborted after 255
|
|
/// entries and was retried every time it streamed into view.
|
|
/// </remarks>
|
|
public static class LandblockStaticEntityIdAllocator
|
|
{
|
|
public const uint MaxCounter = 0xFFFu;
|
|
|
|
public static uint Base(uint landblockX, uint landblockY) =>
|
|
0xC0000000u
|
|
| ((landblockX & 0xFFu) << 20)
|
|
| ((landblockY & 0xFFu) << 12);
|
|
|
|
public static uint Allocate(uint landblockX, uint landblockY, ref uint counter)
|
|
{
|
|
if (counter > MaxCounter)
|
|
{
|
|
throw new InvalidDataException(
|
|
$"Landblock ({landblockX & 0xFFu:X2},{landblockY & 0xFFu:X2}) exceeds the 4096-entry static entity id namespace.");
|
|
}
|
|
|
|
return Base(landblockX, landblockY) + counter++;
|
|
}
|
|
|
|
public static bool IsInNamespace(uint entityId) =>
|
|
(entityId & 0xF0000000u) == 0xC0000000u;
|
|
}
|