Runnable Rust/Bevy prototype for an original low-poly 3D arcade arena brawler. It combines custom Bevy geometry with a curated set of CC0 Kenney assets from arts/, without a third-party physics crate.
cargo runThe window opens at 1280x720.
One-time setup:
rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli --version 0.2.121
brew install binaryenbinaryen supplies wasm-opt. On non-macOS systems, install Binaryen with the
platform package manager before building.
Build the static web folder:
./scripts/build_web.shCreate the itch.io upload archive:
./scripts/package_itch.shThe package is written to
target/itch/animal-fighter-club-web.zip. The script verifies that
index.html is at the ZIP root, pkg/ and assets/ are sibling directories,
and the archive stays within itch.io's HTML5 file-count and size limits.
Serve locally:
python3 -m http.server 8000 --directory web_distOpen http://127.0.0.1:8000, then click or press Enter to start user mode.
For itch.io, create an HTML Game, upload the ZIP, and select Click to launch in fullscreen. The launch click supplies the browser interaction needed before audio playback and controller joining. Test Xbox and standard DualSense discovery, reconnect, replacement, and gameplay input on a draft upload in current Chrome; also test Safari on macOS before publishing.
- Development workflow
- Runtime architecture
- Multiplayer architecture and delivery plan
- Performance budgets and profiling
Setup:
- Enter: start the selected match
- 1: timed team score rules
- 2: free-for-all score rules
- 3: stock ring-out rules
- A: cycle arena selection forward
- Shift+A: cycle arena selection backward
- Demo battle is locked to one player fighter and one bot fighter.
- Z/X: cycle player/bot styles
- T/Y: cycle player/bot equipment
- R: reroll replay seed while staying in setup
Player:
- Arrow keys: move.
- Z: aim toward the bot; tap to grab.
- X: strong attack, throw held item, heavy throw during grab hold.
- C: light attack, pick up item when empty-handed, dash attack while dashing, jump attack while airborne, swing held item.
- V: jump, quick stand while knocked down.
- Double-tap a movement key: dash, recovery roll while knocked down.
- X + C: guard / block.
- While grabbed, X + C plus movement away: escape attempt; X + C: brace against throws.
User Mode Local Multiplayer:
- Single Player opens character select immediately and uses Keyboard 1 unless P1 already has an explicit session assignment.
- On character select, arena select, combat, or results, press an unassigned controller's family-specific Confirm button twice to transfer P1 from Keyboard 1. Back or Esc cancels the confirmation.
- Choose two, three, or four local players from the Multiplayer mode screen.
- Join in P1-P4 order with a controller's family-specific Confirm button or any keyboard layout's Jump/Aim key. Use the controller's Back button to leave.
- If an assigned controller disconnects, reclaim its seat with the original or another unassigned controller before play continues.
- Xbox: Left stick/D-pad move; A jump; X light; Y heavy; B grab/back; LT aim; RT guard; RB dash; LB ultimate.
- DualSense: Left stick/D-pad move; Cross jump/confirm; Square light; Triangle heavy; Circle grab/back; L2 aim; R2 guard; R1 dash; L1 ultimate; Options is the menu/pause control where available.
- Open Settings → Controls. Controller opens registration; Keyboard edits or restores all four layouts; Sound controls audio preferences. Controller order is retained for the current session, while keyboard bindings and audio preferences persist between launches.
- P1: Arrow keys move; Z/X/C/V actions.
- P2: A/D/W/S move; T/Y/U/I actions.
- P3: F/H/R/G move; B/N/M/Comma actions.
- P4: J/L/O/K move; 7/8/9/0 actions.
- Key Settings shows one complete eight-action layout at a time and swaps duplicate assignments safely.
The standard PlayStation 5 DualSense is supported over USB and Bluetooth on
Windows 10/11, Linux, and macOS, and through the standard Gamepad API in current
Chrome on those operating systems and Safari on macOS. DualSense Edge uses the
same normalized controls, but its extra controls are not bound or part of the
hardware acceptance target. Linux requires a current kernel with
hid-playstation and suitable input/force-feedback permissions.
Windows and Linux use Bevy/Gilrs normalized mappings, macOS uses Apple's extended GameController profile, and browsers use standard Gamepad mappings. Vibration is capability-based: the game uses the existing platform haptic route when one is exposed, while unsupported vibration never blocks input, joining, or reconnecting. On macOS, DualSense uses its separate handle actuators when available, while Xbox and other controllers use Apple's whole-controller default haptic route. Touchpad input, motion, adaptive-trigger effects, light-bar control, speaker, microphone, and DualSense Edge extra controls are out of scope.
Native Dev Hotkeys:
- Shift+U: enter user mode from the dev setup screen.
- In user mode, choose player count, one character per player, and an arena before starting the match.
- F2: toggle map editor while in setup.
- H: toggle hitbox, hurtbox, item, impact-source, reaction, technique-window, and feedback-cue debug overlays.
- Shift+Up/Down: pan the gameplay camera forward/back.
- Shift+Left/Right: rotate the gameplay camera.
- Shift+Cmd/Ctrl+Up/Down: raise/lower the gameplay camera.
- Shift+mouse wheel: zoom the gameplay camera.
- Shift+R: reset the gameplay camera.
- Shift+C: cycle gameplay camera filter/action-effect look.
- Shift+Cmd/Ctrl+F: toggle whether the saved single-player camera follows Player 1.
- Shift+Cmd/Ctrl+L: load the saved single-player camera preset into the live dev camera.
- Shift+Cmd/Ctrl+S: save the current gameplay camera angle as the single-player camera preset.
- Dev hotkeys are native-only and are blocked while user mode is active.
Debug:
- H: toggle hitbox, hurtbox, item, impact-source, reaction, technique-window, and feedback-cue debug overlays
- 1: timed team score rules
- 2: free-for-all score rules
- 3: stock ring-out rules
- R: reset/rematch with the current rules
- Enter on results: return to setup with the current selections
Pickups:
- Guard Battery: restores health and stamina.
- Foam Mallet: carried melee prop with four durability uses. Swing it or throw it.
- Pop Bomb: carried explosive. Throw it or drop it to arm a short fuse.
- Spark Lobber: ranged carried prop with a long light poke.
- Breeze Buoy: utility prop that consumes itself for stamina.
- Stone Crate: heavy prop with stronger close swings and throws.
- Guard Kite: shield-like prop with a short bash and high durability.
Styles:
- Anchor: slower, sturdier guard economy, stronger ring-control throws, a longer-invulnerable brace step, and stamina-paid heavy startup armor with longer whiff recovery.
- Vector: faster pressure movement and attacks, weaker guard economy, a shorter dash-attack flow, and a narrow dash-attack-to-light branch window.
- Catalyst: balanced movement and defense with the roster's longest mid-range preference.
- Style identity is visible through compact HUD taglines and small in-match accent rings.
Equipment:
- Dash Coil: boosts dash attack knockback on cooldown.
- Aerial Spur: boosts jump attack damage on cooldown.
- Counter Cell: boosts perfect-guard counter damage on cooldown.
- Heavy Seal: boosts heavy attack knockback on cooldown.
- Equipment identity is shown through HUD effect text and a small fixed back-chip accent.
Guard Batteries are collected automatically by walking into them. Carried items must be picked up with grab.
- The demo starts as one controlled fighter versus one bot. Crown Ring keeps its original authored layout, while nine additional arenas use split terraces, layered stone steps, crossways, spirals, lanes, market wings, garden petals, snow steps, and cannon-court footprints.
- Arena definitions provide ground shapes, visual themes, spawn points, item anchors, ring-out bounds, camera hints, platform blocks, and phased hazard data. All ten arenas can be selected in user mode or cycled in native dev setup.
- The camera follows the center of living fighters from a high angled arcade view, while single-player user mode follows the controlled fighter with the saved single-player camera preset.
- Movement uses simple acceleration, friction, gravity, jump, dash stamina cost, radius-aware platform support, ledge jump grace, side pushout, limited wall bounce, and manual ground checks.
- Combat uses Rust-side technique definitions for startup, active, recovery, cancel/branch windows, stamina hooks, and impact payloads across the light chain, dash attack, jump attack, heavy attacks, guard counter, item actions, and stateful grab/throw.
- Heavy hits, combo finishers, throws, thrown items, and Pop Bombs can launch fighters into reaction profiles, limited ground/wall bounce, knockdown, and get-up states.
- Knocked-down fighters wake automatically after a short pause and gain brief invulnerability while standing.
- Guard reduces front-facing damage and knockback, but stamina pressure can cause guard break. A precisely timed guard prevents chip damage and starts a quick counter.
- Guard plus dash performs a short defensive step, and knocked-down fighters can quick stand or recovery roll instead of waiting for automatic get-up.
- Primitive hit sparks, guard flashes, dash trails, dust puffs, respawn beams, and item effects make combat state easier to read without external assets.
- Simple arena items add arcade match chaos: stamina recovery, a carried melee prop, and a carried short-fuse bomb.
- Arena hazards now include launch pulses, slowing snare fields, and bumper nodes with per-hazard phase offsets that apply neutral shared-impact pressure without awarding ring-out credit.
- HUD rows tint and show EDGE danger when fighters drift near arena ring-out bounds or fall toward the lower blast plane.
- Fighters use shared action rules with style tuning for movement, stamina economy, guard pressure, attack timing, throw pressure, and bot range preference. User mode supports one player against a bot or up to four local keyboard players.
- Equipped modifiers each affect one move, show effect text/cooldown status in the fighter HUD row, flash on trigger, route a feedback cue, and add a small visual accent.
- Move, item, style, and equipment tuning now live in internal Rust-side definition structs for faster iteration.
- Match flow now runs through countdown, fighting, time-up, results, reset/rematch, and return-to-setup phases.
- Rule presets cover timed team score, timed free-for-all score, and stock ring-out matches.
- Team-score rules now use centralized even-vs-odd team membership and explicit friendly-fire policy to block self/teammate strikes, grabs, item hits, and bombs from awarding damage or ring-out credit.
- A lightweight local setup shell selects, previews, and applies the mode, arena, active fighter slots, fighter styles, equipment, and replay seed before countdown.
- Local match telemetry tracks ring-outs, uncredited falls, item hits, throw hits, guard breaks, and total damage for result/debug displays.
- Ring-outs happen when a fighter falls below the arena or gets pushed too far out. The last attacker gets a score point; stock rules also remove lives and can end the match.
- Bots pick the nearest opponent, move toward them, strafe, attack in range, and sometimes dash.
- Bots can chain light attacks, sometimes grab at close range, occasionally use dash or jump attacks, and make role-aware item choices: ranged pokes at distance, explosives near mid-range, utility when stamina is missing, heavy props for ring pressure, and defensive props for guarding.
- Bots now quick-stand or recovery-roll from knockdown, guard against readable incoming attacks, avoid active arena hazards/thrown items/armed bombs, and use style/equipment-aware personality weights with small deterministic mistakes.
- The HUD now shows phase/rule state, results, held item status, equipment cooldowns, debug overlays, timer, scores, health, and stamina.
Use the development workflow and performance protocol when extending or optimizing the game.
- Continue platform collision tuning for walls, ramps, and ledges.
- Continue tuning balance, readability, and setup polish from live playtests.
- Continue tuning moving arena devices, map-authored overlay dressing, and footprint-aware bot navigation.
- Expand style and equipment identity so archetypes and modifiers change more than raw tuning.