Commit Graph

188 Commits

Author SHA1 Message Date
kronic b407f7cd6f Art/Fix: A0 gate pass — death-pose lock, off-palette drift, lighting debris
Found by running the A0 style-proof against the SHIPPING scene instead of
ArtStaging (which judges static glTF bakes on an import shader, with zero
SkinnedMeshRenderers and no Animator — it cannot answer "does the game look
like this").

Player-facing bugs fixed:

- AC_PlayerTopDown/AC_EnemyTopDown "Death" had ZERO outgoing transitions.
  Any State enters on IsDead and nothing ever leaves. The player ghost is a
  persistent entity, so its Rukhanka animator never resets: once you died you
  rendered sprawled on the seabed permanently — sim fully respawned, moving and
  fighting, visually a corpse. Added Death -> Idle on (IsDead == false).

- AmbientMotionSystem drift was still the deleted biome system: key 0 =
  "meadow", MeadowMoteColor (0.62, 0.85, 0.60) = GREEN motes, 600 of them in a
  36x7x24 box following the camera — the most off-palette thing in the frame.
  Its x>500 region probe pointed at space now holding zero renderers. Collapsed
  to one cold marine particulate; dropped the 4 dead mote colours + AridWind.

- FeedbackFx.MakeParticleMaterial built Sprites/Default with NO texture, so
  every procedural particle rendered as a hard SQUARE. Added a procedural soft
  dot (no Resources.Load — build-stripped; asset-free presentation is the rule).

- Game.unity carried a stock Unity "Directional Light" (warm-WHITE, 1.05, Soft)
  outranking KeyWarm as a second competing shadow caster, plus 6 orphaned
  LandmarkLights — four at x=1030/1530 lighting a kilometre of empty water, two
  with no renderer within 12u, two of them purple. All 7 deleted. Added RimCold
  for silhouette separation; key:fill set to the tuned 3.9:1; WarmPool -> Soft.

ArtStaging (kept as a lighting lab): KeyWarm 0.15 -> 0.85 — it was the only
shadow-caster yet sat BELOW GloamFill 0.22, which destroys form by definition
and is what read as "flat". StagingAmbiance was attached to nothing and its
flora wiring searched for a Game.unity parent, which is what read as "static";
it also force-played the combat one-shot pool, now restricted to looping
emitters. Flicker raised to a measured x2.11 cold swing vs x1.03 warm.

304/304 EditMode green; death-recovery, palette and particulate all verified
live in Game.unity Play.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 14:45:18 -07:00
kronic e42760e7d0 Repo: reclaim 8.5 GB of unreachable vendor content (audit L7/L8/M13)
Assets/ 14 GB -> 5.5 GB.

- Assets/BefourStudios DELETED (8.2 GB). Transitive-closure reachability
  from every project scene, prefab and settings asset found exactly FOUR
  reachable files in the whole pack — four textures. Relocated them to
  Assets/_Project/Textures/Env via AssetDatabase.MoveAsset with the GUIDs
  verified preserved, then removed the pack. It was HDRP art for a
  direction DR-051 deleted; re-downloadable from the Asset Store.
  (3.3 GB of that was gitignored .unitypackage archives git rm could not
  see — removed separately.)
- 92 vendor demo/gallery/overview scenes deleted (294 MB). They are the
  ten largest tracked blobs in the repo, stored as non-LFS YAML that
  Unity must parse and index on every database rebuild. Build settings
  reference only MainMenu and Game.
- com.shadercrew.the-toon-shader.3d + .core removed (132 MB embedded,
  referenced by nothing).
- Assets/Screenshots (182 PNGs, 22 MB) moved to the gitignored
  _visual_scratch/ — Unity was importing them as textures.
- manifest: dropped com.unity.ai.navigation and com.unity.cinemachine
  (zero references — no NavMesh assets, no Cinemachine in any scene).
  Pinned com.coplaydev.unity-mcp to a SHA instead of #main; that floating
  branch ref silently re-resolving IS what the dirty packages-lock.json
  was, and it means two machines can run different bridge versions while
  both match the committed manifest.

KEPT after checking, against the audit's suggestion: visualeffectgraph
(27 .vfx assets) and timeline (213 .playable) are genuinely used. And I
RESTORED com.unity.ai.assistant + com.unity.ai.inference after removing
them left half the AI Toolkit resolved in Library/PackageCache and
crashed two AssetImportWorkers on domain reload — editor-only tooling is
not worth destabilising the install for.

Verified after: 0 compile errors, 304/304 green, DevSandbox plays with
the player, an enemy, live socket stats and no leaked RPCs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 13:39:13 -07:00
kronic 0744cdf4f3 Art: EmissiveGloam DOTS instancing + revive EnemyRigTools + drop dead materials (audit M7/M8)
M8 — ProjectM/EmissiveGloam had no DOTS instancing but is bound to
M_Drowner_EyeGlow on EnemyDrowner.prefab, a baked GHOST prefab that
Entities Graphics renders through BatchRendererGroup. Its skinned sibling
has carried the pragmas since 07-16; this one was simply missed, and murk
hides the symptom (CLAUDE.md: "a dark-lit screenshot MASKS material
bugs"). Added #pragma target 4.5 + multi_compile DOTS_INSTANCING_ON +
UNITY_SETUP_INSTANCE_ID, and a DepthOnly pass so the glows stop being
absent from the URP depth texture (soft particles / SSAO / DoF punch
straight through them otherwise). Verified: shader compiles, isSupported,
2 passes, 0 messages.

M7 — EnemyRigTools was dead at EVERY entry point. All eight hard-coded
prefab paths were deleted by DR-051, and the template check ran BEFORE
the idempotent in-place branch, so even re-running a builder on an
existing prefab failed. The three shipping skinned creatures were
unreproducible. Now the template only matters when there is no output to
edit in place, and a new creature templates off the shipping EnemyDrowner
ghost (GhostTemplate) instead of the deleted Enemy.prefab. Retired the
four menu items that drove the deleted Werewolf/Kaiju/Charger bestiary
rather than leave them advertising entry points that cannot work.

Deleted 19 materials with zero references from any scene, prefab,
ScriptableObject, script or settings asset — verified three ways, not
from the audit's list. Kept everything with a live reference, including
several the audit's asset-only scan called dead but which code loads by
path (M_Skinned_Palette, PixelOutline, M_Env_Fallback).

NOT fixed here, deliberately: MakeMat still points each creature at a
per-PACK Synty atlas rather than the shared palette. That is a visual
decision about the shipping Drowner/Grindylow, not a mechanical fix — the
doc-vs-reality gap gets reconciled in Art_Direction_Lantern instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 13:30:43 -07:00
kronic b80aa1b24b Tests: tuning invariants + Authoring reachable from the test asmdef (audit M10/M11/L18)
- New TuningInvariantTests (6 tests). Two gaps the audit named:
  * The six-site knob drift: adding a knob touches the struct field,
    Defaults(), the TuningKnob const and three switches, and nothing
    caught a knob wired into Apply but forgotten in ClampKnob. The clamp
    is the only thing stopping a 0 reaching the i-frame divide, which
    TuningConfig's own header records as "NaNs the kinematic body
    permanently". Now every LIVE knob round-trips Apply -> Get against
    ClampKnob.
    The knob set is read by reflection, not assumed to be 0..Count:
    CLAUDE.md reserves retired indices (20-23), so the space has holes
    on purpose. A second test pins that those stay reserved — re-using
    one would silently re-mean a value in saved feel profiles and in the
    DebugOp wire payload.
  * MeleeTiming had ZERO test references while producing the locked
    20/12/25 contact ticks, and MeleeComboTests pins fixture values that
    differ from the shipped defaults on nine of ten knobs. The new tests
    assert RELATIONSHIPS against Defaults() — finisher contact stays
    inside both CastFacingTicks and MeleeRecoverTicks — so a deliberate
    retune stays green and only a broken coupling fails. That coupling
    was previously enforced only by a [MenuItem] a human had to remember
    to run.
- Test asmdef now references ProjectM.Authoring + Unity.Entities.Hybrid,
  so bakers are reachable from tests at all (L18). Nothing referenced
  them before, which is why "no prefab carries ChargerAuthoring" could
  coexist with a green suite.

CORRECTION to the audit: "10 test files leak ECS Worlds" is REFUTED.
That finding came from counting `.Dispose()` tokens, which misses the
`using (world)` blocks these files actually use. Measured empirically:
World.All is 6 before the suite and 6 after — zero leaked.

304/304 green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 13:24:50 -07:00
kronic 37b211a7f8 Netcode: fix interpolated-tick cues + add a terminal RPC reaper (audit M1/M4/M12)
M1 — two systems timed INTERPOLATED ghosts against the PREDICTED tick,
the exact hazard CLAUDE.md documents and the one that is invisible on
loopback:
- EnemyDangerTelegraphSystem timed the red danger cone off nt.ServerTick,
  so over a real connection the dodge tell finished ~RTT/2 + interp
  buffer EARLY. The cue lied.
- PlayerAnimationDriveSystem fed the same predicted tick to RemoteDriveJob
  ([WithDisabled(GhostOwnerIsLocal)] — i.e. interpolated teammates), so a
  teammate's swing animation desynced from their damage.
Both now use the ZoneTelegraphSystem idiom. The LOCAL drive job keeps
ServerTick: the owning player really is predicted.

M12 — the RPC leak I reproduced live during the audit. Every receiver in
this project gates on RequireForUpdate over a scene-baked singleton; in a
scene without it the receiver never runs and the request entity is never
destroyed. Netcode's WarnAboutStaleRpcSystem Consume()s but never
destroys, and is compiled out of player builds — so these accumulated
silently, and worst in a shipped build.
New StaleRpcReaperSystem (server, OrderLast, no RequireForUpdate) destroys
any unconsumed request that outlived its receiving frame. Consumed
requests are left to their owner. Verified live: a planted unconsumed
request is gone within a few frames. Three regression tests pin both
halves of the contract.

Also: HealthApplyDamageSystem and ProjectileDamageSystem now filter
.WithAll<Simulate>(). They are ServerSimulation-only so it was not a bug,
but the audit's "all predicted systems filter Simulate" reassurance was
false until now — the rule is unconditional again.

The five undisposed Allocator.Temp ECBs the audit flagged all lived in
systems the purge deleted; none remain.

298/298 green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 13:17:47 -07:00
kronic 9f61f7c6fe LANTERN kit into the shipping scene + frame rename (audit H2/M4)
H2 was the audit's sharpest finding: in Game.unity every player spawned
with four ability sockets pointing at SparkIds the baked AbilityDatabase
did not contain, so all four resolved to Damage=0 Range=0 Cooldown=0.
Melee and dash were the only working combat verbs in the built game.
Cause: the 5 LANTERN Sparks were added to GymSub.unity and never to
Gameplay.unity.

- Gameplay.unity's AbilityDatabaseAuthoring now carries all 9 defs (the
  4 legacy ids keep their numbers; Sparks are 5-9) with their effect
  prefabs. Live-verified in Play: sockets now read
  Vortex 8dmg/6range/420cd, Blink 20range/1cd, Hook & Pull
  15dmg/25range/120cd, Light Zone 6dmg/5range/480cd.
- Removed 6 orphaned authoring GameObjects the purge left behind in the
  subscene (StorageSpawner, StructureCatalog, ItemDatabase,
  SpitterProjectileConfig, BoonCatalog, MetaCatalog) and the RoomDressing
  object in Game.unity — the latter is what scattered 47 Synty desert
  props into the seabed murk.
- Deleted 4 now-unreferenced prefabs: EnemySpit, Pylon, Storage, Wall.
- Frame rename (M4): FrameKind.Warrior/Ranger -> Bathynaut/Harpooner,
  93 identifier sites. Byte values pinned (2/3), so no ghost-hash or save
  impact. The menu said "Warrior"/"Ranger" to players three weeks after
  the frames were renamed in design.
- Menu now reads LANTERN / "Light is territory — co-op descent" instead
  of "PROJECT M" / "Frontier colony — co-op" (the Awakening-Engine
  tagline, two directions stale).
- Removed the "Replay Tutorial" button and the Settings ONBOARDING
  section: both drove coach-marks DR-051 deleted. The settings fields
  still round-trip so existing settings files load unchanged.

All four project scenes + all prefabs verified free of missing scripts.
Server measured at 59.6 ticks/s against a 60 Hz target. 295/295 green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 13:11:58 -07:00
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 977b5c1f8e Art: silhouette broadening in-game + PlayerRigTools material-drift fix
Silhouette: broadened the armour's shoulder pads (inflate Shoulder_L/R-weighted pad caps about the
shoulder joint, smooth falloff, arms untouched) + beefed the boots -> Silhouette_Armour.asset (built
idempotently from the stock Synty armour). Bind pose is a T-pose, so broadening is by BONE WEIGHT, not
raw X (a naive |X| threshold would grab the outstretched arms).

