Commit graph

15 commits

Author SHA1 Message Date
Erik
c1a029edf9 feat(render) Campaign FW1: NINE of ten fixtures conformant - the degrade arm
The moving-fixture divergence was the building degrade ladder:
GfxObjDegradeInfo::get_degrade @0x0051e4b0 (Ghidra-verified - BN's
FPU-flag pseudo-C misread BOTH arm selection and one formula) slides
each level's threshold from ideal toward MAX as the multiplier
approaches 1, and the live client runs the positive arm at ~0.99, so
level 0's portal-bearing BSP survives to ~max_dist (48 for the Holtburg
cottages), not ideal (24). The recon note's "deg_mul = -0.99" was a
sign misread; the negative arm's threshold slides toward MIN and
contradicts the fixtures from both directions. With the two-arm port,
holtburg-walkout, holtburg-transitions, and holtburg-walkabout pass
every pairable frame - the walkout-F2 microscope's prediction
(103,100 | 100x3 | 124 through the cottage exit views) landed exactly.

Also this round, falsified and reverted: a BN-driven swap of the
portal walker's negative/in-plane arms (Ghidra shows side 1 = negative
EMITS, side 2 = in-plane does not - the original port was correct; the
swap broke four fixtures). The walker docs and unit tests now pin the
Ghidra-verified truth table.

