Warden rebuild (design)
Warden rebuild: Nova look, player-grade attack FX, smarter Survival AI
Section titled “Warden rebuild: Nova look, player-grade attack FX, smarter Survival AI”Date: 2026-10-01. Approved by Chris in conversation (“yes lets plan and do all of that”), Survival-only AI with the new look + FX everywhere (tutorial included).
Telemetry (D1 runs.timeline_json.bosses, builds 208-235):
| Group | Fights | Warden killed | Warden landed the killing blow |
|---|---|---|---|
| Survival, human (211-230) | 7 | 2 | 0 (5 died to swarmers/shooters while it lived) |
| Survival, autopilot (209-235) | 56 | 45 | 8 (~14%) |
Small human sample, but it agrees with the code. The Warden is not under-damaged (swing 56, missile 18, contact 34) — it rarely threatens:
- Fixed attack order (swing → barrage → missiles → spiral → swarm → summon), learnable in one cycle.
- Range-blind: it swings (its biggest hit) even when the pilot is far outside the 240 px reach.
- Nothing aimed: barrage + spiral are fixed radial patterns (36-shot ring ≈ 70 px gaps at 400 px).
- Stationary ~1.5-2.9 s of every ~3-4.4 s cycle; speed 88 vs pilot 260 → trivially kited.
- Enrage = faster cadence + 3 spiral arms; nothing new. Barrage wind-up (2.0 s) never shortens.
- Any drone soaks its missiles.
- Visually the dullest thing on screen: calm boss shots are tinted
Color.WHITE, missiles and telegraphs aredraw_circle/draw_arcprimitives, the body is a painterly Recraft sprite that clashes with the Nova units.
- The Warden reads as a Nova-look unit, the most imposing one on screen.
- Every Warden attack has an effect on par with the player’s Weapon FX v2 looks, in a hostile colour language that can never be mistaken for player fire.
- Survival Warden is scarier: it adapts to range, aims, moves while attacking, has a real phase 2. Still fair: every attack keeps a readable telegraph.
- We can measure whether it worked (per-attack damage telemetry).
Non-goals: damage-number increases (hit rate is the problem, not hit size); tutorial/story AI changes; other bosses; the bestiary/codex art (beyond the stale stats noted below).
A. Body — Nova rebuild
Section titled “A. Body — Nova rebuild”- New radial design
wardenintools/nova_units/nova_unit_designs.py, “jailer” theme: a central eye (iris + pupil plate), an inner ring of 8 locking plates, an outer ring of 6 heavy blades — the same negative-space plate construction / facet shading as the other units. Baked at 512 px (boss scale; swarm units export at 128) torender/enemy_sprites/nova/warden_{body,glow}.pngplus separate ring layerswarden_ring_inner_{body,glow}.pngandwarden_ring_outer_{body,glow}.png. - The core (eye + hub) is a Nova bucket in
ArchetypeRenderer(row in_NOVA_UNITS, gated byVisualLook.novalike every unit). ArchetypeRenderer never rotates, so the two ring layers are drawn by a newrender/warden_body_renderer.gd(child of main, z just above the swarm) as rotating sprites centred on the boss. - The rings carry state (the telegraph language):
- idle: slow counter-rotation (inner +, outer −);
- telegraph swing: outer ring spins up and its blades flare outward (scale 1.0 → 1.15);
- telegraph barrage/fan: inner plates part (radial offset), eye brightens;
- enraged: tint crimson (existing
BOSS_COLORrule), spin ×1.6, the eye pupil narrows.
- Classic look (
VisualLook.nova == false) keeps the old sprite bucket untouched. - A/B:
VisualLook.warden_v2(default true) switches body + FX back to the old renderer; Debug Settings row “Warden Look (A/B)” + Remote Console parity, per the toggle-competing-techniques rule.
B. Attack FX — on the Weapon FX v2 system
Section titled “B. Attack FX — on the Weapon FX v2 system”All new looks are WeaponFxLayer subclasses (one draw call each, saved _mat.tres, prewarm family,
MultiMeshCulling.disable), living in fx/boss/ so they don’t collide with the in-flight player-FX
branches. Palette: void crimson body #ff2e57 → white-hot core, with a violet rim — distinct from every
player element accent. Enraged: hotter (more white, faster turbulence).
| Attack | Current | New look |
|---|---|---|
| Barrage / spiral / fan shots (enemy_proj from TYPE_BOSS) | white dots in the shared enemy-proj MultiMesh | warden_bolt: elongated crimson plasma bolt along velocity, white core, short tail. Drawn in place of the dot for boss-sourced projectiles (their dot gets alpha 0 in _enemy_proj_colors while warden_v2 is on). |
Homing missiles (sim.boss_missiles) |
two draw_circles + a line |
warden_missile: arrow-head body + flickering exhaust plume + fading trail |
| Missile impact / launch | ring primitive in FxManager | warden_burst: shader shock-ring + sparks (shared by launch/impact/summon) |
| Swing telegraph + slash | draw_arc + jagged lines |
warden_swing: shader danger ring that fills as the wind-up completes, then a crescent shear sweeping the full circle on hit |
| Barrage wind-up + eruption | draw_circle vibration + rings |
warden_charge: converging energy ring + noise corona while charging; eruption = plasma ring burst (Plasma Nova technique, hostile palette) |
Swarm drones (is_homing == 2) |
overbright magenta dot | warden_drone: tiny dart with comet trail |
| Aimed fan / lunge telegraphs (new) | — | warden_lane: a thin flickering lane wedge showing the fan arc / lunge path for its telegraph time |
C. Survival behaviour (gated BossWarden.survival(sim))
Section titled “C. Survival behaviour (gated BossWarden.survival(sim))”Tutorial/story Warden keeps its current 4-attack loop exactly.
- Range-aware attack deck. Replace
attack_idx = (idx+1) % nwith a weighted pick by distance band (close < 300, mid 300-600, far > 600), drawn fromsim.rng(deterministic; Warden spawns at 90 s, after every 600-tick baseline). Same attack never twice in a row; summon at most once per 3 attacks and only when <SUMMON_MAX_ADDSalive. Weights are tunables.- close: swing 4, slam-double (enraged only) 3, fan 2, barrage 1
- mid: fan 4, spiral 3, barrage 2, missiles 2, swarm 1
- far: lunge 4, missiles 3, swarm 3, summon 1
- Aimed fan (new attack
ATTACK_FAN). 3 volleys of 7 bolts in a 50° cone aimed at the pilot’s predicted position (pos + vel * t_flight, clamped lead), 0.18 s apart; enraged: 5 volleys. Telegraph shows the cone (warden_lane). - Barrage closes its gaps. Two rings, the second offset by half a step and fired 0.12 s later.
- Lunge (new attack
ATTACK_LUNGE). Telegraphed charge along a lane aimed at the predicted position; contact damage on the path; ends with a short radial burst. Replaces the “dash only at the start of an approach”. - Moves while attacking. During telegraph of ranged attacks it strafes (orbit at 0.6× speed, direction flips each attack); during rest it repositions to its preferred band for the next pick. Base Survival speed 88 → 120 (tunable).
- Phase 2 (enraged). Barrage telegraph shortens by the cadence multiplier too; swing becomes a double swing (second ring 0.45 s later, catches a dash back in); missiles fire WITH a spiral (paired attack); drone swarm count already rises.
- No missile soak. Survival missiles home on the pilot only; drones no longer absorb them (decoy aggro rules untouched).
Fairness guard: every attack has a visible telegraph ≥ 0.45 s (enraged) and every aimed pattern leaves a dodge path (fan cone ≤ 50°, double-swing gap 0.45 s).
D. Telemetry
Section titled “D. Telemetry”- Tag each Warden hit with its attack (
"boss:swing","boss:fan", …) and accumulate a per-bossdmgmap +hitscount into the run timeline’s boss entry ([type, spawn_t, kill_t, {attack: dmg}]).death_causekeeps"boss"for compatibility. Same data class as existing run summaries — confirm the privacy page wording still covers it; no new table.
E. Docs / housekeeping
Section titled “E. Docs / housekeeping”data/bestiary.jsonWarden stats are stale (hp 1500/speed 40) — sync to the live values + new attacks.tools/vfx_library/library_manifest.gd: new entries (with scores) for each new look; Warden body.docs/architecture/enemies-bosses-survival.md: the new attack deck + phase 2.- RELEASE-1.0.1 entry.
Testing
Section titled “Testing”- Sim (GUT, TDD): deck picks by band, no-repeat, summon cap, fan aim leads a moving pilot, barrage double ring, lunge path damage, strafe during telegraph, enraged double swing + paired attack, survival missiles ignore drones, tutorial Warden unchanged (attack order + counts pinned), telemetry dmg map.
- Render: shader compile under mobile + gl_compatibility (windowed), prewarm family covered,
test_baked_shader_materials, VFX library manifest, a capture of the new body + each attack for Chris to eyeball, A/B toggle verified. scripts/gate.shgreen; determinism baselines unchanged.