Commit graph

431 commits

Author SHA1 Message Date
Erik
c7f5f251f8 feat(render): add integer vertex attributes and the terrain tiling binding
A scouting pass over V4d stopped before writing code and reported three gaps between terrain and the pinned contract. All three verified against source.

The load-bearing one: terrain_modern.vert declares locations 2-5 as uvec4 and TerrainModernRenderer feeds them with glVertexAttribIPointer, but GpuVertexFormat had no integer format and the encoder only issued glVertexAttribPointer. GL leaves an integer shader input undefined if it arrives through the float path, and Vulkan needs the format named as R8G8B8A8_UINT rather than _UNORM, so UByte4Normalized cannot stand in for it. Those packed bytes carry terrain-type, road and split-direction codes that drive every blend decision, so normalising them would have produced garbage rather than an approximation. Adds GpuVertexFormat.UByte4UInt and an integer branch in the encoder.

Also adds a uniform binding for terrain's 36-float per-layer tiling array, which at 144 bytes cannot ride in the 96-byte push-constant block or Vulkan's guaranteed 128-byte ceiling, and has no uniform-array verb to reach it otherwise.

Corrects two V4d plan rows: TerrainAtlas belongs to V4t with the rest of the texture stack, and terrain has no GPU timer to port since its diagnostics use a CPU stopwatch. The uView/uProjection convergence gets its own pixel-gated sub-commit because it moves a matrix product from per-vertex GPU evaluation to a CPU multiply, and that rounding effect should be attributable on its own.

Files #250: two zero-allocation tests fail about one run in three on an unchanged tree, independent of this campaign. That noise trains everyone to re-run until green, which is how a real regression gets waved through.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 21:11:48 +02:00
Erik
79ee2361ad docs(render): close Campaign V slice V4a and file #249
V4a landed on the second attempt at 096dd203, verified independently: offline pixel gate passing at 22 differing pixels against an 8-26 same-commit noise band, App suite at exactly the 3,843/3 baseline, 26 files touched, no encoding damage. Three audits of the reverted first attempt found defects that outlive it - resident bindless handles never released, no test coverage for the Multisample state dimension, and no encoding guard - now tracked as #249.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 19:41:08 +02:00
Erik
ec414d60cd docs(render): Campaign V slice V3 - clip-space and sRGB audit
V3 exists to verify the assumptions the whole Vulkan design rests on, before
V6 builds on them. The central claim held. One plan assumption did not, and
catching it here is the slice paying for itself.

Confirmed: every projection reaching a shader is built by
Matrix4x4.CreatePerspectiveFieldOfView, so NDC z is already [0,1] - Vulkan's
own convention - and no projection rework is needed. There are no orthographic
projections in production at all; the retained UI converts pixel coordinates
straight to NDC with a constant z, so V4a has no matrix to convert. Phase U.3's
clip planes are derived and compared entirely in clip space with plane.z always
zero, making them insensitive to both the depth convention and the viewport Y
flip. SkyProjection.WithDepthRange is the only hand-written matrix edit and it
re-derives the same D3D-convention mapping rather than a GL-style depth scale.

Corrected: the plan specified a B8G8R8A8_SRGB swapchain "matching the GL
FramebufferSrgb contract." That contract does not exist. FramebufferSrgb is
enabled only inside the throwaway capability probe and disabled immediately,
never on the real backbuffer; no texture uses an sRGB internal format; no
shader converts gamma. The renderer is UNORM end to end, so the correct
swapchain format is B8G8R8A8_UNORM. Shipping _SRGB would have applied an encode
to already-display-space values - a global brightening on every frame that
nothing before V7 would have caught.

Two acceptance items carried forward to V6/V7: the Vulkan encoder must flip
scissor rectangles itself, because vkCmdSetScissor is top-left-origin and the
negative viewport height does not affect it; and the V7 differential must
launch both backends with ACDREAM_MSAA_SAMPLES=0, since MSAA is fixed at window
creation and cannot be toggled mid-session.

