Update BOT_SETUP.md with full retro mode combo reference, scoring, and strategy tips. Add docs/bot-guide.md as a standalone developer guide covering all challenge types including retro mode. Add docs/sprite-guide.md and sprite-reference.html for custom sprite creation. Update docs.ts API endpoint and Python example bot with retro_mode handling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
300 lines
11 KiB
Markdown
300 lines
11 KiB
Markdown
# Botfights Sprite Sheet Guide
|
|
|
|
## Quick Reference
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Sheet size** | 576 x 768 px |
|
|
| **Frame size** | 96 x 96 px |
|
|
| **Internal grid** | 48 x 48 px (drawn at 2x scale) |
|
|
| **Columns** | 6 (max frames per animation) |
|
|
| **Rows** | 8 (one per animation) |
|
|
| **Format** | PNG, transparent background |
|
|
|
|
Open `sprite-reference.html` in a browser to generate and download a visual reference sheet.
|
|
|
|
---
|
|
|
|
## Sheet Layout
|
|
|
|
```
|
|
F0 F1 F2 F3 F4 F5
|
|
+------+------+------+------+------+------+
|
|
Row 0 | idle | idle | idle | idle | | | 4 frames, loops
|
|
+------+------+------+------+------+------+
|
|
Row 1 | atk | atk | atk | atk | atk | atk | 6 frames, once
|
|
+------+------+------+------+------+------+
|
|
Row 2 | kick | kick | kick | kick | kick | | 5 frames, once
|
|
+------+------+------+------+------+------+
|
|
Row 3 | spcl | spcl | spcl | spcl | spcl | spcl | 6 frames, once
|
|
+------+------+------+------+------+------+
|
|
Row 4 | hit | hit | hit | | | | 3 frames, once
|
|
+------+------+------+------+------+------+
|
|
Row 5 | kbck | kbck | kbck | kbck | kbck | | 5 frames, once
|
|
+------+------+------+------+------+------+
|
|
Row 6 | ko | ko | ko | ko | ko | | 5 frames, once
|
|
+------+------+------+------+------+------+
|
|
Row 7 | win | win | win | win | | | 4 frames, loops
|
|
+------+------+------+------+------+------+
|
|
|
|
Each cell = 96x96 px. Unused cells (beyond frame count) should be empty/transparent.
|
|
```
|
|
|
|
## Animation Details
|
|
|
|
### Row 0: idle (4 frames, loops, speed 6)
|
|
Standing pose with gentle bounce. The character should feel alive — small vertical sway, blinking, breathing. This is the default state.
|
|
|
|
### Row 1: attack (6 frames, plays once, speed 12)
|
|
Punch attack. Right arm extends forward with impact at mid-animation (frames 2-3). Fast playback speed. Show wind-up, extension, and recovery.
|
|
|
|
### Row 2: kick (5 frames, plays once, speed 10)
|
|
Kick attack. Right leg extends outward/forward. Peak extension at frames 2-3, then retract.
|
|
|
|
### Row 3: special (6 frames, plays once, speed 8)
|
|
Ranged/energy attack. Right arm extends and fires a projectile (fireball, energy bolt, etc). Projectile appears in frames 3-5, moving rightward from the hand.
|
|
|
|
### Row 4: hit (3 frames, plays once, speed 8)
|
|
Taking damage. Character flinches/shifts right slightly. Quick reaction — just 3 frames. Shows impact.
|
|
|
|
### Row 5: knockback (5 frames, plays once, speed 8)
|
|
Heavy hit received. Character launched into the air (vertical arc up then down). Arms and legs flung. Stars/effects around head optional.
|
|
|
|
### Row 6: ko (5 frames, plays once, speed 6)
|
|
Knockout collapse. Character progressively slumps downward. Final frame should show the character on the ground, defeated. Eyes become X shapes.
|
|
|
|
### Row 7: win (4 frames, loops, speed 6)
|
|
Victory pose. One arm raised, triumphant expression. Loops for celebration. Optional sparkle effects.
|
|
|
|
---
|
|
|
|
## Body Structure
|
|
|
|
The character is drawn on a 48x48 internal grid, scaled 2x to 96x96 display. All pixel coordinates below are in the 48x48 space.
|
|
|
|
### Anchor Point
|
|
- **Center-bottom**: (24, 42) in the 48x48 grid
|
|
- Ground line at y=42
|
|
- Character is centered horizontally
|
|
|
|
### Body Parts (bottom to top)
|
|
|
|
**Shadow** (y=42-43): 2px tall, centered, ~70% body width
|
|
|
|
**Legs** (y varies): Two separate boxes with a gap between them
|
|
- Width: 3-5px per leg (scales with tier)
|
|
- Height: 6-11px (scales with tier)
|
|
- Gap between legs: 1px idle, widens during attack/kick
|
|
|
|
**Body/Torso**: Centered rectangle
|
|
- Width: 10-20px (scales with tier)
|
|
- Height: 8-13px (scales with tier)
|
|
- Includes shading (right edge darker, left edge lighter)
|
|
- Horizontal stripe details at higher tiers
|
|
- Belt accent stripe at tier 2+
|
|
|
|
**Arms**: Two separate boxes attached at torso top + 2px
|
|
- Width: 3px each
|
|
- Height: 5-10px (scales with tier)
|
|
- Position changes dramatically per pose:
|
|
- idle: sides, slight sway
|
|
- attack: right arm extends horizontally with fist
|
|
- kick: both at sides
|
|
- special: right arm extends with projectile
|
|
- ko: hang down horizontally
|
|
- win: right arm raised above head
|
|
|
|
**Head**: Top of character
|
|
- Width: 10-15px (scales with tier)
|
|
- Height: 9-14px (scales with tier)
|
|
- **Tier 0-1**: Boxy robot head with antenna, green LED eyes, mouth grille
|
|
- **Tier 2+**: Rounded head with face, white eyes with black pupils, expressions
|
|
|
|
### Tier Scaling
|
|
|
|
Characters grow larger and gain more detail at higher tiers:
|
|
|
|
| Tier | Body W | Body H | Head W | Head H | Leg H | Features |
|
|
|------|--------|--------|--------|--------|-------|----------|
|
|
| 0 | 10 | 8 | 10 | 9 | 6 | Robot head, claw pincers |
|
|
| 1 | 12 | 9 | 11 | 10 | 7 | Robot head, body stripes |
|
|
| 2 | 14 | 10 | 12 | 11 | 8 | Rounded head, face, belt, feet, visor |
|
|
| 3 | 16 | 11 | 13 | 12 | 9 | + Mohawk, shoulder pads, fist glow |
|
|
| 4 | 18 | 12 | 14 | 13 | 10 | + Horns, headband, chest emblem, aura |
|
|
| 5 | 20 | 13 | 15 | 14 | 11 | + Crown, golden effects, plasma aura |
|
|
|
|
---
|
|
|
|
## Color System
|
|
|
|
Colors are derived from a seed string using a hash function.
|
|
|
|
### Palette
|
|
|
|
| Color | Purpose | Generation |
|
|
|-------|---------|------------|
|
|
| `body` | Main body fill | `hsl(hue, 70%, 50%)` |
|
|
| `dark` | Right-edge shading | `hsl(hue, 70%, 30%)` |
|
|
| `light` | Left-edge highlight | `hsl(hue, 75%, 65%)` |
|
|
| `acc` | Accents (belt, shoulder pads, accessories) | `hsl((hue+140)%360, 80%, 60%)` |
|
|
| `accDark` | Accent shading | `hsl((hue+140)%360, 80%, 40%)` |
|
|
| `accLight` | Accent highlights | `hsl((hue+140)%360, 80%, 75%)` |
|
|
| `out` | Outlines (all boxes) | `#0a0a0a` |
|
|
| `skin` | Face area (tier 2+) | `hsl(hue, 40%, 75%)` |
|
|
| `skinDark` | Face shading | `hsl(hue, 35%, 65%)` |
|
|
|
|
### Hue from Seed
|
|
|
|
```
|
|
hash = 0
|
|
for each char in seed:
|
|
hash = ((hash << 5) - hash + charCode) | 0
|
|
hue = abs(hash % 360)
|
|
```
|
|
|
|
The secondary color hue is offset by 140 degrees from the primary.
|
|
|
|
### Custom Colors
|
|
|
|
Bots can override colors during registration via the `customization` object:
|
|
|
|
```json
|
|
{
|
|
"primaryColor": "hsl(200, 70%, 50%)",
|
|
"secondaryColor": "hsl(340, 80%, 60%)"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Drawing Primitives
|
|
|
|
All pixel art uses three functions:
|
|
|
|
### `px(x, y, color, ox, oy)`
|
|
Draw a single pixel at (x, y) in the 48x48 grid. `ox`, `oy` are the frame offset in the sheet.
|
|
|
|
### `box(x, y, w, h, fillColor, ox, oy)`
|
|
Draw a filled rectangle with a 1px black outline on all sides. This is the primary drawing function — bodies, heads, limbs all use this.
|
|
|
|
### `fill(x, y, w, h, color, ox, oy)`
|
|
Draw a filled rectangle without outline. Used for shading, highlights, and effects.
|
|
|
|
---
|
|
|
|
## Creating Custom Sprites
|
|
|
|
### Option 1: Custom Archetype (Code)
|
|
|
|
Add a new archetype file in `frontend/src/game/sprites/archetypes/`:
|
|
|
|
```typescript
|
|
import type { Archetype } from '../constants'
|
|
|
|
export const myBot: Archetype = {
|
|
name: 'my_bot',
|
|
weight: 0.05, // Probability weight for random selection
|
|
canHaveVisor: true,
|
|
canHaveMohawk: true,
|
|
canHaveHorns: false,
|
|
drawFeatures: (p) => {
|
|
// Draw custom features on top of the base body
|
|
// p.px, p.box, p.fill — drawing primitives
|
|
// p.pal — color palette
|
|
// p.tier — current tier (0-5)
|
|
// p.idle, p.atk, p.kick, etc. — current pose booleans
|
|
// p.bx, p.by, p.bw, p.bh — body position/size
|
|
// p.hx, p.hy, p.hw, p.hh — head position/size
|
|
// p.ox, p.oy — frame offset
|
|
|
|
// Example: draw a hat
|
|
if (!p.ko) {
|
|
p.box(p.hx + 1, p.hy - 4, p.hw - 2, 3, p.pal.acc, p.ox, p.oy)
|
|
p.fill(p.hx - 1, p.hy - 1, p.hw + 2, 1, p.pal.accDark, p.ox, p.oy)
|
|
}
|
|
},
|
|
}
|
|
```
|
|
|
|
Register it in `frontend/src/game/sprites/archetypes/index.ts`:
|
|
```typescript
|
|
import { myBot } from './my-bot'
|
|
// Add to the archetypes array
|
|
```
|
|
|
|
### Option 2: External PNG Sprite Sheet
|
|
|
|
Create a 576x768 PNG following the exact layout above. Requirements:
|
|
|
|
1. **Dimensions**: Exactly 576 x 768 pixels
|
|
2. **Transparent background**: All unused space must be transparent
|
|
3. **Frame grid**: 6 columns x 8 rows, each frame 96x96
|
|
4. **Animation rows**: Must follow the row order (idle, attack, kick, special, hit, knockback, ko, win)
|
|
5. **Frame counts**: Fill the correct number of frames per row. Extra cells can be empty.
|
|
6. **Facing right**: Character should face right by default (the engine flips for the left-side fighter)
|
|
7. **Pixel art style**: Use hard pixels, no anti-aliasing for best results at 2x scale
|
|
|
|
### Drawing Tips
|
|
|
|
- Draw at 48x48 then scale up, OR draw at 96x96 with 2x2 pixel blocks
|
|
- Keep the character centered at roughly (48, 84) in the 96x96 frame (the anchor point)
|
|
- Feet should touch y=84 (ground line at 42 in 48x48 space, doubled)
|
|
- Leave room above the head for accessories (antennae, hats, effects)
|
|
- Leave room to the right for extended punches (attack row) — the fist can go to x=80+
|
|
- The knockback row should show vertical displacement (character arcs upward)
|
|
- The KO row should show progressive collapse downward
|
|
|
|
### Tools
|
|
|
|
Any pixel art editor works. Recommended:
|
|
- [Aseprite](https://www.aseprite.org/) — professional pixel art with animation support
|
|
- [Piskel](https://www.piskelapp.com/) — free, browser-based
|
|
- [Pixelorama](https://orama-interactive.itch.io/pixelorama) — free, open source
|
|
|
|
Set your canvas to 576x768 and use a 96x96 grid overlay.
|
|
|
|
---
|
|
|
|
## Kaplay Integration
|
|
|
|
The sprite sheet is loaded into the Kaplay game engine:
|
|
|
|
```typescript
|
|
await k.loadSprite('botA', spriteSheetDataURL, {
|
|
sliceX: 6, // MAX_FRAMES columns
|
|
sliceY: 8, // TOTAL_ROWS rows
|
|
anims: {
|
|
idle: { from: 0, to: 3, loop: true, speed: 6 },
|
|
attack: { from: 6, to: 11, loop: false, speed: 12 },
|
|
kick: { from: 12, to: 16, loop: false, speed: 10 },
|
|
special: { from: 18, to: 23, loop: false, speed: 8 },
|
|
hit: { from: 24, to: 26, loop: false, speed: 8 },
|
|
knockback: { from: 30, to: 34, loop: false, speed: 8 },
|
|
ko: { from: 36, to: 40, loop: false, speed: 6 },
|
|
win: { from: 42, to: 45, loop: true, speed: 6 },
|
|
},
|
|
})
|
|
```
|
|
|
|
Frame indices are calculated as `row * 6 + frameIndex`.
|
|
|
|
---
|
|
|
|
## 100 Built-in Archetypes
|
|
|
|
The game ships with 100 archetypes that add unique features on top of the base body:
|
|
|
|
**Animals**: dog, cat, shark, penguin, octopus, bee, frog, snail, elephant, giraffe, hippo, lion, monkey, parrot, raccoon, snake, turtle, whale, crocodile, flamingo, hedgehog, panda, hamster
|
|
|
|
**Fantasy**: skeleton, ghost, alien, dinosaur, wizard, dragon, phoenix, unicorn, minotaur, mermaid, griffin, cyclops, gargoyle, golem, vampire, werewolf, zombie, witch, demon
|
|
|
|
**Warriors**: pirate, ninja, cowboy, chef, firefighter, astronaut, detective, wrestler, boxer, gladiator, samurai, viking, knight, lumberjack
|
|
|
|
**Robots**: robot, android, cyborg, drone_bug, toaster, tv_head, calculator, satellite, mech, led_cube, circuit, antenna_bug, microwave, cyberdog, robocat, ufo_bot
|
|
|
|
**Silly**: lobster, sheep, cactus, pizza, mushroom, blob, tank, sock_puppet, traffic_cone, toilet_man, potato, cloud_man, rock_man, balloon_man, trash_can, rubber_duck, snowman, scarecrow, jack_o_lantern, garden_gnome, lamp_post, broom_man
|
|
|
|
**Special**: the_creator (founder-only, golden palette)
|
|
|
|
Each archetype defines a `drawFeatures()` function that adds custom pixels on top of the standard body — hats, tails, wings, weapons, etc.
|