← back to Baguette Brawl

README.md

81 lines

# 🥖 Baguette Brawl — Duel de Paris

A 2D fighting game where two crusty baguette duelists brawl beneath the Eiffel
Tower. Swing your loaf, guard your crust, charge the meter, and unleash the
**Crust Crusher** super. First to **2 rounds** wins the boulangerie.

Vanilla JavaScript + HTML5 Canvas. **Zero dependencies, zero build step.** Runs
straight from the filesystem.

![genre](https://img.shields.io/badge/genre-fighting-c65f38) ![stack](https://img.shields.io/badge/stack-vanilla%20JS%20%2B%20canvas-e0a458) ![deps](https://img.shields.io/badge/dependencies-0-4b6b7a)

## Play

Open `src/index.html` in any modern browser — that's it.

Or serve it (needed for mobile testing on another device):

```bash
npm start          # → http://localhost:8080
# or:  python3 -m http.server 8080 --directory src
```

## Controls

|                | Pierre · P1            | Gaston · P2            |
| -------------- | ---------------------- | ---------------------- |
| Move / Jump    | `A` `D` / `W`          | `←` `→` / `↑`          |
| Jab · Heavy    | `J` · `K`              | `,` · `.`              |
| Guard · Super  | `L` · `U`              | `/` · `;`              |

Global: **`P`** or `Esc` pause · **`M`** mute · **`R`** rematch on the result screen.

On a touch device, on-screen buttons appear automatically and drive Player 1.

## Modes

- **Solo vs. Chef IA** — three AI difficulties (Apprenti / Boulanger / Maître)
  with real spacing, anti-air, whiff-punishing and super usage.
- **Deux Joueurs** — local two-player on one keyboard.
- **Entraînement (Training)** — a practice room: no timer, no rounds, **infinite
  meter** for free super practice, a live **combo / max-combo** readout, and a
  configurable dummy that never dies (regenerates between strings). Switch dummy
  behavior on the fly with `1` Immobile (stand) · `2` Garde (blocks everything) ·
  `3` CPU (spars back), and `R` to reset positions.

## Fighting system

- **Jab** — fast, low commitment, small damage, builds meter.
- **Heavy** — slow, high damage & knockback, grounded only.
- **Guard** — hold to block; blocking chip-damages you a little and builds a
  sliver of meter. You can only block what you're facing.
- **Crust Crusher (Super)** — costs a full meter, **unblockable**, huge damage
  and launch. The meter fills as you deal and take damage.
- Round ends on K.O. or when the 60-second timer runs out (most HP wins).

## Project layout

```
src/
  index.html    # markup: canvas, menu, pause & result overlays, touch pad
  styles.css    # all styling
  game.js       # engine: input, physics, combat, AI, particles, rendering
README.md
package.json    # `npm start` static server
```

## What changed from the original artifact

This started as a Model Arena artifact and was rebuilt into a real project:

- **Press-edge input** — attacks/jumps fire once per tap instead of auto-repeating while held.
- **Clean round state machine** (`intro → fight → ko → result`) — removed the `dt*0` freeze hack; countdown now beeps and ends on a real "COMBATTEZ !".
- **Super meter + unblockable Crust Crusher** special move.
- **Selectable AI difficulty** with spacing, anti-air, whiff-punish, blocking and super logic.
- **Mobile touch controls**, pause, mute, slow-mo K.O., body-separation so fighters don't overlap, and depth-sorted draw order.
- Split the monolithic HTML into `index.html` / `styles.css` / `game.js`, added git, README, and a static-serve script.

## License

MIT