Commit Graph

23 Commits

Author SHA1 Message Date
kronic 62e48a3b0b LANTERN purge: delete the superseded base/expedition shell (audit H1/H3/M5)
The 2026-08-06 audit found the shipping scene was still the abandoned
co-op-Hades game with LANTERN combat bolted on, and that a third of the
codebase was live code for a direction abandoned on 2026-07-13. Operator
chose deletion over freezing: "everything is saved in source control if
needed. I want the project to be clean."

DELETED (~140 source files, Scripts 335->231, Tests 77->43):
- Enemy variants + boss (H3). ChargerAuthoring / SpitterAuthoring /
  SwarmerAuthoring were attached to ZERO prefabs, so LungeState /
  SpitterState / SwarmerTag were never baked: ~272 lines of Bursted AI
  passes, BossAISystem (261 lines) and the whole MixBands escalation
  curve could not match a single chunk at runtime, while 734 lines of
  green tests certified them. Both shipping enemy prefabs were already
  byte-identical in stats.
- Run/room lifecycle: RunDirector FSM, RunInfo/RunMap/RoomPlan/RoomTag,
  route select, portal interact, ready-check, room field/teardown.
- Meta shop, prep loadout, boons (incl. KillRewardSystem and
  DashTrailDamageSystem, which existed only to serve boon flags).
- Build palette + structures, shared storage, inventory/equipment
  (already recorded PAUSED in CLAUDE.md).
- The HUD panels driving all of the above (HudSystem 1168 -> 610).

KEPT deliberately: BaseGridMath + BaseAnchor (8 systems use PlotCenter
for spawn rings, respawn and dynamic light), the resource ledger +
StorageMath, the save system, region/relevancy. Three of these were in
the delete set until I checked their consumers — worth remembering that
the file-level manifest was wrong about them.

Also folds in audit finding M5: PlayerClass was a second, server-only
copy of the byte FrameId already replicates. It existed for the meta
shop; with that gone, FrameId is the single frame identity.

Harvest is now single-sink (ledger). HarvestMath keeps its shape so
LANTERN's carried-vs-banked cargo split lands in one place, not two.