Filed #248 for FrustumCuller's near-plane extraction, which uses the GL
[-1,1] Gribb-Hartmann formula against [0,1] matrices. It is provably
over-inclusive rather than over-culling, and it is pure CPU math untouched by
the backend swap, so it is tracked rather than fixed inside this campaign.

No code changed, so the pixel gate is trivially satisfied.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 16:20:34 +02:00
Erik
f6275f4501 docs: reconcile project state and refresh README
Some checks failed
Headless portability / portable-headless (ubuntu-latest) (push) Has been cancelled
Headless portability / portable-headless (windows-latest) (push) Has been cancelled
Headless portability / linux-graphical (push) Has been cancelled
2026-07-27 12:53:31 +02:00
Erik
921712f412 fix(interaction): restore retail loot placement and world-drop projection 2026-07-27 00:03:15 +02:00
Erik
4d095be286 fix(physics): traverse prepared indoor portal topology 2026-07-27 00:02:44 +02:00
Erik
81b31857c6 docs(runtime): close interaction transaction ownership
Record the exact J5.2 owner boundary, retail ordering, Release and connected evidence, rollback, and J5.3 handoff across architecture, roadmap, milestones, agent instructions, and durable memory.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 11:22:07 +02:00
Erik
be73bccf5a docs(runtime): close canonical action ownership
Record J5.1's exact Runtime selection, combat, and target-mode owner, its automated and connected acceptance evidence, rollback, and the J5.2 interaction-transaction boundary. Synchronize architecture, roadmap, milestones, issues, and agent handoff state.

Co-authored-by: Codex <codex@openai.com>
2026-07-26 10:54:12 +02:00
Erik
2c67a2c3ba docs(runtime): close gameplay-state ownership
Record J4.5 canonical shortcut and spellbook command ownership, combined failure and graphical/headless parity evidence, the 8,544-test Release gate, exact-binary lifecycle and nine-stop acceptance, rollback instructions, and the J5 boundary.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 10:17:39 +02:00
Erik
9496c01be1 docs(runtime): close J2 session lifetime gate
Record the canonical Runtime session/transport cutover, exact rollback, full Release evidence, and exact-binary lifecycle acceptance. Advance the active execution pointer and durable memory to J3 identity and object ownership.

Validated by the existing 79 Runtime tests, 3,776 App tests with three skips, 8,428 complete Release tests with five skips, and logs/connected-world-gate-20260725-193936/report.json.

Co-authored-by: Codex <codex@openai.com>
2026-07-25 19:46:47 +02:00
Erik
f84624b1e9 docs(runtime): close J1 contract gate
Record the exact-binary connected lifecycle/reconnect acceptance, synchronized active pointers, rollback, and durable evidence before session ownership moves in J2.
2026-07-25 19:16:30 +02:00
Erik
afebbe3eca docs(physics): close Slice I evidence and roadmap
Record the accepted flat-authoritative collision cutover, production parsed-graph removal, exact rollbacks, zero-residency connected gates, and RDP measurement boundary. Reconcile architecture, milestones, roadmap, issue ledger, agent instructions, and the active Slice J handoff.

Validated by the existing zero-warning Release build, 8,413 passing Release tests with five pre-existing skips, 201 focused closeout tests, and both exact-binary connected routes.

Co-authored-by: Codex <codex@openai.com>
2026-07-25 18:44:43 +02:00
Erik
16d182c2f0 perf(physics): reuse reset-complete transition scratch
Mirror retail's ten-deep LIFO transition lifetime, retain all query scratch with complete reset contracts, and remove Tier-0 enum boxing without changing collision decisions. Fresh and retained engines are bit-identical across the expanded oracle, while measured transition profiles now allocate 0 bytes per resolve.
2026-07-25 14:37:02 +02:00
Erik
14b48cf553 docs(portal): record arrival visual gate
Close the retained-projection regression after the user confirmed both /ls and spell recall show the retail purple materialization silhouette without a character pop or leftover animation/effect tail.