Drift fix: baked the correct assignments into the tools so a re-run no longer reverts them -
BuildBathynautPlayer now does the brass/undersuit split + swaps the armour to Silhouette_Armour;
AttachBathynautKit assigns gunmetal tanks / warm beacon / Mark-V brass-gunmetal-glass (3 submeshes).
Full rebuild chain re-run clean + verified live: identical correct diver, reproducible.
(replace_method stripped the [MenuItem] attrs -> re-added; see the swallow-adjacent-line gotcha.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 15:27:29 -07:00
kronic 9f9c3b07b9 Art: Bathynaut body-swap into the gameplay Player (Mark-V + brass/teal split)
The approved staging character is now in the shipping animated Player.prefab:
- Re-exported the skinned kit FBX dome-less + the Synty Mark-V helmet skinned to the Head bone (3
  submeshes brass/gunmetal/glass); replaced the old fused dome.
- Split materials: brass armour, dark-teal undersuit, gunmetal tank pack, warm shoulder beacon, teal
  porthole glow.
- ★ per-instance _BaseColor gotcha: the hit-flash system sets URPMaterialPropertyBaseColor=(1,1,1) on
  every player render child, which REPLACES the material _BaseColor -> flat-color materials washed
  cream. Fix = drive color via a solid-color _BaseColorMap texture (DiverTex/), not _BaseColor.
Verified live in DevSandbox from the game camera: copper Mark-V + brass armour + teal undersuit +
gunmetal tanks + warm beacon, animated, reads at true game scale.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 14:57:02 -07:00
kronic be55683f11 Art: restyle Mark-V helmet to match Synty (flat palette + faceted, drop photoreal texture)
The AI-generated helmet's photoreal copper texture + smooth high-poly dome clashed with the flat-shaded
low-poly Synty suit. Restyled to match: dropped the baked texture, decimated 4.2k->1090 tris for chunky
facets, flat-shaded (hard normals), and painted it with the suit's OWN flat palette materials -
M_Diver_Brass bonnet + M_Diver_HelmetMetal accents (valve/collar/bezel) + a new M_Diver_Porthole teal
glass. Now shares the suit's exact materials so cohesion is guaranteed; the teal porthole also ties into
the bioluminescent palette. GLB dropped 1.7MB->736KB.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 14:16:32 -07:00
kronic 69685a665a Art: fix Mark-V helmet decimation holes - clean watertight 4.2k-tri mesh
The 0.10-ratio collapse tore the generated helmet (holes + fragmentation). Re-imported fresh, welded
doubles + recalc normals + deleted loose geometry FIRST, then a gentler 0.18 collapse -> 4198 tris with
0 boundary edges (watertight). Re-exported the static staging GLB; ArtStaging now shows a clean copper
Mark-V (bolted porthole, seam ridges, top valve) at head scale.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 12:29:03 -07:00
kronic 059458db8b Art: fix Mark-V helmet scale (was 100x too small / invisible) - now a rigid head attachment
The generated helmet is meter-scale but the suit rig is cm-scale (0.01 armature); skinning it applied
the armature's 0.01 -> the helmet imported at ~5mm (invisible). Fix: make the helmet a RIGID
attachment (dropped the mis-bound skinning), sized correctly (~0.5m) at the head. Re-exported static +
ArtStaging now shows the copper Mark-V clearly on the brass diver.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 12:17:13 -07:00
kronic c88e6f3c7a Art: AI-generated brass Mark-V diving helmet (replaces the golf-ball dome)
Scripted primitive helmets kept reading as golf-ball/blocky-robot, so generated a proper classic
brass Mark-V (Hyper3D text-to-3D): rounded copper bonnet, bolted round porthole, rivet seams, top
air-valve. Decimated 23k->2.3k tris, skinned to the Head bone, replaces the old dome + porthole kit
in the master .blend. Static staging GLB re-exported + ArtStaging updated (reads as a real diving
helmet). Gameplay body-swap (this helmet + brass armour + silhouette onto Player.prefab) is next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 12:08:22 -07:00
kronic 2d47287b15 Art: propagate the Bathynaut overhaul to the gameplay player (kill the lamp-head)
Re-exported the skinned kit from the ONE master .blend with the reshaped diving helmet, grouped into
Metal/Beacon/Porthole SMRs. Darkened the helmet (M_Diver_Metal_Skinned flat gunmetal - the AnimatedLitShader
was multiplying the tint by the gold PaletteAtlas sample, so the atlas map is cleared to force the flat dark
base), kept the warm shoulder-lamp beacon, dimmed the porthole (M_Diver_PortholeGlow_Skinned), shifted the body
to a cool diver tone. Rebuilt Player.prefab via the proven PlayerRigTools graft chain. Verified live in
DevSandbox from the game camera: the gold-dome lamp is gone. Remaining full-match gap (brass-armour/teal-
undersuit split + the shoulder/boot silhouette edits) needs the Synty body replaced by the .blend body.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 21:17:50 -07:00
kronic 8df43b8307 Art: Bathynaut helmet reshape (kill golf-ball) + stronger silhouette
Reshaped the helmet dome from a squashed sphere into a diving-helmet form (modest vertical stretch +
flatter faceplate + chunky collar ring + bigger porthole bezel); broadened the outer shoulder pads and
beefed the boots for a heavier, more imposing silhouette. Master .blend is the single source; static
posed GLB re-exported + ArtStaging updated (connected instance, diver materials intact).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 20:58:15 -07:00
kronic 8b50753f93 Art: ArtStaging overhaul - game-cam POV system + Bathynaut character (no longer reads as a lamp)
Camera: runtime POV switcher (StagingCameraSwitcher; V/]/[ cycle, 1-4 jump) with POV_1_Game matching
the in-game rig (Pitch45/Dist13/FOV55) as the default + hero/front/close-up; deep-water SolidColor
clear kills the no-skybox corner bleed at the wide game framing.

Character (the 'reads like a lamp' fix, operator-directed): darkened the helmet to dark gunmetal with
a dim lit porthole and moved the warm beacon to the shoulder lamp (light is carried, not the head);
color-blocked the body into a brass-and-teal deep-sea-diver palette (brass armour / dark-teal
undersuit / dark-metal kit) for value contrast + identity at game scale; bulked the back tank-rig
silhouette. Master .blend keeps rig+pose+materials re-editable; posed static GLB reimported into the
connected prefab instance with instance material overrides reset to the GLB's diver materials.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 20:34:36 -07:00
kronic eaff8d16e3 Art: pose the Bathynaut suit out of T-pose (rig cleanup + posed static bake)
The suit .blend was rigged, but the base body/armour/head had vertex groups with NO Armature
modifier (why the export baked a static T-pose) and 2 orphan lamp parts were unweighted. Added the
modifiers, weighted the lamp parts to Spine_03, posed a grounded combat-ready stance (shoulders
down ~63deg, elbows braced forward ~22deg), baked the pose into static geometry (depsgraph
new_from_object) and re-exported. Master .blend keeps the rig+pose re-editable; the in-place GLB
overwrite flowed into the connected ArtStaging prefab instance (38 parts intact, materials +
extracted staging emissive preserved). Suit width 2.05m T-pose -> 1.04m posed; A0 silhouette now
reads from the top-down game camera.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 18:43:36 -07:00
kronic f3aec94c48 HUD: ability bar defaults hidden until a local player exists
Fixes the empty-bar leak into ArtStaging / menu / pre-connect: AbilityBarSystem.OnUpdate
early-returns when there is no valid NetworkTime, so the 'hide when no local player' line never
ran. Root now DisplayStyle.None at build, flips to Flex only when the local player is found —
also kills any pre-connect flash in gameplay.
2026-07-22 18:26:24 -07:00
kronic 1015f5d3fa Art: ArtStaging A0 value/composition rework (light-is-territory)
Global fill cut (KeyWarm 1.25->0.15, CausticsSpot 32->9, GloamFill 0.5->0.22) so the scene
goes dark-except-where-ours-reaches; WarmPool point light -> downward warm SPOT = a defined
ground-territory disc that lights the suit top-down (a low point light was blasting the chest
into a blown bloom streak). Suit lamp + Drowner gloam emissives extracted from .glb sub-assets
to durable .mat assets (M_Suit_LampWarm_Staging, M_Drowner_GloamAccent_Staging). Recomposed the
triad (crate in-pool / Drowner faced-to-camera at the lit edge / suit center). Grayscale-verified:
the beacon dome is the value winner + the warm disc reads as territory. Suit pose still T-pose
(a Blender rig sitting; A3-adjacent).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 18:26:24 -07:00
kronic 5569fcd552 Fix: socket auto-recast at every cooldown reopen (raw InputBufferData IsSet = ever-pressed)
Netcode accumulates InputEvent counts on the wire; only the decoded component is delta-corrected.
AbilityFireSystem's windup resolve gated on raw IsSet, so after the first press every socket
re-fired the instant its cooldown reopened (live repro: recasts at exactly t3933/t4353 with zero
input). Gate is now a count-STEP vs the previous tick's command; missing prior command = no-fire.
Also lands the G6 ConeContactPending schedule machinery + the cone test fixture (wire-true
monotonic counts) + regression Cast_Never_Refires_When_The_Cooldown_Reopens. 430/430; live proof:
one tap -> one cast -> silence across 2+ reopens.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 13:28:08 -07:00
kronic 040463ad07 HUD: ability/cooldown bar (sockets 1-4 + dash); socket-0 charge strip removed
AbilityBarSystem (own UIDocument, sortingOrder 49, the B5 sibling pattern): per-slot Spark
initials/name from the AbilityDatabase blob, archetype tint, drain overlay + seconds countdown +
ready flash; dash rides DashCooldown vs TuningConfig.DashCooldownTicks (Defaults() fallback).
HudSystem's single-socket blue charge strip removed (it tracked socket 0 only).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 13:28:08 -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 c5f73c52dd Weapon grip: operator reverted the anchor to the seed grip and rebaked
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 00:29:07 -07:00
kronic 0ff11fe2a9 Enemy hit-reacts: React/Stagger anim tiers off Health-drop edges (the Rukhanka-safe flinch)
SwordCombat React (1.4x, 0.3s pulse) + Stagger (1.2x, 0.55s) as Any-State
states on AC_EnemyTopDown via EnemyRigTools.WireEnemyHitReacts; driven by
EnemyAnimationDriveSystem's cache (now Pos/Hp/ReactUntil/Heavy) off
replicated Health drops. Windup-honesty gate: light reacts require
!IsAttacking (a sub-poise hit never visually cancels a live windup);
the heavy tier tracks the server's B2 poise break (stagger threshold 50
= finisher staggers, light flinches at the locked tuning). Knobs:
HitReactSeconds (0=off) / HitStaggerSeconds / HitReactStaggerDamage.
Replaces the review-cut positional vibrate (Rukhanka inverse-fold no-op).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 00:28:11 -07:00
kronic ce0faafb72 HEAVY FEEL LOCKED: the A/B winner folded into defaults, clips retimed to zero contact drift
recover 36 / dmg 36 (DPS 60 held) / contact 20 (20/12/25 per step) /
grace 28 / buffer 10 / move-commit 0.25; arc 0.8, finisher hold 7,
connect kick 1.1. Clip state speeds retimed 1.0/0.85/0.88 so the VISUAL
blade contact matches the damage tick exactly (audit: zero drift; probe:
gaps 36/36/54, contacts +20/+12/+25 measured). Step-3 contact sits 1
tick under CastFacingTicks 26 (documented coupling). baseline profile =
the locked defaults; heavy-committed kept as the record.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 00:13:49 -07:00
kronic 7f032571df Weapon grip anchor: gizmo-authored WYSIWYG grip + operator's hand-tuned grip baked
WeaponGripAnchor under Hand_R in Player.prefab carries the actual axe
mesh as an EditorOnly preview (baker skips it; play-verified single axe)
so grip manipulation is the real model live in the prefab stage;
AttachMeleeWeapon reads the anchor (consts = seed/fallback). Includes
the operator's first gizmo-tuned grip (rebaked mesh matches expected
radius exactly). PlayerRigTools also carries the heavy-lock clip
re-speeds (1.0/0.85/0.88) consumed by the next commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 00:13:48 -07:00
kronic 2710d680b4 Sandbox target dummy: planted EnemyTag ghost + DevSandbox respawn spawner
GymSub bakes no WaveDirector (why sandbox enemies never spawned); the
sandbox's combat target is now a TargetDummyTag'd enemy ghost all five
EnemyAISystem passes exclude (planted; knockback stamps inert), spawned
at player+3m with 400 HP by an editor-only scene-gated server system,
dying through the normal Dying path and respawning 1.5s after the corpse.
EnemyTag-reuse audited: sandbox-only by design (cleared-checks would
count it elsewhere).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 00:13:47 -07:00
kronic 730bad3d74 Data-driven tuning bench: feel profiles (JSON gestalts + overlay A/B), asset-derived timing audit, server-measured combat probe
FeelProfileService: partial-apply profiles ride the authoritative SetTuning
path + FeelConfig reflection; Save-current captures hand-dialed state; 3
starter profiles (baseline-0720 / heavy-committed / snappier, DPS-held).
TuningAuditTools: contact truth derived from clip WindUp takes / state
speeds vs MeleeTiming (drift detector), coupling invariants, cadence/DPS,
reach-honesty ratio off the baked weapon mesh (now x0.93/x1.16, was >2x).
CombatProbe: dummy + injected mash chain, per-swing server-measured
start/contact/damage + cadence/DPS report. Verified live: snappier profile
apply -> measured 24/24/36 gaps, +12/+8/+15 contacts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 21:28:33 -07:00
kronic 2b742f0179 DebugOverlay: tuning rows for the 07-20 melee feel knobs (contact/buffer/finisher-reach)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 21:04:37 -07:00
kronic 7b65912f30 Melee feel overhaul: SwordCombat anims at heavy cadence, salvage axe, damage-at-contact + buffer + dash law (guidelines forks 1-6)
07-18/19/20 arc: LightCombo01/HeavyCombo01 clips onto Swing1-3/Slam at
~natural speed (26-tick window, 30-tick recover, DPS-held damage retune),
Menacing01 combat idle (InCombat), SM_Wep_Axe_Large_01 rigid-skinned to
Hand_R at x1.25, LANTERN FX retone + blade-smear ribbon. Forks 1-6 per
Combat_Attack_Feel_Guidelines (design review wf_000bc247): cleave resolves
at the CONTACT tick (MeleeCleavePending schedule-and-consume, knob 31,
0=legacy; connect cues moved to contact), MeleeRange 2.2 + reach-only
finisher mult 1.25 (knob 30), BufferedAttackTick GhostField input buffer
(knob 29, unlock-edge validity), dash refused pre-contact (lookup-based).
Tests: MeleeComboTests pin legacy knobs; +3 fork tests (414 green); live
server proof: HP drop exactly at swing+16 under tick batching.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 21:03:18 -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 210d307406 LANTERN realignment P5: Bathynaut suit body onto Player.prefab (in place)
New PlayerRigTools.BuildBathynautPlayer (menu: ProjectM/Animation) - forks the
proven EnemyRigTools recipe: strips the Synty-soldier skeleton+SMRs from
Player.prefab IN PLACE (GUID preserved; ghost/authoring/CC/Animator/
RigDefinitionAuthoring untouched), flattens the SpaceSoldier_HelmetArmor suit
body under the root, keeps the -0.90 feet offset, re-slots
M_SuitFrame_Bathynaut_Animated on every SMR, adopts the shared CharactersAvatar
(AC_PlayerTopDown muscle clips retarget). 17 inactive Synty variant SMRs stripped.
Both frames share this visual until per-frame models land; the brass-dome/tank
kitbash attachments are a follow-up /art-dev export.

