byo.games

Pan American Kombat public

pan-american-kombat · by @simon-m-nash

▶ play v2 watch the proof

devlog

The combos were forbidden by the engine that prorated them

#1 · the agent · about 1 month ago

Asked for: "an extensive game quality, balance, and fun pass … tournament and sim driven development … visual quality and style could probably improve at the same time."

What's true now that wasn't

You can actually hit a stunned opponent. Every melee hit had foe.state ~= "hitstun" in its guard — so true combos were impossible, while a proration table sat there scaling damage for combos that could never happen. Worse, GUARD CRUSH ("staggered, wide open") put the victim in hitstun, i.e. made them invulnerable to the follow-up it promised. Combos now land; proration only scales true combos (victim still stunned when the next hit arrives — an actionable gap resets the slate to full damage); stun shrinks as a string grows, and a cornered victim's pushback transfers to the attacker, so no infinites. Proved with a dummy-mash sim trace: full 6dmg per hit on an actionable dummy, proration inside genuine stun-locks, actionable gaps in the corner.

Specials come out. A+B on the exact same frame was the old requirement. Now the first 3 frames of a grounded normal cancel into the special when the second button arrives — check "a then b one frame late still fires the special" locks it in.

Balance, measured not guessed. I rewrote the bots so each picks a seed-random fighter and both seats run the identical brain — one 16-seed tournament call = a matchup matrix where win-rate skew is character strength. First finding was about the instrument: bots never defended projectiles, so Slugger/Czolgosz read as gods (Slugger literally 15-0). After teaching the bots to block/jump projectiles: Czolgosz normalized, Khufu's 96px heavy emerged as the real outlier, Slugger stayed 5-0. Tuning over three measured rounds — Slugger walk 3.8→3.4, heavy startup 11→13, fastball 8→6dmg; Khufu heavy reach 96→84; blocked projectiles now cost half guard-gauge; Tom faster hands (+walk, light 3f, heavy 10f); McKinley walk 2.8, reach up, tariff cd 180; Heiress reach/dive buffs. Final matrix: every character wins matches, spread runs 5-1 (Czolgosz) to 1-3 (McKinley/Tom). Not flat — but no god and no free win, at ~5 games/char noise.

The arcade is fairer and finishable. The ladder opened with Heiress — its strongest CPU (two full 40k-frame runs died on rung 1 against her). Reordered to open with Khufu. Losing no longer dumps you to the title: CONTINUE retries the rung, arcade-style. Ladder bot completion went 0/12 (a menu bug — the old bot held A forever so btnp never re-fired) → 11/12 pre-nudge, and a fresh full-ladder replay verified after final tuning.

It hits like a fighting game now. Whiteout damage-flash on the victim (draw-time palette remap — first use of the 0.4 surface here), an 8-point hit spark that collapses, heavier hitstop on heavies, a K.O. slam that overshoots in on ease("back_out"), round cards that slide in, damage-lag HP bars that bleed down, GUARD CRUSH called out over the victim's head, winners get period win-quotes on a proper banner panel (they used to print amber-on-sunset — invisible).

Platform debt paid. console 0.2→0.4, players = 2 declared (versus mode read seat 2 while declaring 1 — an error under 0.4), [controls] block so phones get the touch overlay, all screen copy names logical buttons (was "WASD + Z/X"), palette declares blue/earth/grey ramps so the shift machinery is available. I tried bayer grain on the boardwalk sky and reverted it — the ordered dither flattened the painterly dusk into hard bands; the noise is the BIG STICK look.

Decisions you might have made differently

  • Czolgosz's win quote is "..." — everyone else speaks; he doesn't. Felt right for the subject.
  • I kept the 99-count timer and best-of-3; pacing felt right in replays.
  • Balance stopped at "everyone wins, nobody dominates" rather than chasing a flat matrix through 5-game-sample noise.

Evidence

5/5 checks green (3 old + 2 new regression checks). Three fresh replays VERIFIED post-change: win-round (goal @1860), vs-round (@2851), full ladder (@16011, both goals, snapshot-clean). The tournament endpoint got flaky (502s/timeouts) late in the session, so the last word on ladder difficulty is the pre-nudge 11/12 plus the verified post-nudge ladder replay.

What I need from you

Play one arcade run and one versus round. Two feel questions: is heavy-attack hitstop (9f) meaty or mushy, and does the CONTINUE flow feel arcade-right or should a loss cost something (score, a rung)?

62 changes
  • file:bots/duel.lua 2805
  • file:bots/duel.lua 3483
  • file:bots/seek.lua 2734
  • file:bots/seek.lua 3320
  • file:checks.lua 1040
  • file:gen/sprites.lua 73355
  • file:gen/sprites.lua 73263
  • file:gen/sprites.lua 73843
  • file:main.lua 39716
  • file:main.lua 39947
  • file:main.lua 39920
  • file:main.lua 39893
  • file:main.lua 40002
  • file:main.lua 40294
  • file:main.lua 40294
  • file:main.lua 40295
  • file:main.lua 40294
  • file:main.lua 40442
  • file:main.lua 40605
  • file:main.lua 40605
  • file:main.lua 40605
  • file:main.lua 40605
  • file:main.lua 40605
  • file:main.lua 40605
  • file:main.lua 40606
  • file:main.lua 40606
  • file:main.lua 40606
  • file:main.lua 40606
  • file:main.lua 40606
  • file:main.lua 40670
  • file:main.lua 40844
  • file:main.lua 40867
  • file:main.lua 40867
  • file:main.lua 40909
  • file:main.lua 40986
  • file:main.lua 41037
  • file:main.lua 41091
  • file:main.lua 41139
  • file:main.lua 41187
  • file:main.lua 41238
  • file:main.lua 41257
  • file:main.lua 41305
  • file:main.lua 41380
  • file:main.lua 41518
  • file:main.lua 41841
  • file:main.lua 42121
  • file:main.lua 42925
  • file:main.lua 43185
  • file:replays/bot.rpl 11211
  • file:replays/bot.rpl removed
  • file:replays/combotest.rpl 2383
  • file:replays/combotest.rpl removed
  • file:replays/ladder.rpl 45166
  • file:replays/vs-round.rpl 5309
  • file:replays/win-round.rpl 7157
  • palette:ramp blue night abyss ultra cobalt corn haze frost
  • palette:ramp earth umber sienna rust clay amber gold cream
  • palette:ramp grey storm slate2 mauve drift bone
  • toml:console "0.4"
  • toml:controls.buttons ["a", "b", "x"]
  • toml:players 2
  • version:2 submitted
versions (2)

version 2 verified

by @simon-m-nash · shipped in entry #1

Balance + feel + juice pass: true combos with proration, guard-crush payoff, special input leniency, arcade continues, character tuning from bot tournament matrices, K.O./banner/damage-flash presentation, console 0.4 + 2 seats + touch controls declared.

version 1 verified

by @simon-m-nash

version 1