Co-authored-by: OpenAI Codex <codex@openai.com>
2026-07-25 10:34:48 +02:00
Erik
7aa9618136 fix(portal): commit destination projection before reveal
Retail installs the destination CObjCell before hidden world simulation resumes. Rebucket the retained local-player projection inside the Place transaction so Hidden/UnHide scripts and particles settle behind the portal viewport instead of firing after reveal. Preserve the existing unloaded-cell scheduler gate and pin the ordering with a cross-landblock placement test.

Co-authored-by: OpenAI Codex <codex@openai.com>
2026-07-25 10:32:21 +02:00
Erik
1a14812c44 fix(world): restore portal and distant use lifecycles 2026-07-25 09:59:25 +02:00
Erik
f1a8d36682 docs(performance): close modern runtime slice H 2026-07-25 06:15:13 +02:00
Erik
b9cbf5e040 perf(rendering): reconcile only changed attachments 2026-07-25 05:18:33 +02:00
Erik
f2a015be8e perf(ui): retain shaped report text 2026-07-25 05:11:12 +02:00
Erik
5ecaa5612d docs(runtime): approve render scene program 2026-07-24 21:01:40 +02:00
Erik
e7d9d6fa7d docs(runtime): close cost-budgeted streaming slice
Record the exact physical-display evidence, ownership fixes, budget semantics, and performance deltas that close Slice E. Reconcile the architecture, roadmap, milestones, issues, documentation map, and session instructions before the explicit F/G approval gate.

Co-authored-by: Erik Nilsson <erikn@users.noreply.github.com>
2026-07-24 20:52:20 +02:00
Erik
2ff8f844b0 perf(streaming): reserve destination reveal capacity
Join destination scheduling to the canonical reveal generation, protect its share across every typed frame-budget dimension, and prevent stale work from clearing a replacement reservation. Remove forced incomplete materialization and project retail's centered portal wait cue while the authored tunnel remains active.

Tests: Release build clean; 91 focused reservation/reveal tests; full solution 8,158 passed, 5 skipped.

