Loading…
a327ex.com

SNKRX Snake

Opus 4.8

Summary

First real re-implementation session of the (secret) SNKRX update on the Anchor 2 snkrx-template: forked the codebase, ported SNKRX's exact snake movement + follow, gave units HP + SNKRX hit/death sounds, then iterated heavily on the death-feedback "juice" (a keep-moving re-organization slide + slow-mo + a camera zoom/rotation punch centered on the dead unit, all live-tunable on an F1 panel). Continues NDA Project 1 (the verified flat-integer stat port); combat-first, meta-loops later.

Alignment / decisions (locked at session start):

  • Codebase home = copy Mini Looper into SNKRX-update/ (it's already snkrx-template + working combat) and strip the looper progressively, keeping only the SNKRX template, the snake, units, and general combat. Looper re-addable later from mini-looper/.
  • Slice 1 scope (user trim): just get it running — steer the snake, units auto-attack, things die. No verified HP curve / no Part-8 numbers yet (deferred).
  • Snake control: WASD/arrows by default + mouse on a toggle (the original has both). Contact model = SNKRX (each unit has HP, takes contact damage, dies), not Mini-Looper's ram. Nomenclature train → snake / snake_unit across the live files.

Foundation (the copy + a .git incident):

  • Copied all of mini-looper/* (except .git) into SNKRX-update/. First attempt's ls -A | grep -v '^\.git$' FAILED because ls emitted .git/ (trailing slash from a classify alias), so cp -r .git clobbered SNKRX-update's repo (remote flipped to mini-looper). Recovered by rm -rf .git + re-cloning [email protected]:a327ex/SNKRX-update.git to /tmp and moving its .git back. Net: working tree = full game code under the SNKRX-update repo, proposal intact, game files untracked.
  • Deleted the looper meta files: loop.lua, building.lua, building_ui.lua, grid.lua, wave.lua, hand.lua, builds.lua. train.luasnake.lua. Kept info_text.lua + the whole snkrx/ toolkit. Mini-Looper-specific units (block/juggernaut/detonator/earthshaker/geomancer) left dormant in units.lua un-pruned (per user); earthshaker still references the deleted loop.lua but is never spawned → handled later.

Snake movement — copied directly from SNKRX player.lua (after a wrong first guess):

  • First pass guessed mouse-follow / 8-direction WASD; user corrected: copy SNKRX exactly. Extracted from player.lua: turn = a FIXED 1.66*math.pi rad/s angular rate; keyboard = A/left rotates r -= rate*dt, D/right r += rate*dt; mouse = rotate toward cursor at the same capped rate via sign(sin(angle_to_mouse - r)), never snapping. Tab toggles snake_control_mode.
  • Follow = SNKRX's previous_positions: the head appends {x,y,r} to one shared buffer every frame (cap 256); each follower walks it from the head to distance 10.4*(index-1) and SNAPS to that discrete point, taking its r. Spacing 10.4, unit size 9×9 (set_as_rectangle(9,9)) — both SNKRX's literals (was 12 / 10×10).
  • Start-teleport fixed by seeding the buffer with a straight line behind the head at spawn (slightly better than SNKRX, which unspools).
  • Death re-link mirrors recalculate_followers: on death, prune + reindex; if the head died the next unit becomes head + buffer reset. snake_max_speed kept 120 (SNKRX base ~75, flagged).

Units get HP + killable; enemies retargeted:

  • snake_unit gained hp/max_hp + :hit/:die; main.lua's snakeenemy collision now damages the UNIT (+ shoves the enemy off via snake_push_force); enemies die only to auto-attacks. enemy.lua steering retargeted from the loop center to the snake head (snake_units[1]), with an empty-snake guard.
  • Starter snake = {archer, swordsman, outlaw, magician, cannoneer} (the loop/ram-independent SNKRX-clean attackers).

On-hit feedback + HP bars (copied from SNKRX):

  • SNKRX Player:hit does camera:shake(4,0.5) on every hit; added shake_shake(main_camera.shake, 4, 0.5) (later gated to NON-lethal hits, so a death has no positional shake).
  • HP bars matched to SNKRX's HPBar (objects.lua): 2px, at y - h, green for player units / red for enemies / white while flashing, scaled by the hit spring. draw_health_ui (snkrx/seeker.lua) updated; snake_unit.hp_bar_color = green, enemies default red.

Sound porting (researched SNKRX source → sourced from E:/sound packs):

  • Unit hit = random of player_hit1/player_hit2 = Body Fall 2.ogg / Body Fall 18.ogg (Fighting Sounds Pro). Unit death = hit4 = Kick 16_2.ogg = the Kick 16 from Ultimate Retro Sounds (the _1/_2 are two different "Kick 16" files from different packs, confirmed by duration-matching SNKRX's shipped oggs against pack originals: 0.493 / 0.541 / 1.543s).
  • 2020 vs HD-Remaster editions are decoded-md5 identical → used 2020. Converted Body Fall 18.ogg + Retro Kick 16.ogg at libvorbis -q:a 10 into assets/; reused the toolkit's existing Body Fall 2. sfx() auto-jitters pitch ±5% (matches SNKRX's 0.95-1.05); death sound played at pitch 1 when length needs to be exact (later moot).

Death-feedback iteration (the bulk of the session — many reversals):

  • v1: staggered re-organization cascade — on death the survivors slide into their new slots one at a time. Added a full time-stop (set_time_scale 0) + a phased camera zoom-in → cascade → zoom-out centered on the death spot, with an F1 panel (teleport/tween toggle, STEP slider, EASE dropdown of all 44 easings, ZOOM/ROT/ZDUR sliders). Added a toolkit slow(amount,duration) (ported from SNKRX shared.lua) — a partial slow-mo distinct from the full-freeze hit_stop.
  • "Keep particles + shake playing during the freeze" → introduced fx_dt (juice on unscaled dt while the sim froze).
  • User then: remove the time-stop, run it live (snake keeps moving), lower delay (STEP 0.1), zoom becomes a trauma shake (zoom+rotation), bring back the slow on top. Reworked to a per-unit settle model: each survivor behind the gap gets settle_off += 1 (eased to 0, staggered) so it slides forward ALONG the trail while the head keeps steering — no freeze, no suspend, trail-accurate. slow() + shake_trauma(...,1.0,0.5) on death.
  • Trauma made zoom + rotation only (custom amplitude {x=0,y=0,rotation=0.2,zoom=0.2}); the per-hit positional shake_shake gated to non-lethal so a death is pure zoom/rotation.
  • Added a death-zoom centering on the dead unit: pan-compensation cam.x = dx - (dx-center)/zoom keeps the death spot pinned while the scene zooms around it (camera_get_effects confirmed pure).
  • Briefly added a cute tween sound (message-display3__cute.ogg, tween duration = sound length + 0.05) — then reverted ("Nevermind, change back").
  • Final death model (this session's end state): trauma removed; a deliberate zoom + rotation punch instead — an envelope ramps 0→1 (EASE IN over DUR IN) then 1→0 (EASE OUT over DUR OUT), driving camera.zoom (1→ZOOM→1) and camera.rotation (0→±ROT→0), centered on the dead unit, on slowed sdt. Two ease dropdowns (E.IN / E.OUT) + ZOOM / ROT / DUR IN / DUR OUT sliders; EASE moved from the slide (now fixed cubic_in_out) to the death cam.
  • Debug keys: K = kill the head outright (full death feedback), P = respawn a fresh snake (keep enemies), R = full restart.

Final F1 defaults (locked at session end): ZOOM 1.33 · DUR IN 0.02 · E.IN linear · E.OUT cubic_in · ROT 0.05 · DUR OUT 0.2 · SLOW 0.20 · STEP 0.07.

State / next: SNKRX-update/ boots an arena: free-steered snake (WASD/arrows + mouse toggle), enemies seeking it, the 5 starter units auto-attacking + dying, SNKRX-faithful hit/death sounds + HP bars, and the live death-feedback (slide + slow + zoom/rotation punch) on an F1 tuning panel. Deferred: re-add the looper as a mode; port the real SNKRX roster (prune the dormant Mini-Looper units + drop loop.lua + handle earthshaker); wire the Part-8 stat numbers; walls + the SNKRX wall-bounce; rotation-pivot centering on the death spot.

🔒 Only the summary of this log is public. Private because this is SNKRX update.