295/295 EditMode green, zero compile errors. Subscene re-bake and Play
validation follow in the next commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 12:59:39 -07:00
kronic 2aebc37115 G6+G4: Cone damage-at-contact + zone fill telegraph (ZoneEffect GhostFields) + co-op saturation budget
Cone/SpecialSlam damage lands at its visual contact via ConeContactPending (knob 32, 0=legacy;
early-flush + resolve re-validate; death + BOTH class-swap paths drop armed pendings — fixes the
shipped melee death-strand in the same stroke). Zones: [GhostField] Caster/Radius/NextTick +
ZoneTelegraphSystem (Geyser latch contract on InterpolationTick; rim = true radius; arm grows,
persistent phase drains). Cone cues latch to contact (FireStartRaw, C14); TuningConfig.Defaults()
fallback at client cue sites (release-build timing fix). G4: SaturationMath ally-FX degrade
(living-enemy census, solo-exempt; enemy telegraphs structurally exempt) + CombatStressDebug +
overlay saturation rows. Reviews wf_98bf1268 (13 confirmed folded) / wf_9757d214 (5 confirmed fixed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 13:27:50 -07:00
kronic 7571091394 LANTERN feel pass (DR-052 + gap list): SoD facing, underwater feel, Bathynaut kit, walk/run gait, suit lamp + new Synty anim packs
- SoD facing: PlayerFacing = body-yaw only (move-facing / cast-turn / idle-hold); every fire
  direction re-sourced to FacingMath.ResolveAim (pre-code review blocking catch); TickWindowMath
  shared windows with Movement-skip; reticle/FX coupled to the damage direction; cursor-dash kept.
- Underwater feel: sharpness 15->6, turn 720->360, MoveSpeed 6->4.2; TuningKnob 26-28
  (0 = no-override sentinels, dev-protocol bump on DebugTuningReport); stride footsteps + silt +
  cadence floor; bubbles; underwater ambience bed + distant groans; camera drag + dev scroll zoom.
- Bathynaut kit in-engine: dome/tank/shoulder-lamp + bare head grafted (GraftSmr rigid rebase,
  RecalculateTangents); EmissiveGloamSkinned shader (Rukhanka deformation); shoulder lamp CASTS
  (warm steady spot on body yaw).
- Gait: two-ring walk/run FreeformDirectional tree (walk @0.35, run @1.0) + blended-natural
  StrideScale; additive Posture(Bank) + Lead(chest-lead) layers; idle = AnimationIdles Base;
  banking driven from facing turn rate; flat terrain (Env_SeabedKit seabed squashed - CC is planar).
- New packs: Synty AnimationIdles + AnimationSwordCombat (combat pass queued) + SyntyPropBoneTool;
  four authored clips (sway/trudge/banks/lean) + Anim_Player_Underwater.blend + suit-kit FBX.
- Validation: 411/411 EditMode green; Play smokes (server==client facing, Aim-true projectile,
  bank/stride live-sampled, lamp beam verified); pre-code + post-impl adversarial reviews applied.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:56:02 -07:00
kronic 77de740b63 LANTERN purge B7: rename CharacterId -> FrameKind (frame terminology)
Enum renamed in StatIds.cs (byte values unchanged - serialized definitions/saves
never re-mean); all call sites + doc mentions swept (ClassTraits, PlayerAuthoring,
CharacterStatsDefinition field type, menu/UI, tests). CharacterStatsDefinition SO
CLASS name kept (asset-binding risk; deferred per plan). 390 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:51:48 -07:00
kronic 8f099c32ba LANTERN P1 step 6: manual-aim windups (SoD readable telegraphs)
AbilityDefBlob/AbilityDefinition gain WindupTicks. AbilityFireSystem's socket
loop resolves each socket at the historical command (serverTick - WindupTicks)
via GetDataAtTick — a pure fn of replicated data on both worlds (Build Spec §4/
DB-6: no local fireAtTick that would diverge under reprediction; fireCount from
that command, spawn uses the current tick's aim/pos; history gap = no-fire).
WindupTicks set on the 4 non-Blink Sparks (Blink is movement, resolved by
BlinkSystem). 497 EditMode green (no regression). Client telegraph VFX + the
reprediction L3 test are operator-eyes / netcode-world follow-ups.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 08:35:20 -07:00
kronic 36950ca21d LANTERN P1 Group B: 5-Spark systems — Aoe/Hitscan dispatch + reel/zone/decoy
Aoe/Hitscan archetype dispatch in AbilityFireSystem (both-worlds cooldown;
server-only ecb.Instantiate — the client-never-instantiates invariant; ZoneEffect
vs DecoyTag chosen by prefab membership). Harpooner REEL as a homing state
(ReelState + ReelSystem re-aim the hit Husk's KnockbackState toward the caster's
live position each tick; EnemyAISystem stays sole Position writer), stamped by
ProjectileDamageSystem on a Reel-flag hit. ZonePulseSystem (enemy-only periodic
AoE, caster attribution, no friendly fire, Vortex pull, born-0 lazy-stamp).
Decoy aggro in EnemyAISystem + DecoySystem despawn. AbilityDefBlob gains
EffectFlags (Reel) + DurationTicks. +3 ZonePulseSystem EditMode tests (497 green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 00:00:41 -07:00
kronic 24800f4bcb Attack Boon Changes 2026-07-13 18:30:41 -07:00
kronic 4febf3dfe2 Hazard: Blight geyser — permanent periodic both-sides AoE (Phase 1.5b bundle 3)
Review-first netcode slice (design review wf_900e9965-8f0 -> 11 folded;
post-impl wf_5c8299f8-299 clean). A PERMANENT periodic telegraphed AoE in
Blight-biome rooms only; one new [GhostField] uint NextEruptTick.

- Geyser component + GeyserEruptSystem (server): inverted invalid-tick guard
  (a baked-0 tick must NEVER erupt -> lazy-stamps born-correct instead of the
  party-wiping per-tick barrage), inline both-sides gather (SourceNetworkId=-1),
  reschedule = now + period (never +=), never destroyed.
- GeyserTelegraphSystem (client): absolute-tick growing warning disc +
  erupt burst on the >0->=<0 crossing, latched per NextEruptTick + arm-guard
  (never edge-detects the replicated field -> no phantom on 0->stamp /
  relevancy re-entry). Reuses ScorchDecalSystem + DynamicLightSystem.
- Seeded in RoomFieldSystem (Blight-gated on plan.Biome, born-correct staggered
  stamp from live ServerTick), GeyserFieldSpawner + authoring wired into the
  Gameplay subscene. Geyser.prefab duplicated from ResourceNode (no collider).
- BuildDisc promoted to FeedbackFx (shared with the barrel fuse ring).
- 474/474 EditMode incl. the unstamped-storm regression; live no-storm end-to-end.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 13:53:48 -07:00
kronic 21a4c71413 Hygiene B4c: clean dedup helpers (knockback, bakers, editor rig)
- KnockbackUtil.Stamp: shared knockback-stamp used by AbilityFireSystem + MeleeComboSystem (guard + planar normalize + write; speed passed in).
- BakerStructureExt: AddPlacedStructure/AddDamageable extensions on Baker<T>; rewired Turret/Structure/Harvester/Conveyor/Fabricator bakers (baked data + serialized fields unchanged).
- EnemyPrefabBakeExt.AddEnemyPrefabPool: shared prefab-buffer bake for ZoneEnemyDirector/WaveDirector authoring (fields stay flat — no serialization change).
- Editor AnimRigUtil (HasParam + root-yaw overlay clip) shared by PlayerRigTools/EnemyRigTools; EnemyRigTools.MakeMat now GUID-preserving (CopySerialized over existing) — the composite AnimatorController copy left as-is with a caveat comment.

466/466 EditMode tests pass, 0 warnings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 21:26:23 -07:00
kronic ba303e5fd0 Hygiene B3: single-sourcing & magic-number consolidation
- StructureCatalogAuthoring: WallCostOre -> WallCostBiomass (it bakes a Biomass cost; [FormerlySerializedAs] preserves the scene value).
- Harvester/Fabricator authoring: resource-id byte defaults reference ResourceId.Ore/.Charge instead of magic 2/4.
- RegionMath.RegionBoundaryX (= ExpeditionOffsetX*0.5) single-sources the region-flip X used by HudSystem + OnboardingSystem (was 500f in 3 places).
- CharacterComponent.DefaultGroundedSharpness single-sources the CC sharpness 15f (GetDefault, DashSystem, PlayerDeathStateSystem, PlayerCharacterAuthoring).
- InventorySlot [InternalBufferCapacity] references Tuning.InventoryMaxSlots.
- ConnectionMode enum -> byte-const class (project convention; removes the latent enum-in-Burst trap); field + one Seed() param become byte.
- Tuning.ChargerWindupTicks single-sources the Charger telegraph windup (EnemyBaker + TuningConfig.Defaults; was a bare 30 that could drift).
- (TicksPerSecond deliberately NOT added: no seconds->ticks conversion site exists; the tick-count fields are per-authoring designer tunables, so a const would be unreferenced.)

451/451 EditMode tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 23:29:43 -07:00
kronic 589e712db3 Hygiene B2: dead-code removal
Delete (unreferenced in any scene, per operator decision):
- TrainingDummy* chain (authoring/spawner/system/components/prefab) + UpgradePickup* chain (authoring/spawner/systems/components/prefab); remove TrainingDummyTag from the 3 live combat queries (AbilityFire/Melee/HealthApplyDamage now key on EnemyTag) and repoint HealthApplyDamageSystemTests to EnemyTag.
- Dead RPC RegionTransitSystem + RegionTransitRequest (no sender, ungated) + its test.
- Heartbeat + HeartbeatSystem (no WorldSystemFilter, ran no-op every tick) + its test.
- BuildSendSystem dead conveyor/pylon dev hooks (s_ConveyorDir, [/] rotation, Place{Pylon,Harvester,Conveyor} statics).
- Deprecated CyclePhase alias consts (Expedition/Defend/Build/*Ticks); repoint WaveSystemTests to Siege/Calm.
- Unread FeelConfig fields (HitFlashDurationMs, RumbleHeavy) + dangling HudUi doc-comments + stale crefs.

451/451 EditMode tests pass. CLAUDE.md HeartbeatSystemTests example ref to be repointed in B7.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 23:16:53 -07:00
kronic cc2e7ad95e Polishes 2026-07-07 20:51:18 -07:00
kronic 3995af736c Boss becomes a real fight + readable-but-fair enemy threat
BossState (server-only) + BossAISystem: sole mover, seek -> telegraphed
radial slam (AttackWindup) -> phase-2 speed + swarmer summon. Excluded from
the EnemyAISystem Charger pass; knockback-immune at all 3 stamp sites;
arena-anchored spawn; scaled Health/HitRadius/AttackRange. Grunt windup now
commits in its last ~30% (whiffs out-of-range); Charger stagger roots; grunt
speed 4.2->5.2; swarmer telegraph synced. SweptMove + zone-enemy spawn-stamp
extracted to shared helpers. Zero new [GhostField].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 20:21:18 -07:00
kronic 16e396841e Run Re-Do 2026-07-02 20:41:43 -07:00
kronic e32dadbc66 Slice Combat Depth (MC-3 + wiring + review fixes): Spitter aim-line + player-hit punch, rigged enemies, in-band gate (DR-041)
Completes the Combat Depth slice on top of the MC-2 server spine (56cf60cce):

MC-3 impact juice (client, observe-only):
- 7 FeelConfig fields + ResetDefaults; magnitude-scaled player-dealt-hit camera
  PunchFov on the enemy-Health-decrease edge (camera-only hit-stop, never timeScale).
- Spitter Kind==2 aim-LANE telegraph (BuildLaneMesh) — reads baked SpitterState
  client-side, falls back to a fixed length. True freeze + material flash deferred.

Content / wiring:
- SpitterProjectilePrefabAuthoring (the SpitterProjectilePrefab singleton).
- Both directors rebuilt to a 4-entry KIND-INDEXED roster [Grunt,Charger,Spitter,
  Swarmer] + mix/MaxAlive config + the SpitterProjectileConfig singleton in the subscene.
- Real rigged models: EnemySpitter (re-skinned Kaiju, ranged poker) + EnemySwarmerUndead
  (Undead-Werewolf, fast/low-HP); grunt/charger keep Werewolf/ChargerMuscle. EnemySpit =
  ownerless interpolated ghost (no Health, no collider).

Post-impl adversarial review fixes (wf_febdcfdb-665):
- [MED] in-band fire gate: the Spitter committed its telegraph from ANY range (fired while
  advancing from far). Now commits only when sInBand || sCornered (gives CorneredRange a
  real read site) — a Spitter out-of-band holds fire and repositions.
- [LOW] EnemyProjectileDamageSystem early-returns on !ServerTick.IsValid (sibling parity).
- [LOW] EnemyAuthoring bake-time guard: errors if a prefab composes both Charger+Spitter
  (would match zero AI passes -> never move).
- [LOW] tests: Spitter brain fires from Expedition (kills the Base==0 region false-green);
  a direct partition-exclusion test replaces the order-masked claim; added out-of-band +
  cornered negative tests.

388/388 EditMode green + two Play smokes (clean boot, fire, swept-hit, region, server==
client; rigged Kaiju spitter bakes + fires with zero console errors). Accepted as-is
(documented in DR-041): global spit soft-cap, co-op punch attribution.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:08:59 -07:00
kronic 56cf60cce3 Slice Combat Depth (MC-2): enemy-variety server spine — Spitter, Swarmer, 4-type mix (DR-041)
Adds the server-authoritative mechanics for three new enemy archetypes on top of
the Grunt/Charger base, plus the weighted wave-composition that introduces them:

- Spitter: a ranged Husk variant (SpitterState) that holds a preferred range-band
  (advance/retreat/hold via EnemyAIMath.BandVelocity) and fires a telegraphed,
  dodgeable EnemyProjectile. New server EnemyProjectileMoveSystem (integrate +
  store LastStep) + EnemyProjectileDamageSystem (region-filtered swept hit-test
  rebuilt from LastStep — DR-018 anti-tunnelling; players use HitRadius, structures
  a const radius; at-most-once destroy). Concurrent-spit soft cap, soft-fail retry.
- Swarmer: marker tag + deterministic cluster spawn (1 slot = 1 pack;
  EnemyAIMath.ClusterOffset), MaxAlive counts ENTITIES so a pack defers if it
  won't fit.
- 4-type weighted mix: MixBands -> ZoneEnemyMath.WaveSlots/KindForSlot/
  PackSizeForSlot drives both the expedition director and (fork-4a) the base siege,
  with a mandatory MaxAlive cap. Legacy WaveSize/IsChargerSlot kept + parity-tested.
- Discriminator stays component-presence (no enum in Bursted systems): query-
  partition guards keep each enemy moved by exactly one EnemyAISystem pass
  (sole-Position-writer). EnemyTelegraph.IsCharger -> Kind byte for the client cue.

New authoring (Spitter/Swarmer/EnemyProjectile) + expanded director authorings with
tunable mix/cluster defaults. 13 new EditMode tests (mix composition + legacy parity,
band/cluster math, projectile move + cross-region + swept anti-tunnelling regressions);
full suite green before commit.

Dormant until the prefab/subscene wiring lands (next): the new systems guard on
TryGetSingleton/RequireForUpdate, so with no prefabs wired the new types stay inert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 20:06:56 -07:00
kronic 3109b86d71 Slice 3: Expedition Combat Spine — epoch-seeded zone waves (DR-040)
Reactivate the dormant Expedition region as a procedural combat venue.
v1 loop: walk the gate -> fight an epoch-seeded enemy wave in the
expedition -> clear -> return -> flat Ore reward (once per epoch) ->
escalated retaliation base siege.

- New sim types: ZoneEnemyTag, ZoneEnemyDirector (+ ZoneEnemyPrefab
  buffer), ZoneEnemyState, ZoneEnemyMath (grunt->charger composition
  by epoch). ZoneEnemyDirectorSystem (server, Burst): drip-spawns the
  wave at a deterministic ring under a MaxAlive cap while a player is
  out and the base is Calm; marks ClearedThisEpoch on a real clear.
  [UpdateAfter(ExpeditionFieldSystem)] only (avoids a sort cycle).
- BLOCKER 1: EnemyAISystem region-filters target selection (player +
  structure snapshots gain parallel region lists; no base structures /
  no Core fallback for expedition husks).
- BLOCKER 3: WaveSystem, ThreatDirectorSystem timeout cull, and
  CyclePhaseSystem DefendCleared + Core-breach cull all count/cull
  RegionTag{Base} husks only (the breach cull was caught region-blind
  by the post-impl review: a base breach wiped the live expedition
  wave and spuriously paid the reward).
- BLOCKER 4: reward de-duped via CycleRuntime.LastRewardedEpoch +
  ClearedThisEpoch; ExpeditionGateSystem deposits RewardOre once/epoch.
- ExpeditionFieldSystem teardown also culls zone enemies + region-
  guards the clutter loop. Subscene wired with the director + roster.

368/368 EditMode green + clean netcode Play smoke. Docs: DR-040 ->
built, session log, CLAUDE.md cross-region tag-reaudit rule.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 22:58:26 -07:00
kronic f3eccec524 Slice 1: combat readability + HUD declutter (DR-038)
Four playtest do-now wins:
- Enemy health bars: pooled world-space Canvas, on-damage-sticky + fade,
  always-on <25% HP (CombatFeedbackSystem; no new replication).
- Telegraph fix: new baked client-safe EnemyTelegraph sizes the danger-cone ramp
  per enemy (0->1 ending at impact, fixes the Charger plateau); windup 18->22;
  a windup scale-pulse.
- Build-mode toggle: BuildPaletteState.PaletteOpen hides the palette by default,
  Tab / gamepad-Y toggles, with a discovery chip (HudSystem/BuildSendSystem).
- Charger committed-lunge tell: [GhostEnabledBit] IsLunging derived once/tick from
  LungeState (the Dead idiom); the danger cone persists through the lunge.

345/345 EditMode (+3 IsLunging derive tests); Play-validated: ghost-hash change
did not break the handshake, bake correct (telegraph on all enemies, IsLunging
baked-disabled on the Charger, replicated to client), no runtime errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 12:48:08 -07:00
kronic 0948d49886 Combat: ability archetype byte (MC-6 dispatch spike)
byte Archetype on AbilityDefBlob (AbilityArchetype enum: Projectile/Hitscan/Cone/Aoe), authored on AbilityDefinition + baked in AbilityDatabaseAuthoring, read at dispatch in AbilityFireSystem -- NOT folded through EffectiveAbilityStats/StatRecomputeSystem (static identity, not a tunable stat; MC-4 review BURST-1). All current abilities are Projectile (0) -> zero behaviour change; the dispatch read-point is the de-risk spike for MC-6 hitscan/cone/aoe.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 17:45:33 -07:00
kronic da522efe7a Vault Re-Alignment 2026-06-09 23:26:20 -07:00
kronic 51401d2c2b Further Tests & Progress 2026-06-04 11:35:57 -07:00
kronic e362aaeb43 Import art/VFX asset packs + game-feel systems; normalize texture extensions to lowercase for LFS
Add BefourStudios SciFi environment packs, Gabriel Aguiar VFX, and the
ShaderCrew Toon Shader embedded packages, plus combat/enemy/wave/death
gameplay systems and supporting vault docs/screenshots.

Rename 11 vendor textures from uppercase .PNG/.HDR to lowercase so the
case-sensitive Git LFS filters (*.png/*.hdr) match on case-sensitive
filesystems (Linux CI, case-sensitive macOS), not just locally where
core.ignorecase=true masks the gap. Each .meta moved with its asset so
GUID references are preserved. All ~1000 binaries tracked via LFS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 22:50:43 -07:00
Luis Gonzalez 1f647dd5e1 Initial Combat Implementation 2026-05-31 21:35:12 -07:00