Co-authored-by: Codex <noreply@openai.com>
2026-07-24 19:39:23 +02:00
Erik
98f1ac8934 perf(streaming): cursor publication across frame budgets 2026-07-24 19:10:18 +02:00
Erik
bb16f74fd4 perf(streaming): quiesce retired generations and budget teardown
Publish the retail blocking-for-cells edge before deferred recenter work, freeze old-world presentation/simulation/audio, and advance full-window retirement from exact metered entity and owner cursors. This removes synchronous portal teardown without allowing retained owners to remain observable.
2026-07-24 18:29:52 +02:00
Erik
66690805c5 docs(render): close unified residency slice 2026-07-24 17:06:17 +02:00
Erik
f2644d42c2 perf(render): bound animation and alpha scratch residency
Complete Slice D3 by replacing the unbounded animation dictionary with a concurrent byte/count LRU and by putting the three retail alpha scratch owners behind one typed aggregate budget. Preserve immediate growth and draw order while reclaiming one-frame density spikes after sustained under-use. Close stale bounds-cache issue evidence without inventing a cache.
2026-07-24 16:34:28 +02:00
Erik
a564c4b782 perf(content): close prepared asset cutover 2026-07-24 15:49:24 +02:00
Erik
bfc5e47365 docs(issues): file #236-#244 - deferred P2 findings from the 2026-07-24 audit review
Nine tactical entries for verified findings the review chose not to fix
inline: UiText per-frame re-wrap (#236), Transition per-resolve allocation
graph (#237, pooling gated on Slice I lifetime tests),
EquippedChildRenderController double-tick + ToArray snapshots (#238),
inbound per-packet allocation chain (#239, Slice H-c scope),
RetailAnimationLoader unbounded cache (#240), InteriorEntityPartition
landblock frustum cull reusing the diagnostics AABB results (#241),
publication third-dictionary + per-attempt re-sort (#242), _boundsCache
bound (#243), SequencerFactory unguarded Setup probe + [dat-miss]
under-lock logging (#244).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 11:52:31 +02:00
Erik
2c3da8e153 fix(ui): keep spell components in authored foreground
Install examination formula icons as the template root UIRegion image, matching retail ClearImage/SetImage behavior while retaining the authored missing-component overlay. Add the real DAT template fixture and conformance coverage.

Co-authored-by: Codex <codex@openai.com>
2026-07-24 08:08:29 +02:00
Erik
d4ce64f56b fix(ui): restore modern spell formula presentation
Resolve spell-examination component cells through their DAT icon DIDs, project scarab and prismatic-taper formulas when ACE disables component enforcement, and version authored window geometry so stale examination sizes reset once without losing user layout behavior.

Co-authored-by: Codex <codex@openai.com>
2026-07-24 07:08:47 +02:00
Erik
3e31b0ac70 fix(ui): select and examine favorite spells like retail 2026-07-24 06:47:54 +02:00
Erik
043ab10b3c fix(ui): select retained items on mouse down
Port UIElement_ListBox's press-time selection ordering through the shared retained item-list contract. Inventory, loot, paperdoll, and physical shortcuts now update canonical selection before release or drag promotion, while target-mode consumption suppresses drag and release-time activation.

Co-authored-by: Codex <codex@openai.com>
2026-07-24 06:17:31 +02:00
Erik
2dd5cb80d2 fix(ui): assess retained items on right click
Port UIElement_ItemList's physical-item right-click branch through the shared retained list. Select and appraise backpack, loot, paperdoll, and shortcut items through their canonical owners, while preventing RMB movement from lifting items or issuing appraisal requests.

Co-authored-by: Codex <codex@openai.com>
2026-07-24 05:55:51 +02:00
Erik
5ad32d5753 feat(input): assess world objects on right click
Port SmartBox's release-completed sr_Examine gesture through the configurable SelectRight binding. Cancel camera drags at the shared retail three-pixel threshold, then reuse the canonical picker, selection pulse, and appraisal request path without inventing another wire or UI owner.

Co-authored-by: Codex <codex@openai.com>
2026-07-24 05:42:28 +02:00
Erik
6718ee45a0 fix(ui): preserve retail item titles and spacing
Carry PublicWeenieDesc material type into the live object model so examination titles use the DAT-authored material prefix. Preserve retail AddItemInfo empty appends and embedded armor separator, restoring the deliberate blank rows between appraisal sections.

Co-authored-by: Codex <codex@openai.com>
2026-07-24 05:21:01 +02:00
Erik
d78d09cfbc feat(ui): port retail item appraisal reports
Follow ItemExamineUI's EoR dispatch and wording for item assessment instead of the generic projection. Resolve material and creature names through installed DAT maps, cover specialized item branches and item-XP curves, and narrow AP-110 to the remaining live/localized preview seams.
2026-07-23 19:08:05 +02:00
Erik
2c00d53db2 fix(net): sign-extend retail capacity bytes
Mirror PublicWeenieDesc::UnPack MOVSX behavior so ACE's FF capacity sentinels remain -1 instead of becoming 255. This suppresses non-container capacity prose through the normal retail appraisal checks, with raw-wire and formatter regression coverage.

Co-authored-by: Codex <codex@openai.com>
2026-07-23 18:25:17 +02:00
Erik
d3c5e06fdd fix(ui): match retail item appraisal semantics
Preserve PublicWeenieDesc hook identity from CreateObject through the item model so hook appraisals suppress sentinel capacities exactly. Use appraisal-only Value and Burden presence, retain AddItemInfo paragraph and authored font-color selection, and port retail lock, page, enchantment, and spell-block formatting.

Co-authored-by: Codex <codex@openai.com>
2026-07-23 18:04:19 +02:00
Erik
bc47bc4917 feat(ui): complete retail item appraisal reports
Restore the authored examination geometry and top-origin item list, then port retail's ordered weapon, armor, magic, requirement, capacity, cooldown, use, and description branches into a dedicated formatter with DAT spell prose. Keep the remaining specialized display-name and preview gaps explicit in AP-110.

Co-authored-by: Codex <codex@openai.com>
2026-07-23 17:03:26 +02:00
Erik
d96ea2de98 feat(ui): complete retail creature appraisal details
Port the separate creature rating list, layer the animated preview between authored row chrome and text, and follow selection while the examination floaty is visible. Preserve the remaining item-preview and font-state gaps in AP-110.

Co-authored-by: Codex <codex@openai.com>
2026-07-23 14:04:19 +02:00
Erik
7eaa68a5f4 feat(ui): port retail creature appraisal presentation
Render assessed creatures through the shared private viewport with retail heading, bounding-box camera, and light. Build the exact authored nine-row stat list and resolve creature names from the retail EnumMapper while keeping remaining font/sequencer adaptations explicit.

Co-authored-by: Codex <codex@openai.com>
2026-07-23 12:55:24 +02:00
Erik
f1a7912160 fix #234: port retail appraisal floaty and inscriptions 2026-07-23 12:12:57 +02:00
Erik
20e2998adb docs(architecture): close GameWindow regression handoff
Reconcile AGENTS.md and CLAUDE.md with the completed structural campaign, verified post-closeout interaction/radar/recall gates, and final Release counts. Record capped/RDP jump-pose cadence as deferred issue #235 without changing the retail object clock.

Co-authored-by: Codex <codex@openai.com>
2026-07-23 06:12:47 +02:00
Erik
f9736ece6c fix(runtime): restore interaction completion ownership
Preserve prepublication local motion completion, require the PartArray enter-world lifecycle port, and balance deferred Use busy ownership across dispatch and cancellation. Reconcile the completed GameWindow connected gates and add regression coverage.

Co-authored-by: Codex <codex@openai.com>
2026-07-23 05:51:51 +02:00
Erik
5c955c36ec docs(architecture): record GameWindow automated closeout
Reconcile the architecture, roadmap, milestones, issue ledger, session instructions, and durable memory with the 1,622-line native shell, canonical soak evidence, connected framebuffer comparison, and sole remaining user visual gate.

Co-authored-by: Codex <codex@openai.com>
2026-07-22 20:52:25 +02:00
Erik
31e6e192b3 refactor(app): extract focused window lifetime
Move the exact retryable shutdown manifest, typed root snapshot, terminal reporting, and native-window-last release out of GameWindow. Keep session and GPU convergence as hard barriers while reporting persistent physical callback cleanup without stranding dependent owners.

Co-authored-by: Codex <codex@openai.com>
2026-07-22 19:43:52 +02:00
Erik
530b4bd8f5 refactor(app): close ordered startup composition 2026-07-22 19:20:20 +02:00
Erik
54244d31f1 refactor(app): make session start terminal
Move live-session startup and its existing diagnostics into the typed Phase-9 owner. GameWindow.OnLoad now ends immediately after that phase, so no callback binding, publication, or allocation can occur after the session becomes active.

Co-authored-by: Codex <codex@openai.com>
2026-07-22 19:06:00 +02:00
Erik
3628aeb520 refactor(app): compose atomic frame roots
Move the complete update/render construction graph into a typed Phase-8 owner, explicitly carry the content dependencies it consumes, and publish both roots through one exact lease. Extract lifecycle resource sampling and frame-owned late bindings so partial startup and shutdown withdraw the same generation without window callbacks.

Co-authored-by: Codex <codex@openai.com>
2026-07-22 19:02:08 +02:00
Erik
826f9ea9b5 refactor(app): complete session startup composition
Move the live-session reset and routing graph, combat and diagnostic command targets, and the sole gameplay input subscriber into Phase 7 before frame publication. Add exact retryable ownership for late bindings so partial startup cannot strand session or component teardown edges.

Co-authored-by: Codex <codex@openai.com>
2026-07-22 18:49:31 +02:00