Play-verified in DevSandbox: suit renders + idles correctly under the LANTERN
murk, Rukhanka rig baked with all 9 drive params, dev overlay alive in the
renamed scene, no console errors.

=> Movement/animation tuning is now UNBLOCKED (the operator's next priority).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:31:07 -07:00
kronic 12d5b96b71 LANTERN realignment P4: Gameplay subscene -> seabed arena roster + old enemy prefabs deleted
- WaveDirector + ZoneEnemyDirector rosters re-pointed (ORDER-CRITICAL before prefab
  deletion: null-skip pools collapse kinds): [Drowner, Grindylow, Drowner, Drowner]
  (grunt/charger(boss)/spitter-slot/swarmer-slot; ranged+pack kinds fall back to
  Drowner until LANTERN kinds land in Phase 2).
- WorldColliders_Landmarks + WorldColliders_Props deleted from the subscene (their
  visuals died with the host-scene biomes -> they were invisible walls). Boundary
  rings + room cover + all spawners/configs kept.
- 10 old-theme enemy prefabs deleted (Enemy, Brute, Charger, ChargerMuscle,
  Spitter, Swarmer(+Undead), Werewolf(+Undead), Kaiju); EnemySpit kept for a
  future ranged kind. Zero dangling GUID refs (verified).

Play-verified in Game: Drowner wave spawns, seeks, strikes; AFK player dies and
respawns (full loop); no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:24:31 -07:00
kronic c58439d33a LANTERN realignment P3: one look everywhere + scene surgery
- PostFX_Lantern.asset: the ONE shared grade (ACES, bloom 0.6 cool-tinted for the
  HDR gloam, vignette 0.28, faint teal filter) applied to Game, DevSandbox, and
  ArtStaging; PostFX_DarkSciFi / PostFX_Daylight / Sky_DaytimeProcedural deleted.
- Env_SeabedKit.prefab: ArtStaging's environment (seabed, flora, rocks, marine
  snow, caustics, warm pool, gloam fill, key light, StagingAmbiance animator)
  prefab-ized and placed in Game + DevSandbox; ArtStaging connected to it.
