Skip to content

Six models rebuild one weapon: the Pulse VFX shootout

Six models rebuild one weapon: the Pulse VFX shootout

Section titled “Six models rebuild one weapon: the Pulse VFX shootout”

Date: 2026-10-01 · Weapon: pulse (chain lightning, rated 3/5 in the VFX library) Status: three finalists shortlisted blind; final pick pending on-device play (BUILD 231).

Eleven weapons sit at 3/5 or below in tools/vfx_library/library_manifest.gd. Rather than rewrite them one at a time in the usual way, this was an experiment: hand the same brief to six different frontier models, let each rebuild one weapon’s look independently, and judge the results blind. Pulse went first because it is the clearest case of a weapon whose mechanic (a chain that hops between enemies) is far more interesting than its visual (a plain bolt).

Each model was given explicit artistic licence to reinterpret the effect, including proposing gameplay changes — but proposals had to be made in writing, never by editing /sim.

  • One shared contract. Every model got tools/weapon_vfx/CANDIDATE_BRIEF.md: the same reading list, the same non-negotiables (one blend_add quad per event, half-float-safe INSTANCE_CUSTOM, accent-slot indirection for colour, read power/rungs/evolved from day one, HDR above 1.0, keep the interior readable rather than a white blob).
  • Discovery by convention, not registration. The harness finds any fx/weapons/candidates/<weapon>/<slug>/look.gd. Nothing is shared and nothing is registered centrally, so six parallel branches merged with zero conflicts.
  • Isolated worktrees. Each model ran as droid exec -m <model> -w <branch> off one base commit, with no visibility of the others.
  • Blind judging. Letters A–F were assigned randomly in Python; the key was withheld until after the pick. Boards were rendered at p0 and evolved, four columns each (0.02 / 0.06 / 0.12 / 0.26 s after the shot).

Four frontier models plus two deliberately cheap wildcards, to test whether price tracks quality.

Letter Model Tier Shortlisted
F claude-opus-5-5 frontier ✅
C gpt-6.1-sol frontier ✅
E glm-5.3 cheap wildcard ✅
A grok-4.7 frontier —
B qwen3.8-max cheap wildcard —
D gemini-3.1-pro-preview frontier —

Headline result: one of the two cheap wildcards made the top three, and one frontier model (D) produced the weakest entry by a clear margin. Price did not predict quality here.

All six respected the mechanical rules (one additive quad per bolt event, accent-slot indirection, reading the investment stamps). They diverged sharply on concept.

F · opus55 — a real lightning strike per link: a kinked channel pinned to both struck points, forks re-rolled on each return stroke, a hot strike node, and ionised residue that outlives the flash. Evolved braids the channel into a plasma rope with coil discharges. The only entry that follows the half-float rule literally (roundf with MAX_LEN = 2000.0). Largest pool (CAP := 40) and the heaviest additive overdraw; it names its own Apple TV whiteout risk.

C · gpt61sol — a fine branching gold discharge with a brief white-hot spine and deliberately hollow contact crowns, so the enemy’s own marker stays visible under the hit. Evolved interweaves two Tesla field lines. Built on nearest-segment distance fields with closed-form “ion beads” rather than particle nodes. The most explicitly anti-whiteout entry (hot wire clamped to 1.15, subdued residue) and the only one that shipped its own verification harness (verify.gd, including a half-float round-trip test) plus a gallery scene.

E · glm53 — “Storm Conduit”: a pale-blue stepped leader sweeps out, then the return stroke blasts the whole channel white-hot with forward-peeling forks, settling into a gold afterglow. Evolved adds two writhing sibling filaments. Notable for engineering against its own failure modes: term clamps to stop a fat white bar, an endpoint taper to stop envelope overshoot, and a lateral window cut because “sRGB gamma lifts exp tails into a visible quad footprint”. It still self-reports a 4.3% whiteout cell at evolved joints.

A · grok47 — a channel struck entirely within one frame that collapses to a thin ionised afterimage, so a multi-link chain reads as a single event. Pixel-space segment distances keep stroke width constant regardless of link length. Rejects volumetric approaches outright: “a bolt is a line, not a volume”. Honest about its weakness — at p0 it is still close to the legacy bolt.

B · qwen38max — “Arc Weave”: a leader bead races to the target, the fractal channel ignites in a one-frame return stroke, then re-strikes on fresh paths at ~18 Hz while cooling. Three octaves of hash polylines, explicitly not fbm (“smooth noise reads as fire, not electricity”). Authored without a vision model: it shipped _inspect.gd, a pixel-statistics probe, and iterated from numbers instead of looking. That is a notable result on its own.

D · gemini31pro — a noise-displaced line animated on TIME rather than on the effect’s own life. The weakest entry, and the only one with concrete brief violations: the half-float rule is neither followed nor mentioned, its own writeup claims “fbm-displaced” while the shader uses two vnoise octaves, and crucially the bolt has no endpoint pinning and no contact flash, so it visibly stops short of the enemy it just hit.

  • Two families emerged, plus an outlier. F, E and B all converged independently on the same narrative: leader → return stroke → re-strike flicker → ionised afterglow, with an evolved braided rope. A and C form a restrained second family: struck in one frame, collapsing to an afterimage, explicitly no travel delay. D is the outlier on every axis.
  • Three of six independently proposed the same sim change. F, E and B each arrived, in writing and without collaborating, at “stamp a link index or strike id on the bolt event so the chain can visibly travel”. Each one checked and noted that fx_events are excluded from the determinism checksum. Convergent design pressure from three directions is a strong signal that the event is genuinely missing information.
  • Self-knowledge varied more than skill. The strongest entries documented their own weaknesses precisely (whiteout cells, colour drift in decay, motif anisotropy on a thin quad). The weakest one made claims its own code did not support. When judging model output at scale, the accuracy of a candidate’s self-assessment turned out to be a better quality signal than the confidence of its prose.
  • Brightness is the real risk. F and B are the whiteout leaders by their own measurements (B self-measures its evolved flash at ~6× the base cell). This matters because BASE_DIM was already cut to 0.75 to stop additive looks washing out the screen.

Harness lessons (these cost more time than the looks did)

Section titled “Harness lessons (these cost more time than the looks did)”
  • Never budget a capture in rendered frames. The sim ticks at a fixed 60 Hz while a windowed capture renders uncapped (~460 fps measured), so every frame budget was roughly 8× shorter than it read. It silently baked whole weapons as “never fired” and turned 24-frame sequences into ~7 ticks of near-duplicate stills. Everything now budgets in sim.run_time.
  • Poll sim.render_fx_events, never sim.fx_events. The latter is cleared at the top of every tick, so sampling it once per rendered frame misses any weapon that fires between samples.
  • Register a look after _on_mode_chosen. Starting a run rebuilds fx_layer, so a look registered earlier is discarded — while the harness still reports it as registered and quietly captures the legacy effect.
  • Serialize windowed Godot runs (scripts/dev/godot-window-lock.sh). Backgrounded windowed Godot hits App Nap and saves black PNGs.

The three finalists are wired into the game behind a live switch rather than judged from stills: Debug Settings → Pulse Look cycles v1 → opus55 → gpt61sol → glm53 mid-run (DevFlags.pulse_look, FxManager.set_candidate_look). Shipped to the Apple TV dev app as BUILD 231 for the final pick.

Once a winner is chosen it gets promoted (copied) into fx/weapons/ and FxManager.V2_LOOKS, removed from PENDING_V2_LOOKS, and its manifest rating re-scored. Every candidate folder stays in the tree (Chris, 2026-10-01, superseding the earlier plan to delete the losers): the candidates are a permanent archive, so each new model’s take can be compared in-game against all of them. Since that change the Pulse Look row offers all six archived looks, not just the three finalists. Convention: fx/weapons/candidates/README.md.