feat(pathfinding): .swb format v8 compact index (#3b) (#2471)

## Summary
Phase #3b (final roadmap item), stacked on #2470. Compacts the index trailer from 20 to 8 bytes/chunk.

Trammel: 19.2 MB → 17.9 MB. Roadmap total: 565 MB → 17.9 MB (−96.8%).

## Details
- Trailer stores `{ u32 packedKey = (ChunkX << 16) | ChunkY, u32 recordLength }` per chunk, in record write order; the file offset is dropped and reconstructed by cumulative recordLength from HeaderSize.
- No record reordering, no varint; fixed-stride, TryReadChunk unchanged.
- Also simplifies the accumulated `.swb` code comments across the stack.
- Format v8; v7 files rejected and re-baked once.

## Tests
v8 multi-chunk round-trip (cumulative offset reconstruction) + the v6/v7 suite; full pathfinding suite green; Release build clean.
This commit is contained in:
Kamron Batman 2026-06-07 01:22:20 -07:00 • committed by GitHub
parent c265bcbb5e
commit c7aaf33de9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 960 additions and 868 deletions

View file

@ -242,8 +242,8 @@ public static class StepProbe
/// </summary>
public static int ComputeStandingZ(Map map, int x, int y, int locZ)
{
GetStaticStartZ(map, x, y, locZ, canSwim: false, cantWalk: false,
out _, out _, out var zCenter);
GetStaticStartZ(map, x, y, locZ, canSwim: false, cantWalk: false, out _, out _, out var zCenter);
return zCenter;
}
@ -255,11 +255,7 @@ public static class StepProbe
/// </summary>
public static int ComputeSwimStandingZ(Map map, int x, int y)
{
if (map == null || map == Map.Internal)
{
return int.MinValue;
}
if (x < 0 || y < 0 || x >= map.Width || y >= map.Height)
if (map == null || map == Map.Internal || x < 0 || y < 0 || x >= map.Width || y >= map.Height)
{
return int.MinValue;
}
@ -290,8 +286,7 @@ public static class StepProbe
/// Mirrors GetStartZ from MovementImpl, parameterized by canSwim / cantWalk.
/// </summary>
private static void GetStaticStartZ(
Map map, int x, int y, int locZ, bool canSwim, bool cantWalk,
out int zLow, out int zTop, out int zCenter
Map map, int x, int y, int locZ, bool canSwim, bool cantWalk, out int zLow, out int zTop, out int zCenter
)
{
var landTile = map.Tiles.GetLandTile(x, y);
@ -300,8 +295,7 @@ public static class StepProbe
// Mirrors MovementImpl: impassable + swim on water is OK; otherwise block on
// cantWalk or impassable.
var landBlocks = (cantWalk || impassable)
&& !(impassable && canSwim && (flags & TileFlag.Wet) != 0);
var landBlocks = (cantWalk || impassable) && !(impassable && canSwim && (flags & TileFlag.Wet) != 0);
map.GetAverageZ(x, y, out var landZ, out var landCenter, out var landTop);
@ -356,8 +350,7 @@ public static class StepProbe
/// Items and mobile collision phases are omitted.
/// </summary>
private static bool CheckStaticStep(
Map map, int x, int y, int startZ, int startTop, bool canSwim, bool cantWalk,
out int newZ
Map map, int x, int y, int startZ, int startTop, bool canSwim, bool cantWalk, out int newZ
)
{
newZ = 0;
@ -371,8 +364,7 @@ public static class StepProbe
var flags = TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags;
var impassable = (flags & TileFlag.Impassable) != 0;
var landBlocks = (cantWalk || impassable)
&& !(impassable && canSwim && (flags & TileFlag.Wet) != 0);
var landBlocks = (cantWalk || impassable) && !(impassable && canSwim && (flags & TileFlag.Wet) != 0);
var considerLand = !landTile.Ignored;