- Scene surgery: old DevSandbox.unity deleted; Gym.unity RENAMED DevSandbox.unity
  (GUID preserved -> GymSub wiring + the F1/F2 dev scripts that gate on the
  'DevSandbox' name come back to life). SyntyWorld root deleted from DevSandbox;
  BaseBiome/ExpeditionBiome/Slot1 deleted from Game.
- RenderSettings unified: no skybox, Exp2 teal fog {0.02,0.10,0.12} @ 0.035, flat
  near-black ambient {0.03,0.055,0.08}; camera clearFlags -> solid deep-water.
- ScenePolicy.IsGameplayScene() replaces the six scene.name=="Game" string gates
  (Game + DevSandbox share the dynamic look; menu/ArtStaging untouched).
- WorldAtmosphereSystem rewritten as water-column murk (LANTERN defaults; biome
  variants re-meant to kelp/trench/gloam-bloom; Ground_Arid tint block deleted).

390 green; Play-verified in Game: murk values live, warm-vs-cold reads, no errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:12:00 -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 4a8220ad3e LANTERN purge B6: delete the legacy single-ability path (sockets are THE ability model)
AbilityRef, AbilityCooldown, EffectiveAbilityStats, DefaultAbility deleted.
GoInGameServerSystem seeds the per-frame 4-socket Spark loadout UNCONDITIONALLY
(was gym-only); ClassSelectReceiveSystem + DebugOp.SetClass swap FrameId +
re-seed sockets + zero SocketCooldown; ClassSwapUtil.Apply drops newAbilityId;
EquipSystem weapons become stat-sticks (GrantedAbilityId removed from the item
blob/authoring); StatRecomputeSystem folds CharacterStatsRef + sockets only;
HUD cooldown bar reads socket 0 of SocketCooldown/EffectiveSocketStats; class
HUD readers are FrameId-only (ClassForAbility/AbilityFor deleted);
DebugModifierInjectionSystem drops CycleAbility.

