mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
v0.3.0 release review: watchdog re-arm, rule-2 sign-offs, GPL source removal, repo hygiene
Per the 2026-09-19 adversarial pre-ship review (findings.md M-192): - d318watchdog.c: one-shot per OCCURRENCE, not per process -- re-arm after 600 ticks of signature absence so a Facility replay in the same session (AllUnlocked) is still covered. - model.c: RULE-2-SIGNOFF records for the retained M-183/M-185 and D311 defensive clamps (user-approved retention as the stability-maximizing option; stale 'Threshold: 50.0' comment corrected to 10.0f; both marked post-release removal candidates pending full cutscene re-verification). - reference/mouse-injector/: removed from the public repo (GPLv2 source + prebuilt discord-rpc.lib in an MIT project; never compiled here). Provenance stub README remains; path gitignored for local re-vendoring. AGENTS.md / GEPD-INPUT-PLAN.md / optionsoverlay.c refs updated. - scratch/: untracked + gitignored (19 session logs/probe sources were committed in the release window). - findings-index.csv: D317 (and 5 other stale rows) now CLOSED -- added CLOSED to gen_findings_index.py's verdict vocabulary. - docs: D310 perf gauge (no change warranted), GE_DEBUG_UNLOCKALL noted in security-and-fidelity-status.md, release notes gain the missing D318 watchdog bullet + FOV-clamp clarification. Build verified: ./build-pc.sh ntsc-final clean; gen_findings_index.py --check and gen_env_probes.py --check pass.
This commit is contained in:
1 parent
63315030f8
commit
b3b0ff74db
57 files changed
+157
-11732
No files matched your search
+14
-10
@@ -3,14 +3,17 @@
|
||||
Status: **plan only** — no code changes yet. Companion to `port/src/input.c`
|
||||
(current state: D118/D165/D166/D194/D214/D223/D238 lineage).
|
||||
|
||||
## 1. The reference (vendored in-repo)
|
||||
## 1. The reference (no longer vendored in the public repo)
|
||||
|
||||
The GEPD Edition Mouse Injector source is vendored at **`reference/mouse-injector/`**
|
||||
(see its README for provenance, version-skew warning, and a per-file guide).
|
||||
The file that matters is **`games/goldeneye.c`** (~380 lines, the whole GE
|
||||
aim model), plus `device.c` (raw mouse polling) and `maindll.h` (tickrate —
|
||||
the units every per-tick constant assumes). Consult it directly; no
|
||||
re-extraction needed.
|
||||
The GEPD Edition Mouse Injector source was vendored at `reference/mouse-injector/`
|
||||
and **removed from the public repo on 2026-09-19** (GPLv2 code + a prebuilt
|
||||
binary inside an MIT project; never compiled here). See
|
||||
`reference/mouse-injector/README.md` for provenance and how to re-vendor it
|
||||
locally if you need the original. The file that mattered was
|
||||
**`games/goldeneye.c`** (~380 lines, the whole GE aim model), plus `device.c`
|
||||
(raw mouse polling) and `maindll.h` (tickrate — the units every per-tick
|
||||
constant assumes). The model is quoted inline below and in the D194 findings;
|
||||
the ported result lives in `port/src/input.c`.
|
||||
|
||||
### What the Mouse Injector does (GE)
|
||||
|
||||
@@ -49,9 +52,10 @@ sensitivity/FOV coupling discipline. That's WIs 1–3 + 6 below.
|
||||
|
||||
Two references, two jobs (decided during #89/#90 triage):
|
||||
|
||||
- **GEPD Mouse Injector** (`reference/mouse-injector/`) = *what the mouse does
|
||||
to the camera*. The only reference with GE-specific knowledge (camera
|
||||
fields, crosshair limits, tank case, safety gates). Primary for WI-1.
|
||||
- **GEPD Mouse Injector** (was `reference/mouse-injector/`, removed from the
|
||||
public repo 2026-09-19 — see its README stub) = *what the mouse does to the
|
||||
camera*. The only reference with GE-specific knowledge (camera fields,
|
||||
crosshair limits, tank case, safety gates). Primary for WI-1.
|
||||
- **PD PC port checkout** (standing reference, see AGENTS.md) = *how a PC game
|
||||
presents and captures input*: cursor-lock behavior, raw input handling,
|
||||
sensitivity units/scaling, and the shipped in-game options/keybind UI.
|
||||
|
||||
@@ -17,17 +17,17 @@ D186,PARTIAL,"Video.FpsCap throttles the sim, not just presentation (M-39 diag,
|
||||
D187,FIXED,"HUD ammo-type/weapon icon vanished at -O2 (M-46 root-cause, M-47 fix + verify).","FIXED (src/game/gunfire.c, #ifdef AVOID_UB); PR #19"
|
||||
D188,FIXED,Linux -O2 boot crash:,"FIXED (src/libultrare/libc/xprintf.c, src/sprintf.c, #ifdef PORT); PR #22"
|
||||
D189,FIXED,Linux -fstack-protector aborts on the decomp's latent stack-buffer overruns (M-48) —,"FIXED (CMakeLists.txt, src/game/stan.c #ifdef PORT); PR #23"
|
||||
D190,?,"Linux -level_45 SIGSEGV at load in add_ptr_to_objective (objective.c:64) (M-48, open).","CLOSED — not a port bug; level 45 is MP-only and has no solo setup file in the ROM (root-caused M-105, reproduced on Windows)."
|
||||
D190,CLOSED,"Linux -level_45 SIGSEGV at load in add_ptr_to_objective (objective.c:64) (M-48, open).","CLOSED — not a port bug; level 45 is MP-only and has no solo setup file in the ROM (root-caused M-105, reproduced on Windows)."
|
||||
D191,FIXED,Windows -O2 release-bundle crash:,FIXED + PLAYTEST-VERIFIED (M-79).…
|
||||
D193,FIXED,NPC AI locomotion is too slow —,FIXED + user-playtest-verified (M-81) —…
|
||||
D194,PARTIAL,Mouse input needs another tuning pass —,PARTIAL — M-120 human playtest…
|
||||
D195,FIXED,"Transparency / alpha surfaces broken on Control (M-49, user playtest) —","FIXED (port/fast3d/gfx_pc.cpp, gfx_sp_vertex) —…"
|
||||
D197,?,"Character face/head textures wrap around the head, seen on Silo (M-49, user playtest).",CLOSED — user playtest v0.2.0-pre
|
||||
D197,CLOSED,"Character face/head textures wrap around the head, seen on Silo (M-49, user playtest).",CLOSED — user playtest v0.2.0-pre
|
||||
D198,FIXED,alAdpcmPull/_decodeChunk used K0_TO_PHYS (an unconditional & 0x1FFFFFFF mask) on 64-bit heap pointers (src/libultra/audio/load.c).,FIXED (src/libultra/audio/load.c) —
|
||||
D199,PARTIAL,Phase-3 software audio mixer:,"LANDED (port/src/mixer.c, port/include/mixer.h, include/PR/abi.h) —"
|
||||
D200,FIXED,-level_09 segfault: reverb's ALDelay.input/output are u32 —,FIXED — 5-line cast in reverb.c (this session)
|
||||
D196,FIXED,"OS mouse cursor stays visible after closing the F10 options overlay in click-to-lock mode (M-49, user playtest).","FIXED (6e758f1d, merged to main) —…"
|
||||
D192,?,Front-end mission/level-select grid pointer still can't reach the outer cells —,"CLOSED — the buggy mode 0 was removed entirely in the v0.2.0 prep pass (see D239); click-to-lock is now the only capture mode, so the unreachable-cells path no longer exists"
|
||||
D192,CLOSED,Front-end mission/level-select grid pointer still can't reach the outer cells —,"CLOSED — the buggy mode 0 was removed entirely in the v0.2.0 prep pass (see D239); click-to-lock is now the only capture mode, so the unreachable-cells path no longer exists"
|
||||
D221,FIXED,SELECT FILE mouse hit-box offset —,"FIXED (M-91) — explicit {min,max} coord2d pairs under #ifdef PORT; human mouse-playtest confirmed."
|
||||
D222,FIXED,High Video.FovScale breaks culling —,"FIXED, awaiting visual verification (M-121)."
|
||||
D223,FIXED,QoL ask: mouse-wheel weapon cycling should be directional like a normal PC shooter —,"FIXED (M-105, port/src/input.c) —…"
|
||||
@@ -42,7 +42,7 @@ D234,FIXED,"Dam: guard towers along the dam structure invisible except the first
|
||||
D244,OPEN,Self-hosted CI runner (corpyvt6agent01) link failure:,"OPEN, not yet fixed. Next…"
|
||||
D228,FIXED,AK47 white missing-texture patches after D217's texpool fix —,"FIXED (port/fast3d/gfx_pc.cpp, palette_to_rgba32) —"
|
||||
D204,FIXED,PC audio ran ~2 % below real time permanently (AI feedback loop's 3 ms setpoint vs PC jitter).,"FIXED (port/src/audio.c, port/src/libultra.c, port/include/audio.h) —"
|
||||
D203,?,"Steam Deck (SteamOS, x86_64 Linux) v0.1.0 release bundle:",CLOSED — root cause + fix in D253.
|
||||
D203,CLOSED,"Steam Deck (SteamOS, x86_64 Linux) v0.1.0 release bundle:",CLOSED — root cause + fix in D253.
|
||||
D201,FIXED,"src/libultra/audio/bnkf.c bank/instrument/sound/wavetable relocation offsets were s32, truncating the real 64-bit base pointer.",FIXED (src/libultra/audio/bnkf.c) —
|
||||
D202,?,"Silenced PPK ""slap"" + broader real-time mixer corruption (M-52→M-67).",ROOT CAUSE ESTABLISHED (M-66); Disposition C implemented + measured (M-66b) —
|
||||
D206,FIXED,PC played every SFX one bank slot too high —,"FIXED (M-76, src/snd.c:1001, #ifdef PORT) —"
|
||||
@@ -50,7 +50,7 @@ D207,?,"Alarm klaxon starves combat SFX and doesn't recover after it stops (surf
|
||||
D208,FIXED,Player weapon-fire sound goes permanently silent mid-firefight (all other SFX unaffected) —,FIXED + user playtest-verified (M-78d) —
|
||||
D209,FIXED,Every AI character in the game is locked to a *walk* animation regardless of the speed the ailist commands —,FIXED + user-playtest-verified (M-81).
|
||||
D210,FIXED,chrToPatrol() leaves act_patrol.lastvisible60 uninitialised on PC —,"FIXED (chraction.c:3872, #ifdef PORT → self->act_patrol.lastvisible60 = -1;, N64 line under #else).…"
|
||||
D205,RESOLVED,"PC plays wrong/extra SFX for gameplay events (gunfire slap layer, explosion→scream, armour pickup, melee→Klobb idx 106) —",CLOSED (M-78) — root cause was D206; all four symptoms resolved + user-confirmed by ear.
|
||||
D205,CLOSED,"PC plays wrong/extra SFX for gameplay events (gunfire slap layer, explosion→scream, armour pickup, melee→Klobb idx 106) —",CLOSED (M-78) — root cause was D206; all four symptoms resolved + user-confirmed by ear.
|
||||
D152+,FIXED,D152 addendum (M-31):,"FIXED (src/snd.c, port/src/libultra.c, #ifdef PORT) —"
|
||||
D168,FIXED,GE_PCDUMP / F12 PPM captures were vertically flipped —,FIXED (port/fast3d/gfx_opengl.cpp); D114 / D116 reclassified as capture-orientation artifacts (below).
|
||||
D169,FIXED,Front-end mouse pointer can't reach the outer cells of the mission/level-select grid —,"FIXED (M-33, port/src/input.c, port-only, no #ifdef PORT)."
|
||||
@@ -135,7 +135,7 @@ D235,OPEN,Wrong textures load after dying/restarting a level —,OPEN — needs:
|
||||
D236,OPEN,"Surface 1: 2D billboard trees render as a wall/sheet of tree texture instead of discrete camera-facing tree sprites (M-106, user QA report).","OPEN, sixteenth pass (2026-09-18) —"
|
||||
D237,OPEN,"QoL ask (M-106, user QA):",OPEN — not designed; port-only
|
||||
D238,OPEN,"QoL ask (M-106, user QA):",OPEN — not designed; port-only (port/src/input.c + config.c)
|
||||
D239,?,"QoL ask (M-106, user QA):",CLOSED — executed in the v0.2.0 prep pass (port-only)…
|
||||
D239,CLOSED,"QoL ask (M-106, user QA):",CLOSED — executed in the v0.2.0 prep pass (port-only)…
|
||||
D240,OPEN,"Player gunshot SFX timing/cadence reportedly does not match the N64 original's rate (M-106, user QA report).","OPEN — not root-caused; static call-site tracing only, no runtime verification possible in this environment."
|
||||
D241,OPEN,Player gunshot SFX goes silent under some conditions —,"OPEN — not newly root-caused; high confidence this is D207 reproduced, not an independent bug."
|
||||
D242,?,Player-death sequence UX regression vs N64 original:,NOT A PORT-LOGIC BUG as far as static analysis can tell.
|
||||
@@ -194,7 +194,7 @@ D313,FIXED,Bullet impacts do not appear on some walls/surfaces —,"FIXED — sa
|
||||
D314,OPEN,"F10 menu items flicker randomly/intermittently (reported on the main-menu context, user report, v0.3.0 playtest build, 2026-09-18).",OPEN — confirmed still present post-D316 fix (2026-09-18); user deprioritized chasing it further for now.
|
||||
D315,OPEN,Menu scaling differs between main menu and in-game —,"OPEN — disclosed as a known issue, deferred to v0.3.1 (bigger design question, not a mechanical fix)."
|
||||
D316,FIXED,"Mouse-clicking some menu items glitches and lands on the item below instead (user report, v0.3.0 playtest build, 2026-09-18).",FIXED — root-caused to two compounding bugs (naive mouse->logical mapping ignoring the safe-area crop; asymmetric row hit-test band) in port/src/optionsoverlay.c + port/fast3d/gfx_pc.cpp.
|
||||
D317,?,"Crash when toggling Game.AllUnlocked back and forth in-game (user report, v0.3.0 playtest build, 2026-09-18) —","CLOSED — symptom of D316 (confirmed instant window close, no WER report; the D316 hit-band bias let a click on ""All unlocked"" fall through to the adjacent ""Quit to desktop"" row)."
|
||||
D317,CLOSED,"Crash when toggling Game.AllUnlocked back and forth in-game (user report, v0.3.0 playtest build, 2026-09-18) —","CLOSED — symptom of D316 (confirmed instant window close, no WER report; the D316 hit-band bias let a click on ""All unlocked"" fall through to the adjacent ""Quit to desktop"" row)."
|
||||
D318,RESOLVED,Facility (regular play path):,RESOLVED (2026-09-19):
|
||||
D319,FIXED,"Frame cap slider was mostly a dead zone; replaced with a plain 30/60 toggle (user ask, 2026-09-18).",FIXED — new ROW_FPSCAP cycle (30/60 only) in port/src/optionsoverlay.c; default changed to 60 in port/src/video.c.
|
||||
D320,OPEN,"D318-class sweep: aim-hold → _update AI lists in 8 levels carry the same as-authored softlock race (static analysis, 2026-09-20).","OPEN — static sweep complete (Facility ai_19, Control ai_9, Depot ai_12 flagged high/med-high; Bond-combat loops likely safe); no live confirmation beyond D318 itself; probe-verify path + generalized…"
|
||||
|
+17
-3
@@ -11707,7 +11707,7 @@ Returns "cheat not unlocked" — the same safe default other cheat-state paths a
|
||||
|
||||
**Status:** FIXED locally on `release/v0.3.0` (not yet pushed) — build-verified, crash-free smoke test; live confirmation against the actual #87 repro still owed.
|
||||
|
||||
**M-183/M-185 (2026-09-17, this session):** Added playspeed and endframe clamp workarounds for D243's Bond position/animation issue. M-183 clamps playspeed > 10.0 to 1.0 during scripted camera modes; M-185 clamps corrupted endframe values (< 0.0 or > 1000.0) to 100.0. Both are + env-gated on GE_D243M. The clamp fixes prevent rapid animation advancement (~97 frames/tick) but Bond's animation still "repeats" — he can't complete his animation during the Dam abseil cutscene. ~~Root cause (struct layout corruption from 32→64-bit pointer widening, D100/D140 family) not yet addressed.~~
|
||||
**M-183/M-185 (2026-09-17, this session):** Added playspeed and endframe clamp workarounds for D243's Bond position/animation issue. M-183 clamps playspeed > 10.0 to 1.0 during scripted camera modes; M-185 clamps corrupted endframe values (< 0.0 or > 1000.0) to 100.0. Both were originally env-gated on GE_D243M — a gate M-187 found to be wrong (the clamps never fired for real players); they are now gated on `gameScriptedCameraActive()` alone and active by default. See M-192 for the v0.3.0 release-review sign-off on their retention. The clamp fixes prevent rapid animation advancement (~97 frames/tick) but Bond's animation still "repeats" — he can't complete his animation during the Dam abseil cutscene. ~~Root cause (struct layout corruption from 32→64-bit pointer widening, D100/D140 family) not yet addressed.~~
|
||||
|
||||
**M-186 (2026-09-17, later recovery session) — the M-183/M-185 diagnosis above is WRONG; correcting the record.** A follow-up agent acted on "struct layout corruption from pointer widening" and converted `Model`'s 7 pointer fields to u32 slots + accessor macros, rewriting ~200 call sites with blind `sed` across 12 files — this broke the build (macro name collisions with unrelated structs' same-named fields, malformed chained-access substitutions) and was **reverted this session** (changes stashed, not committed: `git stash` "D243 broken sed attempt (superseded)"). The diagnosis itself doesn't hold up: a `Model*` accessed normally is always self-consistent post-compilation; this codebase's actual pointer-widening bug class only bites when something *puns/overlays* a Model onto raw hardcoded-offset bytes (§A, `porting-notes.md`), and all three known instances of that for models (D100 Bond's own inline model, D102 weapon model, D140 watch model) are already fixed with real inline storage. No unfixed punning gap exists for Bond's world model. **The real, already-established lead is above this entry, in M-169 through M-178** — the 3rd `chrlvPerformAnimationForActor` scripted restart (`chraction.c:605`) triggers the rapid `animframe` advancement; M-178's own stated next step (diff that call's caller-side state writes, `chraction.c:615-627`, against a normal `modelTickAnim` loop-wrap) was never carried out and is the correct place to resume. See `docs/HANDOFF.md` for the fuller writeup, including a new unconfirmed candidate (`modelSetAnimation`/`modelSetAnimation2` never reset `playspeed`/`unkb0`/`unkb4`/`unkac`/`animrate`, only `modelSetAnimPlaySpeed` does) that needs a live `GE_D243M` capture to check, and a reminder not to lose D243 CONSOLIDATED NEXT STEPS item 5's model-pointer-reuse caveat as an alternative explanation for the "playspeed already corrupted before `modelSetAnimPlaySpeed` was even called" observation.
|
||||
|
||||
@@ -11751,6 +11751,18 @@ Returns "cheat not unlocked" — the same safe default other cheat-state paths a
|
||||
|
||||
Build clean (`./build-pc.sh ntsc-final`), `tools_pc/verify.sh dam` PASS. **User confirmed both fixes live, full Dam intro-flyover + abseil-jump + abseil-descent playthrough: "ok yeah looks good."**
|
||||
|
||||
### M-192 (2026-09-19): v0.3.0 release review — sign-offs, watchdog re-arm, repo hygiene, post-release cleanup list
|
||||
|
||||
Adversarial pre-ship review of the whole v0.3.0 window (147 commits since v0.2.2). Build verified clean (`./build-pc.sh ntsc-final`, 244/244 + link); `gen_findings_index.py --check` and `gen_env_probes.py --check` both pass. Outcomes, per user decisions in-thread:
|
||||
|
||||
1. **M-183/M-185 clamps (this section): RULE-2-SIGNOFF granted for RETENTION.** They are ungated behavior-modifying guards in `src/game/model.c` outside the ABI/layout exception; with M-189's root cause fixed and user-verified they no longer fire in practice, but removing them a day before ship would drop defense-in-depth across ALL cutscenes (verification so far covers Dam only). User approved retention as the stability-maximizing option. In-code comments updated (incl. fixing the stale "Threshold: 50.0" — code uses 10.0f). **Post-release: re-verify all scripted-camera cutscenes with the clamps compiled out; if clean, delete both blocks (reverts to pure decomp).**
|
||||
2. **D311 heal clamps (`model.c`): RULE-2-SIGNOFF granted for RETENTION** — same decision, classified as defensive guards against non-finite state in the accepted D156 class (fire only on poison values; snap to valid frames; never touch legitimate animation). See the D311 entry.
|
||||
3. **D318 watchdog re-arm (fixed this pass).** `port/src/d318watchdog.c` was one-shot per PROCESS: `s_fired` never reset, so a Facility replay later in the same session (AllUnlocked) hitting the same race would softlock with no recovery — the exact scenario the feature exists to prevent. Now one-shot per OCCURRENCE: after firing, the watchdog re-arms once the signature has been absent for `D318_REARM_TICKS` (600 ≈ 10 s) consecutive ticks; logs a `D318W: ... re-armed` line.
|
||||
4. **GPL reference source removed from the public repo.** `reference/mouse-injector/` (GEPD-Edition Mouse Injector, GPLv2, incl. a prebuilt `discord-rpc.lib`) was committed inside the v0.3.0 window of an MIT project and would have shipped in the tag's auto-generated source tarball. Removed; a provenance stub README remains (`reference/mouse-injector/README.md`), the path is gitignored for local re-vendoring, and AGENTS.md / `docs/dev/GEPD-INPUT-PLAN.md` / `optionsoverlay.c` references were updated. The ported model lives in `port/src/input.c` (D194 lineage).
|
||||
5. **`scratch/` untracked + gitignored.** 19 session logs / investigation scratch files (incl. a 1396-line regression log and probe `.c` sources) had been committed; removed from the index, `/scratch/` added to `.gitignore`. Local copies untouched.
|
||||
6. **D310 perf gauge (no change needed).** v2's up-front `chraiGetAIListID()` in `chraiGoToLabel` adds ≤ (level-local + ~20 global) pointer comparisons per label jump, on a path that previously ran only in the rare EndList-not-found branch. Worst case for a heavy level (Train/Archives, ~50 active guards × 1–2 goto-family records/tick): ~1000 calls/tick × ~40 comparisons ≈ 40 µs/tick < 0.3% of a 16.7 ms frame — two orders of magnitude below D250's per-triangle `getenv` anti-pattern. Re-measure only if an AI-heavy level regresses.
|
||||
7. **Post-release cleanup list (deferred by user):** (a) remove the TEMP diagnostic probes marked "remove once Dxxx concludes" whose investigations have ended (D236 passes 10/12/14/16 in `gfx_pc.cpp` + `GE_D236RAW` in `bg.c`, D288, D157, D252, D245V); (b) cache the few remaining per-call `getenv()`s on tick paths (bondview2 D243CAM ×3, chrai `AI_PLAYANIMATION` GE_D243M, sky.c water GE_D245_FIXEDSHIFT) per the D250 discipline; (c) delete M-183/M-185 if cutscene re-verification passes (item 1); (d) D317's latent heap-corruption class (39 dev-run crashes, pre-final-fix) stays on the radar — see its entry.
|
||||
|
||||
## D302 — Render FPS regression to ~40-45fps on release/v0.3.0 (user QA on the local v0.3.0 pre-release build, 2026-09-18).
|
||||
|
||||
**User reported drops to 40-45fps on a self-described high-end PC on a local v0.3.0 pre-release build**, after the port had previously held a rock-steady 60-61fps end-to-end (D250, fully resolved). Same symptom class and roughly the same fps range as D250's original regression.
|
||||
@@ -11950,6 +11962,8 @@ This confirms the M-160/M-164/M-165 hypothesis (`## D173`'s own consolidated-nex
|
||||
|
||||
**Cross-refs:** D309 (this fix neutralizes its spin mechanism — the teardown-ordering open question in D309's "why PC and not N64" remains, but reaching that state is now harmless); GE_D309 probes (`chrai.c` `ai()`/`chraiGoToLabel`, `chraction.c` `chrGoToBond`) remain as diagnostic tools.
|
||||
|
||||
**Perf gauge (2026-09-19, release review — M-192 item 6):** v2's up-front `chraiGetAIListID()` call in `chraiGoToLabel` (added so the sizer knows global-vs-local) runs on EVERY label jump; originally that lookup ran only in the rare EndList-not-found branch. Cost per call: ≤ (level-local lists + ~20-entry `g_GlobalAILists`) pointer comparisons ≈ tens of ns. Worst case for a heavy level (Train/Archives, ~50 active guards each executing 1–2 goto-family records per tick): ~1000 calls/tick × ~40 comparisons ≈ 40 µs/tick — under 0.3% of a 16.7 ms frame, and two orders of magnitude below the D250 `getenv` anti-pattern (which was per-TRIANGLE, tens of thousands of calls per frame). **No change warranted; re-measure only if an AI-heavy level shows a regression.**
|
||||
|
||||
## D311 — Complete freeze in `modelSetAnimFrame2WithChrStuff` root-motion loop: D156 guard hole — poisoned `framea` (`model->animframe1`) passes through the frameb-only clamp and saturates to a ~3.1e9-iteration spin (Caverns, live GDB diagnosis, 2026-09-18).
|
||||
|
||||
**Reported:** user playtest of the D310 v2 build in Caverns — "it's frozen" shortly after launch (watchdog: no frame rendered for 8014 ms at frames=8424; ~2.3 min into the session).
|
||||
@@ -11967,7 +11981,7 @@ This confirms the M-160/M-164/M-165 hypothesis (`## D173`'s own consolidated-nex
|
||||
|
||||
**Open question (deeper root cause, NOT fixed):** what wrote `-1.75e18` into `oldspeed` / poisoned `animframe1` in the first place? `oldspeed = model->speed` at transition start (`model.c:2975`) means `speed` was already garbage upstream; `timespeed = 0` and `unkb0 = 0` at the guarded tick are suspicious division denominators (D156's original note flagged `/ unkb0` and `/ timespeed` as guarded `> 0` but not against tiny values). Also, the model's persistent root-motion header (`header->unk34/unk24`) is poisoned to ~1e30–1e32 in this instance, so **Bond's rendered model may be displaced even after the freeze is prevented** — a level reload clears it. Needs its own investigation (dump speed-field write sites during the triggering transition) before any further fix.
|
||||
|
||||
**Status:** GUARDED (freeze class neutralized; upstream poison source OPEN). Disclosed to user in-thread as a D156-guard extension following the already-accepted D156 precedent in this same file; if the project wants formal rule-2 sign-off for `src/game` edits, this is the entry to reference — revert is two small blocks. Cross-refs: D156 (original guard + Facility outro hang), D309/D310 (ruled out for this freeze — no AI involvement).
|
||||
**Status:** GUARDED (freeze class neutralized; upstream poison source OPEN). **RULE-2-SIGNOFF (2026-09-19, release review — M-192 item 2):** user approved retention as the stability-maximizing option; classified as a defensive guard against non-finite state in the same class as the accepted D156 guards — it fires only on poison values that indicate an already-broken state and snaps to a valid frame rather than altering any legitimate animation. Previously disclosed in-thread as a D156-guard extension following the already-accepted D156 precedent in this same file; revert is still two small blocks. Cross-refs: D156 (original guard + Facility outro hang), D309/D310 (ruled out for this freeze — no AI involvement).
|
||||
|
||||
## D312 — Throwable items (mines, grenades, etc.) can clip through walls in certain spots (user report, v0.3.0 pre-release playtest, 2026-09-18) — FIXED: `bgBuildRoomVtxBounds` mis-reads the G_VTX vertex count on PC (Gfx_le `dma.par` bit-layout shift), collapsing whole batches of wall geometry out of the collision query (diagnosed + fixed, 2026-09-18).
|
||||
|
||||
@@ -12097,7 +12111,7 @@ Ourumov = chr 78 on list 0x0417 (ai_22). Key offsets: off=38 pre-aim at Trevelya
|
||||
|
||||
### Fix (port-side, `port/src/d318watchdog.c` — same pattern as D202 M-66b)
|
||||
|
||||
Per-tick check (hooked at the `g_GlobalTimer += g_ClockTimer` site in lv.c). Signature, all held for 600 consecutive ticks (10 s; the escape path resolves in < 2 s): chr 78 on list 0x0417 with offset in [321, 333), `actiontype == ACT_ATTACK`, `act_attack.entityid == 67` (targeting Trevelyan — legitimate combat at this offset targets Bond, ent=1), and chr 67 alive. On confirm: **re-initialize c78's attack via `sub_GAME_7F025560(c78, attacktype, entityid)`** — the same entry point the game itself uses for a fresh attack (chrlvTickAttack type_of_motion==2, chraction.c:7401). That runs `chrlvInitActAttack` → random variant + `modelSetAnimation(start_frame)`, breaking the pin; c78 then live-fires Trevelyan exactly like the natural escape path. One-shot; logs `D318W:` lines for playtest audit; opt-out `GE_D318W=0`.
|
||||
Per-tick check (hooked at the `g_GlobalTimer += g_ClockTimer` site in lv.c). Signature, all held for 600 consecutive ticks (10 s; the escape path resolves in < 2 s): chr 78 on list 0x0417 with offset in [321, 333), `actiontype == ACT_ATTACK`, `act_attack.entityid == 67` (targeting Trevelyan — legitimate combat at this offset targets Bond, ent=1), and chr 67 alive. On confirm: **re-initialize c78's attack via `sub_GAME_7F025560(c78, attacktype, entityid)`** — the same entry point the game itself uses for a fresh attack (chrlvTickAttack type_of_motion==2, chraction.c:7401). That runs `chrlvInitActAttack` → random variant + `modelSetAnimation(start_frame)`, breaking the pin; c78 then live-fires Trevelyan exactly like the natural escape path. One-shot per OCCURRENCE: after firing, the watchdog re-arms once the signature has been absent for 600 consecutive ticks (~10 s), so a later replay of Facility in the same session (AllUnlocked) is still covered — added 2026-09-19 during the v0.3.0 release review (M-192 item 3; previously one-shot per process, which would have left a replayed Facility unprotected). Logs `D318W:` lines for playtest audit; opt-out `GE_D318W=0`.
|
||||
|
||||
**Why not just kill Trevelyan:** first attempt applied the scripted headshot's own damage call (`handles_shot_actors(c67, 0x08, &zero, 0x06, FALSE)` — ai_22 off=333). c67 died, but a pinned attack has **no completion event tied to target death** — c78 stayed in ACT_ATTACK and the stop check still never passed (probe-verified: act=8 in 100% of samples post-kill vs 32/264 ACT_STAND samples in natural-escape runs). The attack state itself must be re-seeded.
|
||||
|
||||
|
||||
Reference in new issue
Block a user