Skip to content

Repository files navigation

Super PAC Out!

A satirical political 2D fighting game for Godot 4.3+ (developed against 4.6.3). Classic 6-button Street Fighter rules, data-driven roster of 22, eight dynamic stages, and GGPO-style rollback — not delay-based netcode.

Primary targets: macOS, iOS, iPadOS. Keyboard, Xbox, DualShock 4 / DualSense, and touch.

How to run

  1. Install Godot 4.3+ (4.4 / 4.6 are fine).
  2. Import SuperPACOut/ as a project, or from a terminal:
godot --path SuperPACOut

Headless test runners (these call the shipped sim, not a reimplementation):

godot --headless --path SuperPACOut --script res://tests/run_combat_tests.gd
godot --headless --path SuperPACOut --script res://tests/run_rollback_tests.gd
godot --headless --path SuperPACOut --script res://tests/run_match_harness.gd

Controls (defaults)

P1 P2 Xbox PlayStation
Move WASD Arrows D-pad / LS D-pad / LS
LP MP HP U I O Numpad 4 5 6 X Y RB Square Triangle R1
LK MK HK J K L Numpad 1 2 3 A B RT Cross Circle R2
4-button L M H S U I O P 4 5 6 0 X Y RB LB Square Triangle R1 L1

Remap everything in Settings. Mobile uses the on-screen 4-button pad (L/M/H + Special).

Architecture

Combat is a pure function of (state, p1_input, p2_input) -> state inside scripts/combat/match_sim.gd. Godot’s variable physics is not used for hit detection.

Presentation (sprites, HUD, audio)     ← read only
        ▲
   MatchScene._process  (renders last tick)
        ▲
   RollbackManager.simulate_step()
        ▲
   MatchSim.tick()     60 Hz, integers only
  • Simulation lives in MatchSim (RefCounted). State is one dictionary, saved every frame.
  • Rollback (scripts/netcode/rollback_manager.gd) predicts remote input by carrying the last confirmed bits. A late / mismatched packet loads the pre-tick snapshot and resimulates forward. Checksums detect desyncs.
  • Input delay defaults to 2 frames. local_side_delay is always 0 — the local player does not eat an extra delay on top of the configured delay.
  • Local versus and fake-online both call the same simulate_step()MatchSim.tick().
  • Transport is a P2P stub (TransportStub) with an optional relay flag. Ranked / unranked / lobby are stubs.

Units are centipixels (1/100 px). No floats in the tick.

Folder map

res://
├── assets/{characters,stages,vfx,ui,audio}   # placeholders + drop-in art
├── data/{characters,stages}                  # JSON movesets / stages
├── scenes/{characters,stages,ui,main}
├── scripts/{combat,netcode,characters,stages,input,systems}
├── autoload/                                 # Game, Roster
└── tests/                                    # shipped-API runners

How to add a character

  1. Copy data/characters/barack_obama.json to data/characters/<id>.json.
  2. Set id, display_name, short_name, side, archetype, color, initials.
  3. Tune stats. Keep the normal keys (5LPjHK). Add 2–3 specials (motion + button + frame data) and one super with meter_cost: 10000.
  4. Add throw, win_pose, and at least one win_quotes entry.
  5. Append the id to data/roster.json and to CharacterDB.required_named_ids() if you want the roster test to cover it.
  6. Drop placeholders at assets/characters/<id>/idle_000.png (and portrait.png).

Motions the detector understands: qcf, qcb, dp, hcf, hcb, charge_b, charge_d. Buttons: P, K, LP/MP/HP/LK/MK/HK, PP, KK.

No GDScript changes are required for a data-only fighter.

How to replace placeholders with Grok Imagine art

Art is never hardcoded. Presentation looks up:

assets/characters/<id>/<anim>_000.png
assets/characters/<id>/portrait.png
assets/characters/<id>/win_screen.png
assets/stages/<id>/<layer>.png
assets/vfx/<name>_000.png
assets/ui/<name>.png

If the file is missing, you get a colored rectangle + initials. If it exists, it is used.

  1. Open ASSET_GENERATION_MANIFEST.md.
  2. Copy the prompt under the path you want (every prompt starts with the style lock).
  3. Generate in Grok Imagine. Save over that exact path (add _001, _002… for extra frames).
  4. Reload the project. Zero code changes.

Stages

Every stage JSON lists at least one match-state-driven dynamic:

id name dynamic
white_house White House Rose Garden destructible bushes + Secret Service at low health
capitol_steps US Capitol Steps crowd meter feeds super + round-3 debris
x_hq X (Twitter) HQ live ticker from who is winning
wall_street Wall Street / NYSE market-crash hazard at low health
southern_border Southern Border Crossing wall hazard on super
silicon_valley Silicon Valley Tech Campus weather/heat from round number
debate_stage Presidential Debate Stage audience meter feeds super; podiums as platforms
mar_a_lago Mar-a-Lago chandelier on super + destructible gold

Exports

export_presets.cfg ships macOS, iOS, and iPadOS (iOS platform, targeted_device_family=2) presets. Fill in your team id / provisioning before shipping.

License / satire

Fighters are satirical cartoon archetypes, not likeness-licensed portraits. Placeholder art is geometric on purpose. Final sprites should stay caricature, not photo-real.

About

Super PAC Out! — a satirical 2D political street fighter for Godot 4.3+ with GGPO-style rollback.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages