Live preview (JavaScript)
The loop is played live in your browser from the validated loop table (the same data the reference render was made from); the badge on the player is its self-test (seam + motion probes). A pre-rendered GIF fallback is embedded for no-JS viewers.
Heavy Laser Hovertank β from the unit’s FBI.
COB-exact: timeline 1:1 from speeder.cob (aim/fire (COB VM), disassembled with _cob_dis.py). Aim/fire family: AimPrimary to the target angle, then 4 shots on the weapon's reload grid (CORE_BATSLASER, 1100 ms), then the close AimPrimary(0, 0) that stands in for the engine-driven RestoreAfterDelay. Engine hooks are kept out of the loop and documented below.
COB timeline (SPEEDER.COB)
- 0.00β0.40 s β Rest pose (3DO zero point)
- 0.40β0.67 s β AimPrimary(8192, 3641): +45Β° yaw / +20Β° pitch at the COB aim speeds (concurrent)
- 0.96β5.37 s β 4 shots at the CORE_BATSLASER reloadtime (1100 ms) β barrels/flares per the compiled script (flashes only)
- 8.63β8.63 s β AimPrimary(0, 0): back to the rest aim (the aim calls the engine sends next; RestoreAfterDelay pacing is engine-driven)
- 8.63β9.23 s β rest again β loop restarts seam-clean (frame N = frame 0, pixel-verified)
Every stage duration equals its COB sleep exactly; values are raw COB units (turns: BAM 65536 = 360Β°, moves: elmo Γ 163840). Renderer conversions follow the proven family conventions (_cob_anim.py).
Engine-side hooks & source notes
- RockUnit / HitByWeapon β engine callbacks (hook registry byte-tactics-verified in the TotalA.exe decompilation: both take 2 args from weapon code). Each script rocks the chassis (base x/z) with engine-supplied values; the preview deliberately leaves both out.
- SetMaxReloadTime(a) β the script stores
a*2as the restore delay; source-verified: the engine passes a = the longest weapon reload in ms (InitUnitWeaponSlots). Create seeds a literal 3000 ms first. The loop closes with AimPrimary(0, 0) instead of the engine-paced restore. - AimFromPrimary / QueryPrimary β out-parameter pieces (
store-arg 0): aim pivot = turret (piece 2), muzzle anchor = flare (piece 1); confirmed against QueryWeaponPiece in the decompilation. - flare + wake1..wake10 carry 0 primitives β pure engine-effect anchors (prims counted in the source 3DO): the CORE_BATSLASER beam and the water-wake spray are engine-drawn. FirePrimary toggles the beam anchor for 150 ms, so the preview shows no flash β faithful, not a defect.
- StartMoving emits wake spray SFX on the anchor pieces in a 300 ms loop (emit-sfx, opcode 0x1000f000) β engine effect, outside the loop. SmokeUnit is the engine smoke loop, omitted by convention.