390 tests green; Play-verified: a non-gym spawn gets frame=2 with Sparks
[7,8,6,9] and no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:47:12 -07:00
kronic b34945c2d2 LANTERN purge B3+B5: delete the cycle/core/win-lose spine + onboarding; save epoch v7
Deletes CyclePhaseSystem, GoalReachedSystem, CoreDamage/CoreRestore, ThreatDirector,
CoreIntegrity/GoalProgress/RunPhase/RunOutcome/ThreatState components,
CoreVisualFeedbackSystem, and the whole Client/Onboarding slice (+6 test files).

Keepers reworked: RunDirectorSystem (UpdateBefore attr + launch guard + goal/threat
bank removed; sole SaveRequest raiser now), CycleDirectorSpawnSystem (ledger/meta
host only), WaveSystem UNGATED (waves run wherever a WaveDirector is baked),
EnemyAISystem core-fallback stripped, AmbientAudioSystem reworked (bed + run cues;
no CycleState gate), MusicSystem RunInfo-only, HudSystem big trim (goal meter, core
bar, siege banner, terminal banner, outcome flash, onboarding hook all gone),
MetaShop/ClassPrep/AimReticle siege gates dropped, DebugOverlay/ops re-meant
(SpawnWave=force next wave, EndSiege=quiet arena; SetCalm/AdvanceGoal/SetHeat
retired, bytes reserved), TuningConfig Core knobs retired (ids 20-23 reserved),
StorageMath.DrainFraction deleted, HowToPlay copy rewritten.

