Docs: 07-21 G6+G4 build spec + session log (H); guidelines shipped-notes; CLAUDE.md tick-source clause; validation-harness fixture notes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# 2026-07-21 (H) — G6 socket honesty + G4 saturation budget (the no-eyes queue)
|
||||
|
||||
**Operator: "do the next few things that don't require eyes."** Skipped the finisher-reach ×1.39 eyes-on and the
|
||||
player hurt flinch (both operator-visual), ran the two autonomous items as one Feature-track pass:
|
||||
**G6** (SpecialSlam/Cone damage-at-contact + the zone fill telegraph) and **G4** (the co-op saturation budget)
|
||||
from [[Combat_Attack_Feel_Guidelines]]. Design → [[Socket_Honesty_Saturation_Build_Spec]] (the durable spec).
|
||||
|
||||
## Reviews (the sandwich)
|
||||
|
||||
- **Pre-code** `wf_98bf1268-51b`: 3 lenses → 14 deduped findings → per-finding refutation critics: **13
|
||||
confirmed / 1 refuted**, all folded in. Two catches were SHIPPED bugs beyond this slice's scope:
|
||||
the **melee death-strand** (an armed `MeleeCleavePending` survives death — `PlayerDeathStateSystem` cleared
|
||||
`MeleeCombo` but not the pending — and fires the cleave from the RESPAWN ring) and the **release-build cue
|
||||
dishonesty** (the client TuningConfig singleton is editor-only; player builds read `default(TuningConfig)` →
|
||||
contact knobs 0 → melee connect cues ~0.35 s before server damage). Both fixed in this pass.
|
||||
- **First run's critics all died on the session quota and returned a CLEAN-LOOKING empty result** — the
|
||||
[[workflow-agent-quota-failures-look-clean]] trap, caught by the failures list; resumed after reset with
|
||||
`resumeFromRunId` (lenses replayed from cache). ALSO: my dedup key truncated at 120 chars and the plan's long
|
||||
temp path swallowed 6 distinct findings — recovered from the journal; key fixed (basename + 160) in the
|
||||
post-impl script.
|
||||
- **Post-impl** `wf_9757d214-b91`: lenses done (11 deduped findings); critics hit the quota again — resumed
|
||||
after the 10am reset (see the addendum below for verdicts). Two findings pre-verified by inspection + fixed
|
||||
immediately: the **base** class-swap path (`ClassSelectReceiveSystem`) lacked the pending clear (dev SetClass
|
||||
parity), and `ZoneAuthoring`'s doc still said "no hand-written [GhostField]".
|
||||
|
||||
## What shipped (14 modified + 6 new files; detail in the build spec)
|
||||
|
||||
1. **Cone damage-at-contact**: `ConeContactPending` (server-only, baked zeroed) + knob 32 `ConeContactTicks`
|
||||
(default 21, 0 = legacy; Count 33; DebugTuningReport +1 = dev-protocol bump) + the schedule/early-flush/
|
||||
re-validate/consume machinery in `AbilityFireSystem` (one shared `FireCone`). Death + BOTH class-swap paths
|
||||
drop an armed pending; the melee pending got the same death-clear.
|
||||
2. **Zone fill telegraph**: `[GhostField]` on `ZoneEffect.CasterNetworkId/Radius/NextTick` (ghost-hash churn;
|
||||
DamagePerPulse/ExpireTick stay server-only); `PulsePeriodTicks` hoisted shared; new `ZoneTelegraphSystem`
|
||||
(Geyser-templated latch + arm-guard, `BuildRing` rim = TRUE radius, fill arrival = the damage moment,
|
||||
**evaluated on `InterpolationTick`** — the zone's observables are interpolated; predicted tick would pin the
|
||||
fill wrong by ~RTT), mine warm/teal vs ally dim-blue tint.
|
||||
3. **Cone cue honesty**: `TickWindowMath.FireStartRaw` (single-sourced), contact latched once at the fire edge
|
||||
(C14), arc reveal ends at contact (C13), `NearestEnemyInCone` shared by 3 call sites, and the
|
||||
`TuningConfig.Defaults()` fallback at every client read site (the release-build fix).
|
||||
4. **G4 saturation budget**: `SaturationMath.AllyScale` (Client, HudVisualMath precedent) + FeelConfig
|
||||
`AllyFxDegradeStart/Full/Floor` (8/16/0.35); degrade set = genuinely ally-attributed FX only (remote arc
|
||||
BRIGHTNESS — life stays contact-honest — + remote shakes); enemy telegraphs structurally exempt;
|
||||
`CombatStressDebug.StressAllyFx` (Debug family + SubsystemRegistration reset — NOT FeelConfig, profiles would
|
||||
capture it) + DebugOverlay `- Saturation (G4) -` rows (Spawn 12 Drowners via DebugOp 14; the stress toggle).
|
||||
|
||||
## Validation
|
||||
|
||||
- **L1** console clean throughout (edits, bake, Play session).
|
||||
- **L2 427/427** EditMode (13 new: 5 cone-schedule incl. death-clear + socket-swap drop; 3 FireStartRaw;
|
||||
5 SaturationMath; knob 32 auto-covered). New fixture lesson: **`NetworkTime.Flags` is internal** — the cone
|
||||
tests set `IsFirstTimeFullyPredictingTick` via a boxed-reflection write (recorded in validation-harness.md).
|
||||
- **Live server proof** (guardian sampling): pending stamped tick 9101 → resolve 9122; dummy HP 340 held through
|
||||
9121, **340→318 exactly across the 9122 boundary, pending consumed atomically**, under real ~4-tick batching.
|
||||
Zone GhostFields verified on the LIVE client (`caster=1 radius=2.5 next=<stamp>`; `DamagePerPulse` correctly
|
||||
absent) + the vortex pulse drain (400→340) + `~ZoneTelegraphFX` drawing.
|
||||
- **L3** screenshot: the teal local-caster rim at the true radius + the new overlay rows.
|
||||
|
||||
## Surfaced along the way
|
||||
|
||||
- **No current frame loadout sockets `WarriorCone`** (Bathynaut = Vortex/Blink/HookPull/LightZone; Harpooner =
|
||||
HookPull/Blink/DecoyWisp/LightZone) — the Cone/SpecialSlam archetype is **dormant in-game** until a loadout
|
||||
carries it. The honesty fix is in place for whenever it returns; the live proof injected the spark directly.
|
||||
Worth an operator call: give a frame the slam back, or park the archetype until a Spark needs it.
|
||||
|
||||
## Post-impl review addendum (critics resumed after the 10am reset)
|
||||
|
||||
`wf_9757d214-b91` final: **5 confirmed / 6 refuted / 0 failures** (all confirmed = low). All five fixed same-session:
|
||||
1. **Saturation census counted corpses** (Dying is server-only; dead ghosts linger ~1 s in the FX cache) → count
|
||||
only `Hp > 0` entries.
|
||||
2. **Solo play degraded the local player's own hit shake** (the health-drop shake for enemy victims rode the
|
||||
ally scale with no co-op gate) → `_remotePlayersQuery` census: 0 remote players ⇒ `_allyFxScale = 1`.
|
||||
3. **The client connect-cue latches survived local death** (server dropped the damage; the corpse still played
|
||||
the full connect package at the contact tick) → the death branch zeroes `_pendingConnectTick` +
|
||||
`_pendingConeConnectTick` — fixes the pre-existing melee variant too. (Two lenses found this independently.)
|
||||
4. **Base class-swap path lacked the pending clear** (`ClassSelectReceiveSystem` — only the dev SetClass op got
|
||||
it; the DR-046 "cannot drift" coupling drifted) → parity clear added (pre-verified by inspection while the
|
||||
critics waited on quota).
|
||||
5. **Two contracts unpinned**: the no-pending-slot fallback + live-steer-at-contact → two new tests
|
||||
(`Cone_Missing_Pending_Slot_Falls_Back_To_Immediate`, `Cone_Resolves_With_The_Aim_At_Contact_Not_Cast`).
|
||||
Plus the `ZoneAuthoring` doc-drift fix ("no hand-written [GhostField]" was no longer true). Suite after fixes:
|
||||
**429/429 green.** Refuted (correctly): the InterpolationTick rim-flash concern, the two-cone-sockets case, the
|
||||
FeelProfileService int round-trip, the FireStartRaw-consumer concern, and the remote-arc life scaling.
|
||||
|
||||
**Next:** the two eyes-on items (finisher reach ×1.39 · player hurt flinch additive layer) + the G6 remainder
|
||||
that needs a designer eye (per-Spark G1 time signatures) + the operator fork: no frame loadout sockets a Cone
|
||||
spark — re-socket the slam or park the archetype.
|
||||
Reference in New Issue
Block a user