Commit Graph

4 Commits

Author SHA1 Message Date
type-two
426bf3f33d [lane B] Hits land on the thing you hit, and the reticle finally says so
Audit item 12.

THE WHOLE COHORT WAS BLINKING. Enemy flash was ONE uFlash uniform per type, and the comment
above it said so and deferred the fix: shoot one bolus chunk in a room of eight and all eight
blinked white. That is not weak feedback, it is WRONG feedback — the single signal that tells
you which body absorbed your shot was being broadcast to every body that did not, in a fogged
tube where telling them apart is the entire skill. Per-instance now: an `aFlash`
InstancedBufferAttribute written at the same compacted draw index as the matrix (they must
match, or the flash lands on somebody else's body once anything in the pool dies). Verified
with five floaters drawn and the middle one shot: aFlash reads [0, 0, 0.9, 0, 0].

emissive.js declares the attribute unconditionally, so a plain Mesh or a pool that never
attaches one gets WebGL's default 0 and renders exactly as before. uFlash stays for the one
effect that IS per-cohort — the boss's open-node tell, where every node opens at once.

THE RETICLE ONLY KNEW ABOUT THE TRIGGER. setHot was driven by `intent.fire`, so the instrument
in the middle of the screen reported whether the player's own finger was down and said nothing
about whether the shot connected. In a game where a foe can be hit-and-unharmed (armoured
plate), hit-and-shielded (the Guardian's shut iris) or simply missed in the fog, that is the
most useful thing it could have been telling you — and the shut-iris case is exactly the one
where a player without feedback concludes the gun is broken. enemies.js now announces
`enemy:hit {dmg, blocked, dead}` and the reticle pops for it: 0.35 blocked, 0.7 landed, 1.0
kill. The tell is a SIZE pop, not brightness alone, because firing already brightens it and one
signal cannot do two jobs — firing is dimmed to 0.55 to make the room.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 22:25:50 +10:00
type-two
5a891107e2 [lane B+F] The enemies were never wearing their meshes: boot forgot to pass assets to combat
Chasing "more detailed looking enemies" turned up the reason detail never landed, and it was
not the art.

boot.js built combat as `createCombat({ scene, world, bus, rng, flags, player })` — no `assets`.
createCombat defaults it to null, so createEnemies got null, so `assets?.get?.('models', type)`
returned null for EVERY archetype and every enemy in the game has been quietly drawing its
procedural primitive. Lane D's GLBs loaded correctly, verified correctly, and were never once
rendered. spore_pod has been an icosahedron since the day it shipped; the Giardia and H. pylori
meshes from an hour ago were cones.

This is the nastiest shape a bug can have: the fallback path is INDISTINGUISHABLE from success.
`assets.get('models','spore_pod').geometry` was there and correct every time I checked it — I
was checking the loader, never the pool that consumes it. Measured after the one-word fix: pool
geometry goes 42 verts -> 6056 (spore_pod), and the new pathogens render at 2234 (Giardia) and
2500 (H. pylori).

Also in: the entity matcap the same investigation was written to prototype. emissiveMat takes an
optional matcap and applies it as LUMINANCE ONLY — sampled, reduced to luma, multiplied into the
core — so an amber foe stays exactly amber and a cyan commensal stays exactly cyan. The
ART_BIBLE readability law that the whole friend/foe system rests on is untouched by construction,
while the silhouettes stop being flat glows and start reading as lit, wet, three-dimensional
organisms. Switchable with ?matcap=0 for A/B, and absent-safe if D's matcap never shipped.
Weapons and pickups deliberately keep the flat look — a tracer is not a creature.

Net effect for playtest: this is the first build where the pathogens are actually visible as
pathogens. The GLB pipeline was correct for weeks; the wiring was one word short.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 18:31:14 +10:00
type-two
71b0663b77 [lane B+C] The phage ally: tend the flora and the biome fights for you
The first ALLY, and the reputation loop that earns it — "don't shoot the biome, it helps you"
(V2_IDEAS) made mechanical.

- combat/enemies.js + balance.js: the `phage` archetype. A friendly seeker that hunts the
  nearest FOE (not the player) and rams it — a bacteriophage bursts its host after `bursts`
  hits. Fast (26 > every foe) so it catches things, fragile (hp 8) so it is spent, not a wall.
  Entities now carry a `foe` flag (foes true; flora + phage false); kill() generalised so ANY
  ally scores nothing and never combos. Fallback silhouette is a bare icosahedron = the phage's
  real icosahedral capsid. Teal (EMISSIVE.ally), distinct from cyan "don't shoot" flora.

- combat/index.js: BIOME STANDING — one run-scoped float. flora:tended raises it, flora:harmed
  drops it 25; at the symbiotic threshold the biome BUDS a phage near you (capped 3, 3s cooldown),
  spending standing. Emits `standing {value}` for a future Lane E meter.

- levels/enemies.js: ARCHETYPES += phage; catalogue `phage`.

Verified deterministically in-engine: tending flora budded a phage, which hunted a spore_pod foe
(30hp) and rammed it dead; three-colour readability holds (amber foe / teal ally / cyan friend).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:36:03 +10:00
jing
0a038582a7 [lane B] Round 1: flight controller, cannon, enemy framework on the stub
Flight (js/flight/): tube-mode controller in spline space (s,x,y) — flow-locked
forward motion, throttle as a spring-back lean, boost + i-frames, banking chase
cam on the parallel-transport frame, arcade wall response (shove + graze damage,
never a hard stop). Twin-stick input: WASD/left-stick moves the ship in the disc,
mouse/right-stick aims, Shift/Ctrl is throttle. Gamepad supported.

Combat (js/combat/): lysozyme cannon (pooled, instanced, heat-limited with
hysteresis lockout) + antacid torpedo emitting level:neutralize. Enemy framework
with floater/seeker/turret and turn-rate-limited homing darts, spawned from C's
level:event. Coat/hull model and the full bus surface E builds against.

Measured (deterministic stepper): flow-lock exact (3s at flow 14 -> s=44.0);
boost peak 30.8 u/s; heat 4s fire -> 2s lockout; wall slam 13.3 coat at 11.3 u/s
with forward speed untouched; 10 combat draws at 55 live enemies (budget <=80);
0.10 ms/frame CPU; 0 leaks over 20 create/dispose cycles. fps NOT claimed — rAF
does not run in the automated pane. Evidence: docs/shots/laneB/.

Three findings escalated in LANE_B_NOTES:
- qa.sh gate #1 is a no-op: node --check silently exits 0 on ESM, so the syntax
  gate has never checked anything. I shipped a real SyntaxError past a GREEN qa.
  Fix + verification handed to F.
- Surf is structurally broken: the peristalsis wave (13.64 u/s) is slower than
  the player (19.6 u/s), so level 2's signature mechanic loses to mashing
  throttle. Not tunable from this lane; escalated to A/F with options.
- Custom ShaderMaterials need #include <colorspace_fragment>, else ART_BIBLE's
  hostile amber reaches the display as rgb(255,26,6). Fixed here; stub/walls
  inherit it.

js/flight/dev.html is a dev harness (boot.js has no player wiring yet); it
retires once F pastes the snippet in LANE_B_NOTES.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 08:56:32 +10:00