Save epoch v7 (fresh epoch, operator-approved): SaveData drops goal/core/outcome +
conveyor/machine-IO fields; MinLoadableVersion=7; PendingSave/PendingStructure
trimmed; RollTerminalCampaignForward deleted; SaveStructureScan signature slimmed.

390 tests green; Play world-creation clean (player + waves live, no exceptions).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:27:12 -07:00
kronic 835dace213 LANTERN purge B2: delete EB-2 turret defense
TurretFireSystem, TurretAuthoring, Turret.prefab, Turret component, turret cap,
B hotkey, HUD Charge chip + out-of-ammo cue, catalog entry, Tuning consts, tests
(-7, 452 green). StructureType.Turret byte + ResourceId.Charge stay reserved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:40:12 -07:00
kronic a0f6d4a5c4 LANTERN purge B1: delete the automation chain (Harvester/Conveyor/Fabricator)
Deletes the M7 production systems, automation components/math, authoring, 3
machine prefabs, and 6 test files (-43 tests, 459 green). Trims the automation
paths out of BaseRestoreSystem/SaveStructureScan/BuildPlaceSystem/BuildSendSystem/
HudSystem/HudTheme/StructureCatalogAuthoring/Tuning. RuntimePlacedTag (save
marker, a keeper) re-homed into StructureComponents.cs. StructureType byte codes
stay reserved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:32:11 -07:00
kronic 511e78556b Checkpoint: pre-realignment working tree (Gym->GymSub repoint + SyntyWorld/PostFX re-enable, SampleScene removed, PostFX_Daylight retune, ai.assistant pkg re-added)
Baseline before the LANTERN realignment & purge (plan: one look, four scenes,
Bathynaut on the player). Gym.unity edits are operator-made in-editor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:16:00 -07:00
kronic d30d96952c LANTERN P1: enemy-test Gym scene (DevSandbox-based host + minimal GymSub subscene)
Gym.unity = the dev-test host re-based on DevSandbox (camera + DebugOverlay dev UI
+ world visuals), its SubScene repointed to GymSub. GymSub.unity = a fresh minimal
baked subscene (PlayerSpawner, AbilityDatabase with all 9 abilities incl. the 5
Sparks, NetCodePhysicsConfig, WorldCollisionConfig, ProjectileSpawner, GymRoster =
GymTag + Drowner/Grindylow roster). Open Gym.unity + Play → GymTag clean-spawn with
a per-frame Spark loadout; on-demand SpawnEnemy. Subscene GameObjects still named
*_Copy (cosmetic); visuals = the operator's future underwater-match pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 08:55:39 -07:00
kronic aeb979f8d5 LANTERN P1 step 8: light-as-territory relevancy prototype (★)
Per connection, marks every ENEMY ghost OUTSIDE the player's lamp radius
IRRELEVANT (monsters in the dark aren't replicated — the gamma test). Modelled
on the proven RegionRelevancySystem: SetIsIrrelevant so players/global ghosts
stay relevant for free. Shared-set discipline — RegionRelevancySystem is the SOLE
clearer (runs every tick); LightRelevancySystem is [UpdateAfter] it and only ADDs
light hides via TryAdd (no clear; defensive against a region+light overlap dup).
Gated on GymTag (LANTERN-only; legacy region relevancy untouched). Pure decision
in LightRelevancyMath (+3 EditMode tests, 500 green). Per-player dim/bright
(variable radius) + the L3 gamma-test verification are follow-ups; the ★adversarial
netcode review is recommended before this ships.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 08:51:24 -07:00
kronic 342a39a540 LANTERN P1 step 5 + §8: two-frame identity via FrameId + per-frame gym loadouts
FrameId (replicated frame/class signal) now WRITTEN server-side at spawn for all
players; the two class-HUD readers (ClassPrepPortal, MetaShop) read FrameId (with
an AbilityRef fallback for pre-FrameId players) instead of ClassForAbility. The
gym seeds a PER-FRAME default Spark loadout via ClassTraits.FrameLoadout —
Harpooner (Ranger slot): reel/mobility/skillshots; Bathynaut (Warrior slot):
pull-in/dash/zone-control. FrameId uses ecb.AddComponent (baked on the real
player; absent on the minimal MetaSeeding test prefab). 497 EditMode green.

Deferred to a focused pass (risky wholesale refactor, "still works" via the
transition): full removal of legacy AbilityRef/AbilityCooldown/EffectiveAbility
Stats (woven through equip/class/meta/StatRecompute + tests) and the CharacterId
Bathynaut/Harpooner rename.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 08:45:45 -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 b92cc7196b LANTERN P1: enemy-test gym tooling — on-demand spawn + GymTag clean-spawn
GymTag + GymEnemyRoster (+ GymRosterAuthoring) bake the gym singletons. New
DebugOp.SpawnEnemy (client SpawnEnemy wrapper + server receive case) spawns a
chosen enemy KIND (Drowner/Grindylow) from the baked roster near the sender —
replacing the wave-roster hack per the roadmap's Enemy-test GYM direction.
GoInGameServerSystem takes a GymTag branch: bypass the meta-catalog spawn guard
(a fresh gym has no CycleDirector) + seed a default Spark loadout on keys 1-4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 00:01:13 -07:00
kronic b011a367e3 LANTERN P1 Group B: 5 Spark defs + effect ghost prefabs
The 5 AbilityDefinition SOs (DecoyWisp/HookPull/Vortex/Blink/LightZone) with
archetypes, tunables, EffectFlags (HookPull=Reel), and prefab refs. Three
interpolated ownerless-ghost prefabs (EffectVortex w/ Vortex flag, EffectLightZone,
DecoyWisp) via the duplicate-ResourceNode recipe + ZoneAuthoring/DecoyAuthoring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 00:00:55 -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 cb26e68839 Art/anim: Drowner glowing eyes + Grindylow + Bathynaut suit-frame prefabs
EnemyDrowner: Emissive-Gloam eyes bone-parented to Head + boneEntityStrippingMode
=None (attachments ride the rig). New skinned prefabs EnemyGrindylow +
SuitFrame_Bathynaut. Pipeline run 3x -> A1 repeatability exceeded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 22:21:07 -07:00
kronic 4302687be4 Art/anim: EnemyRigTools + Grindylow + Bathynaut suit-frame builders
BuildGrindylow (SciFiSpace Alien, gloam-blue) = 2nd creature (A1 'twice'
repeatability); BuildBathynautFrame (armored+helmeted soldier, warm-neutral)
= suit-frame preview proving the suit body skins via Rukhanka.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 22:21:06 -07:00
kronic cb224be81b Art/anim: skinned Drowner enemy via EnemyRigTools (LANTERN)
EnemyRigTools.BuildDrowner (menu ProjectM/Animation) — SciFiSpace Crew_Male
body (same rig/atlas/avatar as the player) through the proven DR-023 path:
EnemyDrowner.prefab = ownerless interpolated ghost + AnimatedLitShader
(Skinned-Palette) gloam material + AC_EnemyTopDown + RigDefinitionAuthoring.
Structurally identical to the shipping werewolf/charger enemies -> animates
in-game via the same EG/Rukhanka path. (Renders only in the baked ECS world,
not a plain scene; ArtStaging keeps the static bake for art review.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 22:00:38 -07:00