Parked with findings: foundry-entry F67 (right flood set, one
plane-side classification at the +/-eps boundary orders 11d before
116/118) and doorway-still (retail shows zero floods at a pose one
meter from walkout-F2's flooding pose; multi-portal clip boundary).

Suites: Walk 124/3 skips; hermetic 6,687/0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 11:34:45 +02:00
Erik
66f9e0d459 feat(render) Campaign FW1: SIX OF TEN FIXTURES FULLY CONFORMANT
Three final pins complete the still-fixture set: (1) the CELL portal
side decode is the INVERSE of the 0x2 bit (uniform with the building
convention; the doorway-still flood proved it - ov=2 n=3 exact, and
foundry-deep stays green); (2) interior frames key the landscape order
off the OUTSIDE-projected landcell (get_outside_cell_id - derived from
the camera origin); (3) the outdoor pview has draw_landscape=FALSE so
look-in floods discard exit portals - the ov=0 pattern of every traced
look-in. CONFORMANT: foundry-deep (every frame), doorway-still,
street-outdoor, terrace-center, terrace-edge (the #456 acceptance
pose), cathedral-arrival - full frames identical to retail. The moving
four diverge only at punch-edge frames (walkabout F9, foundry-entry
F67) - pose-timing sensitivity parked in the driver Skip note.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 11:07:29 +02:00
Erik
28475d0544 feat(render) Campaign FW1: street fixture retail-exact except flood depth
Three pinned corrections close the outdoor frame: (1) the camera basis
RE-pinned to +Y-forward - the terrace-edge fixture EXTERNAL ground
truth (the ledge faces the F518 vista, east) overrules the walkabout
motion sweep, whose camera was mouse-turned off the run line; (2)
alwaysDrawObjects (.data default 1 @0x00820ed4) drawn into the
DrawSortCell gate - cell contents draw for every cell of an in-view
block; (3) the building portal side decode data-pinned as the INVERSE
of the cell 0x2 bit (the sweep winning arm). Street result: all 13
buildings in retail exact order (a9b3003c in, aab50002 correctly
absent), punches at exactly 001a and 0022 opening the exact first
cells 16e/164. SOLE remaining delta: look-in flood depth (mine 1 cell,
retail 3-4) - the doorway-still fixture adjudicates the interior flood
in isolation next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 11:02:16 +02:00
Erik
e23a589a6b feat(render) Campaign FW1: port the exact retail degrade selection
UpdateViewerDistance @0x0050e030 + get_degrade @0x0051e4b0 ported with
live-pinned globals: distance measured to the part SCALED SORT CENTER,
effective = max(0, dist - s_rDegradeDistance [live 100]), level = first
with effective < IdealDist (the live auto_update_deg_mul<=0 arm), else
the last level. WalkBuildingDegradeLevel carries the full authored
bands; the adapter fills sort centers; the replay context measures to
the transformed sort center. Sweep state after the rule: the level-0
building set is now correct; the residual divergence is the per-portal
side/clip gate (my arms punch a near-complement of retail two) - the
sweep driver carries the next instrument in its Skip note.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 10:55:19 +02:00
Erik
b3ac5872e9 feat(render) Campaign FW1: the degrade-level BSP gate kills the wrong punches
The offline degrade probe proved the mechanism: every Holtburg building
carries PORT nodes ONLY in its level-0 GfxObj (out to ~24-48 m); every
degraded level has zero. Retail walks the CURRENT degrade level BSP
(part->gfxobj[deg_level]) - that is what limits look-in punches to the
nearest buildings. WalkBuilding gains the degrade ladder +
SelectDrawingBsp (band pick; UpdateViewerDistance hysteresis is a port
TODO), the walk selects per viewer distance, the adapter builds
per-level BSPs, and the stab-list load rule (CLandBlock::init_buildings
@0052fd80: a full-res block loads exactly its buildings portal stab
cells) replaces load-everything in the landscape builder. The sweep now
shows clean rosters with all far-building punches gone; remaining
deltas: the near buildings 001a/0022 (50 m/28 m center distance vs the
48 m band edge - sphere-adjusted distance/hysteresis to port) and the
one ring-1 frustum boundary pair (aab50002/a9b3003c).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 10:51:05 +02:00
Erik
6caedf25f9 fix(render) Campaign FW1: keep the conformance DAT adapter behind the seam guard
RuntimeDatAccessArchitectureTests correctly flagged WalkWorldDatAdapter
taking raw DatCollection in production. The adapter is the conformance
harness world builder, so it moves into the test assembly; the FW3
production adapter will consume the content-owner seam. Hermetic suite
back to 6,687/0; adapter + conformance 10/10.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 10:24:51 +02:00
Erik
0f01fb4430 feat(render) Campaign FW1: FIRST TRACE CONFORMANCE GREEN (foundry-deep)
The replay harness reconstructs the camera from a pose-stamped oracle
frame (Frame quaternion w,x,y,z storage order; +Y forward / +Z up;
landblock-local origin) and drives the ported walk over adapter-built
cells (cell transforms from EnvCell.Position now populated). The
foundry-deep fixture - the pure-interior frame shape - reproduces
retail EXACTLY on every complete frame: DI + DC(ov=0, [cell]) with no
landscape, 39/39. Conventions are now pinned by live retail output; the
remaining nine fixtures need the outdoor world build-out (landscape
blocks, terrain z-slabs, building transforms + active-view clip) and
join the same gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 10:23:39 +02:00
Erik
17c57bbd1d feat(render) Campaign FW1: the DAT adapter + ground-truth roster conformance
WalkWorldDatAdapter builds WalkCell/WalkBuilding from real DATs: cell
portals with the PortalSide flag bit and signed OtherPortalId, portal
polygons + planes via the production formula, stab lists, building
position cells (24 m landcell math), building portals with stab lists,
and the drawing-BSP -> WalkBspNode conversion incl. PORT-node PortalRef
polygons (the previously missing consumers the 2026-08-30 survey named).
Lane=InstalledDat conformance: every BLD id the FW0 oracle traces saw
retail draw (26 buildings over 7 landblocks) resolves in the adapter
roster at its EXACT position cell; the traced look-in cells build with
portals/polygons/stabs; the sanctuary BSP carries portal refs. 9/9.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 10:16:33 +02:00
Erik
4b401a08ed feat(render) Campaign FW1: the frame-walk composition root
RetailFrameWalk composes the ported machinery into retail frame shapes:
SmartBox::RenderNormalMode rooting (camera-cell low word < 0x100),
PView::DrawInside + the DrawCells event half (interior pview, the
traces pv=009d4a80), LScape::draw (per-view visibility, blocks
far-to-near, per-block cells far-to-near, buildings at their cell turn)
and RenderDeviceD3D::DrawBuilding (BLD at entry before the degrade
check; two-pass BSP portal walk per active view on the outdoor pview,
the traces pv=009d4b08). WalkLandscape ports the block grid +
draw_check_blocks/landcell_check visibility (192 m/24 m pitch,
viewer-relative, union across views, never downgrade). Six composition
tests: outdoor far-to-near emission, degrade-entry event, interior
ov=0/ov=1 shapes, rooting, complete view unwind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 10:06:09 +02:00
Erik
f05b93b5b5 feat(render) Campaign FW1: port the building look-in machinery
WalkBuildingPortals transcribes the portal-only drawing-BSP walk
(BSPTREE/BSPNODE::build_draw_portals_only @0x00539860/@0x0053c100,
BSPPORTAL::portal_draw_portals_only @0x0053d870 - opposite-child-first
= far-to-near emission, IN_PLANE PORT arm emits nothing),
PView::DrawPortal @0x005a5ab0 (stab add/remove_views around the
look-in, DrawCells on pass-2 success), and the CBldPortal
PView::ConstructView overload @0x005a59a0 (side must EQUAL the authored
portal_side, clip survival, Visible destination, punch on pass 1, flood
recursion on pass 2). Punch surfaces via the pass sink for FW1
conformance; the depth-fan submission itself is FW2. Six tests: BSP
emission order both viewer sides, in-plane suppression, pass-1
punch-no-flood, pass-2 flood + DC event, sidedness rejection, unloaded
destination skip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 10:01:45 +02:00
Erik
161ffaf4e9 feat(render) Campaign FW1: port the PView interior flood
WalkPView transcribes ConstructView @0x005a57b0, InitCell @0x005a4b70,
InsCellTodoList @0x005a4f50 (nearest-first pop), ClipPortals @0x005a5520,
OtherPortalClip @0x005a5400 (inverted ==0 sidedness), AddViewToPortals
@0x005a52d0 (update_count watermark, duplicate-reach arm), AddToCell
@0x005a4d90, SetOtherSeen @0x005a4e30, FixCellList/AdjustCellPlace/
AdjustDrawList/AdjustCellView @0x005a5250/0x005a5010/0x005a4e90/
0x005a5770, plus set_view and PView::GetClip @0x005a4320 over the
WalkScreenClip chain. Resolves and documents the portal-flag convention
(inflag=1 = the portal FACES the viewer and feeds max_indist; inflag=0 +
armed seen = an opening — the same side condition building look-ins
require), which the PDB names obscure. WalkWorld supplies the cell model
and frame-context seam. Six synthetic-world flood tests pass on first
run: traversal, facing rejection with the exact distance key, exit-view
raising, entry-portal no-ping-pong, chain ordering, unloaded skips.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 09:58:28 +02:00
Erik
11ca527fb9 feat(render) Campaign FW1: port the view machinery (xformStart, polyClipFinish, copy_view)
WalkScreenClip ports PrimD3DRender::xformStart @0x0059b990 (homogeneous
viewport coords, y-flip, no divide) and ACRender::polyClipFinish
@0x006b6d00 (w>=cdstW plane then last-to-first edge passes, inside =
side<=0 homogeneous 2D cross, reverse-scan passes with original-winding
restore, <3 early-outs). WalkViews ports the view_type/portal_view_type
data model and Render::copy_view @0x0054dfc0 exactly: in-place divide,
the keep/last/stl/second pruning bookkeeping with all three closing
wrap checks, <3 reject leaving dest untouched, cap 31, pool-base reset
at view_count==0, retail fabs on copy, and edge planes
N=normalize(cross(ray[k+1],ray[k])), d=-dot(N,eye) behind an
IWalkRayCaster seam. Thirteen new tests; Walk namespace 85/85.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 09:50:03 +02:00
Erik
368c480bc2 feat(render) Campaign FW1: flood decomp appendix + the visibility math port
The second decomp round (flood bookkeeping/propagation, view-clip
support, landscape visibility) is archived Ghidra-arbitrated - it caught
a load-bearing BN inversion (InsCellTodoList pops NEAREST-first, which
is what makes the draw list far-to-near) and three more traps (the 192m
elided constant, the min/max double positional swap, the copy_view
cross order - the walk doc section 6 is corrected). WalkVisibilityMath
ports get_pt_limit @0x0054b840, get_clip_height @0x0054cff0,
corner/block_plane_check @0x0054b930/@0x0054d060, block_check
@0x0054dc50, and viewconeCheck @0x0054c250 with retail boundary
semantics (strict cull, inclusive partial, touch-out=Outside /
touch-in=EntirelyInside) under 23 focused tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 09:44:49 +02:00
Erik
0926b55eaf feat(render) Campaign FW1: the walk event vocabulary
WalkEvent mirrors the FW0 oracle-trace vocabulary one-to-one (Landscape,
Building, DrawInside, DrawCells) as the conformance surface RetailFrameWalk
emits; the FW2 ordered draw stream layers on later without changing it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 09:36:51 +02:00
Erik
d1fc4a0986 feat(render) Campaign FW1: port the retail landscape draw-order machinery
LandWalkOrder ports LScape::get_block_order @0x00504c50 (near-to-far ring
list, walked backwards by LScape::draw), CLandBlock::calc_sq_draw_order
@0x0052f4a0 (cell array filled backwards from the closest cell),
LandDefs::get_dir @0x005a9aa0, and the 9-case closest-cell direction
switch. The shared 8-slot ring coefficient tables were byte-decoded from
the PDB-paired binary (block VA 0x0081cc6c.., cell VA 0x0081df88.. -
identical sets); the intra-ring visit order is preserved exactly because
it decides draw order between equidistant blocks and the oracle traces
pin it. Thirty focused tests cover coverage/ordering invariants, the
hand-expanded ring-1 pattern, and the direction/closest-cell contracts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 09:35:26 +02:00