Battle Painters — User Manual
A 3D web remake of the freeware Windows game Battle Painters (Saito Games, 2000–2009), an ancestor of Splatoon. Up to four players race to cover the arena floor in their colour; whoever owns the most territory when the timer hits zero wins.
Table of Contents
- Overview
- Getting Started
- Main Menu
- Game Modes
- Controls
- Gameplay
- Magic Items
- Player Collisions
- HUD
- CPU Opponents
- Tips & Strategy
1. Overview
Battle Painters is a multiplayer arena game for 1–4 players locally (human or CPU), or up to 8 players online. Every player controls a paint brush that automatically moves forward across a canvas floor. Steering left and right is the only direct input. The brush leaves a trail of colour as it moves. When the round timer runs out, the percentages of floor covered by each colour determine the winner.
The arena size scales with the number of active players — two players get a smaller arena than four, so every match feels comparably dense regardless of headcount.
The canvas sits on the floor of a cheerful kid's bedroom — a bed, a toy chest, building blocks, a bookshelf, a rocking horse, a plush bear, and painting-themed touches like an easel, paint cans, a palette, and a framed paint color-chart poster all frame the play field, which sits on the wood-plank floor. A curtained window is a real opening in the wall that looks out onto a suburban backyard — a picket fence, a leafy tree with a swing, flowers, a neighbor's house, and clouds drifting overhead — which changes with your local time of day: a sunny blue sky by day, a warm low sun at dawn and dusk, and a moon, stars, and the neighbor's lit window at night; by day a soft sunbeam slants in through the glass with fine dust drifting in it. The backyard also mirrors the real weather where you are — clear, cloudy, overcast, rain, snow, or fog — and the real current moon phase (a crescent, gibbous, or full moon). Your location is inferred from your IP (no permission prompt) and, when you're offline, nothing is fetched — the window simply shows fair weather. A working wall clock ticks the actual current time, and balloons in the player colors bob overhead beside a slowly spinning mobile. Soft shadows ground the props and players. The scenery is purely decorative and never affects movement or painting; in high-contrast mode it is hidden so nothing competes with the paint for visibility.
2. Getting Started
Open the game in a browser (served from localhost:8080 during development, or the production dist/ build). The main menu appears automatically. No installation is required. Any reasonably recent browser works — Chrome/Edge 88+, Firefox 78+, or Safari 14.1+; older browsers see an update notice instead.
The production build is an installable PWA and works offline after your first online visit: the app, artwork, and sounds are cached locally, so you can add it to your home screen and play with no connection. Shortly after that first load the game quietly finishes caching all the music, sound effects, and character portraits in the background (and tops them up whenever you reconnect), so a later offline session has everything ready — even if you never heard a sound or saw every character the first time. Online multiplayer, naturally, still needs a connection.
The downloadable desktop app (macOS/Windows/Linux) keeps itself up to date: when a new version ships, an "update available" toast appears — accept it and the app downloads, installs, and relaunches on the new version; "Later" re-offers it next time you come back to the window.
3. Main Menu
| Option | Description |
|---|---|
| Battle Mode | 2–4 player versus mode (human vs human, human vs CPU, or CPU vs CPU), all on the same device. |
| Online Mode | Match with friends over the internet (WebRTC peer-to-peer). One side hosts and shares a short room code; others join by entering it. Up to 8 participants per room — the host can add CPU bots to fill empty slots. |
Below the main panel a Settings button opens a modal dialog with:
- Audio: independent Music and Sound effects volume sliders (each with a Mute checkbox).
- Display:
- Theme selector: Dark / System / Light (System follows the OS preference; persisted).
- Language selector: English, Français, Deutsch, Italiano, Español, עברית (RTL), 日本語 — auto-detected on first visit and persisted thereafter. Changing language live-rebuilds the surrounding screen — main menu or online lobby — without dropping a lobby's connections.
- Fullscreen toggle (where supported; on iPhone Safari an "Add to Home Screen" hint is shown instead).
- Minimap toggle — shows a small live coverage map in the corner during a round (on by default).
- Split screen toggle — when on, a local match with 2 or more Human slots renders one camera viewport per human instead of a single shared centroid camera; each viewport tracks only its own player, with thin divider strips between panes. Off by default. Only affects local matches — online host/client modes keep the single camera regardless. Live-toggled mid-round from the pause-menu Settings dialog.
- Head-to-head layout toggle — when on AND split screen is engaged, the panes are rotated so two players seated on opposite sides of a shared tablet each see their own pane right-side up. 2-pane: side-by-side columns rolled 90° in opposite directions. 3-4-pane: bottom row stays upright (near-side players) while the top row is rolled 180° (far-side players). The minimap, bottom status bar, and pickup-notification stack are hidden while head-to-head is active. Multiple humans can pick Touch as their input method in this mode, and each touch is attributed to the player whose pane it lands on.
- Player labels toggle — show name labels above brushes (on by default).
- Visual effects toggle — when off, suppresses the gameplay particle/burst effects (paint splashes, sparkle and brush trails, item-spawn rings, bomb explosions) and the decorative room's ambient motion (bobbing balloons, drifting clouds, dust motes, swaying curtains, the ticking wall clock). On by default, but defaults off automatically when your OS requests reduced motion (
prefers-reduced-motion: reduce). Live-toggled mid-round.
- Replays: Max local replays chip selector (1 / 3 / 5 / 10) — controls how many rounds are kept in IndexedDB. Lowering the cap prunes older entries immediately.
- Accessibility: Audio cues toggle — enables a continuous coverage feedback tone, HRTF-panned spatial item/collision sounds, and on-demand
P/I/Skeyboard shortcuts that narrate the local player's position, nearby items, and scores through a politearia-liveregion. Off by default.
The same Settings dialog is also available from the pause menu mid-game; toggles that affect the live round (minimap, split screen, head-to-head layout, player labels, visual effects, audio cues) take effect without restarting.
Below Settings, a Replays button opens the replay picker — browse rounds saved on this device, import a .bpr file from disk, or play one back. Each entry shows the recording date, winner, and finishing percentages; the picker also offers Download (binary .bpr) and Delete.
An About button opens a dialog with this user manual, the credits/attributions, and the privacy policy (all shown in-app).
At the bottom of the menu, small footer links open the web versions of these documents: the Player guide (this manual), the Privacy policy, and About the game (the promo listing).
4. Game Modes
4.1 Battle Mode
Configure the match before starting:
| Setting | Values | Notes |
|---|---|---|
| Battle Type | Single / Team | In Team mode, Players 1 & 2 face Players 3 & 4. Combined area percentage decides the team winner. |
| Win Match | Best of 1 / 3 / 5 | First player (or team) to reach the required number of round wins takes the match. |
| Player 1–4 | Human / CPU / Off | Mix any combination. Player 1 cannot be Off. For an actual contest, mark at least one other slot as Human or CPU. |
| CPU Difficulty | Easy / Normal / Hard / 😈 Hell | Controls how often and how accurately CPU opponents re-evaluate their target. Hell bots react in 80–180 ms and sample 32 candidate positions per think cycle. |
| Duration | 3 / 6 / 9 min (default 3 min) | Round length. |
After a round, the round-over screen shows the current win tally as win-pip dots per player. When someone clinches the match, the match-over screen shows the winner spotlighted with a coverage bar, the other players ranked below, and a stats block beneath: a Coverage over time sparkline (one colored line per player, sampled once per second across the round) and Items collected chips (per-player tally of which 👟 🖌 ⏰ 🧪 💣 ✨ items they picked up, with counts).
The match-over screen also offers:
- Watch Replay — plays back the just-finished round using a dedicated replay HUD (play/pause, scrubber, variable speed 0.25× – 8×, frame-step, save
.bprto disk, export to MP4 video). - Download image — saves the results card itself as a PNG.
Every round is automatically saved to a local Replays library backed by IndexedDB. The cap (default 3, configurable 1–10 in Settings) keeps the most recent N rounds and prunes older entries LRU. The library is reachable from the main menu's Replays button. Replay files are portable: a .bpr saved on one device plays back identically on another (the same recorded inputs are re-simulated). Playback always uses the single shared camera, even when the Split screen setting is on.
Note (online mode): Recording happens on the host (who runs the authoritative simulation). An online client doesn't record its own copy — to keep a replay of a match you played as a guest, ask the host for the file.
4.2 Online Mode
Two roles in the online panel:
- Host a room — your browser generates a short room code. Share that code with the other players (chat, SMS, whatever), or press the lobby's Invite Link button to share (or copy) a direct join URL instead. The host configures the match (battle type, win count, duration, CPU difficulty, which slots are filled by which side) and starts the round once guests have joined. Up to 8 player slots are available.
- Join a room — enter the host's code (Enter submits, or press Join the game), or simply open the host's invite link: it drops you straight into the lobby with no code entry. The connection opens directly (no central game server, no account, no sign-in); if it can't open, you get the usual connection error and land back on the menu.
Once connected, the host runs the authoritative simulation: paint, items, collisions, and the AI for any CPU slots all live on the host's machine. Each client sends its local player's steering inputs over the connection and renders the state the host broadcasts back. A laggy connection will feel laggy for the client; the host's view is always immediate.
The connection uses WebRTC peer-to-peer via the public PeerJS signalling server — no backend of your own is needed, but a corporate / school firewall that blocks UDP may prevent the connection from opening.
If you lose connection mid-game, a reconnect dialog appears automatically and immediately retries. If it succeeds, your slot is restored and play continues. If you can't reconnect in time, the host's game replaces your slot with an AI controller — you'll see a notification in the HUD. The host can also evict a guest from the pause menu, which replaces that slot with AI and lets the rest of the game continue.
If you join while a game is already in progress, you'll see a "Game In Progress" screen and are queued to connect at the start of the next game.
5. Controls
Players always move forward automatically. Only turning is required.
Each human player can choose an input method from their player card in the menu.
Keyboard
Keys are defined by physical position (using KeyboardEvent.code), so the same
key cluster works on QWERTY, AZERTY, QWERTZ, and Dvorak. The labels in the table below
show the QWERTY engraving; the menu displays the labels for your actual keyboard layout.
On Chromium browsers the labels come from the Keyboard Layout API
(navigator.keyboard.getLayoutMap()). On Firefox / Safari the labels start from the
US-QWERTY defaults and self-learn from real keystrokes — pressing keys in the
menu (or during a round) updates the chip text to match what's actually printed on
your keyboard, and the mapping is persisted across reloads. Until a key has been
pressed at least once, the chip falls back to the bundled simple-keyboard-layouts
table for common European layouts.
| Player | Colour | Turn Left | Turn Right | Dash | Physical position (layout-independent) |
|---|---|---|---|---|---|
| Player 1 | 🔴 Red | ← Arrow |
→ Arrow |
↑ Arrow |
Arrow keys |
| Player 2 | 🔵 Blue | A |
D |
W |
KeyA / KeyD / KeyW (WASD cluster, prints QD/Z on AZERTY) |
| Player 3 | 🟠 Orange | G |
J |
Y |
KeyG / KeyJ / KeyY (home-row cluster) |
| Player 4 | 🟢 Green | 4 |
6 |
8 |
Numpad 4 / 6 / 8 |
Gamepad / Controller
Select Gamepad in the input method cycle on any human player card. If multiple players choose Gamepad, the first (lowest-numbered) gets physical pad 0, the next gets pad 1, and so on.
Supported controls (standard mapping):
| Action | Input |
|---|---|
| Turn left | Left stick ← or D-pad ← |
| Turn right | Left stick → or D-pad → |
| Dash | A button (bottom face button) |
| Look around | Right stick — orbit the camera; springs back to default when released |
Multiple players can each use a separate gamepad simultaneously. Gamepad is not exclusive — other players can use keyboard at the same time.
A connected gamepad also drives the menus: the D-pad or left stick moves the focus between controls, A activates the focused control, and B backs out of the open dialog (same as Escape). In a running round these buttons stay with steering — menu navigation only engages while a menu or dialog is on screen.
TV remote (TV devices only)
On a smart TV or streaming-stick browser (Samsung Tizen, LG webOS, Android/Google TV, Fire TV, and similar), an extra TV remote input method appears in the cycle — it is hidden everywhere else. The remote's Left/Right D-pad buttons steer the brush and Up triggers a dash. A TV has one remote, so only one player can use it at a time (choosing it on another card moves it there); on a TV, Player 1 starts on TV remote automatically.
TVs also get D-pad menu navigation: the arrow buttons move a highlighted focus ring between menu controls, OK activates, and the remote's Back button closes dialogs. Menus, dialogs, and buttons render slightly larger for couch distance.
Mouse / Touch
These are also selectable as input methods. Mouse is always exclusive across slots — a single pointer can't drive two players. Touch is also exclusive by default, but when Split screen is enabled, multiple humans can each pick Touch and share the touchscreen: every active finger is bound to a slot at touchstart based on which split-screen pane it lands in (or the lone touch slot when split screen is off), so two players on a shared tablet can each tap their own pane to steer their brush. The player clicks or taps to set the direction of travel — aiming outside the painting canvas works too (the point is projected onto the floor plane, so tapping the bedroom floor past the arena edge still steers). A left click (mouse) or a quick double-tap (touch) triggers a dash. To look around, hold the right mouse button and drag, two-finger scroll on a trackpad (or roll the mouse wheel), or place two fingers and drag on a touchscreen (in split screen this orbits the pane the pointer/fingers are in); steering pauses while you orbit, and the camera springs back to its default angle when you let go (or, after a scroll, a moment after you stop).
General Keys
| Key / Control | Action |
|---|---|
ESC |
Open the pause menu (Resume / Settings / Return to Main Menu) |
| Pause button (⏸) | Touch devices only — circular button in the top-left corner of the screen |
P (audio cues on) |
Speak the local player's grid coordinates and facing |
I (audio cues on) |
Speak the nearest visible items and their bearings |
S (audio cues on) |
Speak the current coverage percentages for every active player |
Auto-pause on focus loss. Switching tabs, minimising, or alt-tabbing the browser window automatically pauses the round. In Online mode the host broadcasts the pause to the rest of the lobby so the match doesn't continue with stale input from your slot.
Camera
At the start of each round, the camera begins just above the floor at the centre of the arena pointing straight down, then over ~2 seconds lifts up and pulls back to the overhead play view — sweeping the floor before settling on the action. Throughout the match it follows the centroid of the human player(s); in CPU-only matches (no humans on this device) it falls back to the centroid of all active players. Online clients track only their own slot rather than the global centroid.
Looking around. You can orbit the camera while it keeps following you: hold the right mouse button and drag, two-finger scroll on a trackpad (or roll the mouse wheel) — horizontal scroll swings left/right, vertical scroll tilts up/down — drag with two fingers on a touchscreen, or push the right stick on a gamepad (the left stick / D-pad keep steering your brush; the keyboard has no camera keys). Rotation is clamped — about ±60° left/right and a limited up/down tilt — so the view always stays inside the room. Let go and the camera springs back to the default overhead angle (after a scroll, a moment after you stop). In split screen each player orbits only their own pane.
Adaptive zoom. Camera distance is picked from the viewport size (not the device type), so resizing or rotating your window changes the zoom live: short viewports (height < 500) pull in closest (~22 units), narrow viewports (width < 768) pull in a little (~26 units), and standard viewports keep the default overhead (~32 units). In head-to-head the portrait layout is the landscape layout rotated 90°, so each pane is measured by its landscape-equivalent footprint — and the two-player portrait panes fix the camera's field of view on the matching axis — so rotating the device keeps the arena framed at the same distance/scale instead of jumping zoom levels. The camera target tracks the player(s) directly with no edge clamp — at the arena walls the surrounding kid's-room scenery is visible past the wall, by design.
Split-screen cameras. With Split screen enabled in a local match of 2 or more humans, the single centroid camera is replaced by one ArcRotateCamera per human, each rendering into its own viewport rectangle and tracking only its own player. The intro arc runs in sync across all panes. Adaptive zoom uses each pane's footprint (not the full window), so a half-width pane pulls in proportionally; 3-4-pane layouts additionally halve the radius so each player still fills their pane. With Head-to-head layout also enabled, each camera's view is rolled to read upright for its target seat — without moving the camera itself — and the split adapts to the device orientation so each player always gets a landscape-shaped, facing pane. In landscape the two-pane layout splits left/right (rolled ±90°); in portrait it stacks top/bottom (near player upright, far player rolled 180°). The 3-pane and 4-pane layouts keep their near (upright) / far (180°) rows in both orientations, with the 3-pane near player taking the full-width bottom band in portrait. Rotating the device reflows the panes, dividers, and countdown portraits live.
6. Gameplay
Movement
- Your brush moves forward continuously at a fixed base speed. You cannot stop voluntarily.
- Dash. Every input method has a dash trigger (see the tables above): a burst of ×2.5 speed for 0.35 s along your current travel direction — steering is locked for the burst (the arrow still pre-aims), and a sparkle trail marks it. Dashing again needs a 2.5 s cooldown (counted from the dash start). Hitting a wall ends the burst early; a player collision or a ⏰ freeze cancels it too (the cooldown keeps running). You can't dash while frozen, airborne, 🩹 bandaged after a collision, or during the item-pickup pause. The dash replaces (never stacks with) the 👟 Shoe boost and the 🩹 penalty for its duration. CPU players on Hard and Hell dash too — to charge an opponent at close range, to escape an incoming collision, to win a race to an item, or simply to cover a long stretch of floor faster.
- Turning steers the brush left or right. Holding a turn key rotates the direction arrow at ~180°/second; the brush's body chases it at ~126°/second.
- Direction arrow and brush lag. A direction arrow floats just ahead of your brush showing where you are steering. The arrow tracks your input directly; the brush's actual travel direction follows it with a slight lag, giving steering a fluid, momentum-like feel. The arrow is capped at ±60° from your current travel direction — you can pre-aim a turn without the brush immediately snapping.
- Frozen players keep their arrow. A player frozen by a ⏰ Clock cannot move or paint, but can still rotate their direction arrow to aim for where they will head when the freeze ends.
- Item-pickup pause. When any item is collected, all players' movement briefly pauses for 0.4 s — the collected item's effect duration is extended by the same amount to compensate.
- Arena boundary: the edge of the 40 × 30 floor is an invisible wall — the brush position is hard-clamped to the playfield. Hitting the edge at an angle causes the brush to slide along it (direction snaps to the nearest wall-parallel). Hitting it head-on (≈ 90°) or cornering stops the brush until you rotate away.
Painting
- The brush paints the floor in your colour as it moves, leaving a circular trail.
- When painting stops: the colored stamp on the floor is suspended in three situations — when you're frozen by an ⏰ Clock, when you're airborne from a player collision (jump arc), or when you're out of ink from a 🧪 Potion. In the Potion case the coloured bristles on your brush model also disappear as a visual cue (frozen players appear grayscale instead, airborne players keep their colour).
Winning a Round
When the timer reaches zero, the floor is tallied pixel by pixel:
- Single battle: the player with the highest coverage % wins the round.
- Team battle: Player 1 + Player 2 coverage is summed against Player 3 + Player 4 coverage; the higher team wins.
The arena resets between rounds (floor wiped clean, players return to their starting positions).
Starting Positions
Active players spawn around the centre of the arena on a ring (radius ≈ 3.5 world units at four players, scaling linearly with player count so the arc between adjacent players stays roughly constant), each facing outward — away from the centre. They burst apart at the start of the round, painting in different directions from a shared origin.
Players sit around the ring in the same order as their cards on the selection screen: clockwise from the top-left as P1, P2, P3, P4.
- All four active: each player keeps their canonical quadrant — Player 1 top-left, Player 2 top-right, Player 3 bottom-right, Player 4 bottom-left (clockwise so the left-to-right player-card order traces the ring).
- Fewer than four active (some slots set to Off): the remaining players are distributed evenly around the spawn circle, keeping their relative menu order — e.g. two active players spawn diametrically opposite each other; three active players form an equilateral triangle. No one is bunched on one side just because another slot is Off.
7. Magic Items
Items spawn as floating 3D objects (a boot, a paintbrush, an alarm clock, a glowing potion flask, bombs) roughly every 15–30 seconds. A maximum of 3 items can be on the field simultaneously. Walk over an item to collect it instantly. The minimap marks each on-field item with the matching emoji glyph.
| Emoji | Name | Effect | Duration |
|---|---|---|---|
| 👟 | Magic Shoe | Your movement speed × 1.7. Also instantly removes any active 🩹 speed-penalty bandage so the full boost applies immediately. | 10 s |
| 🖌 | Magic Brush | Your paint radius × 1.5 (wider trail). If you are currently ink-drained, collecting a Brush also instantly restores your ink before applying the radius bonus. | 10 s |
| ⏰ | Magic Clock | All other players are frozen — they stop moving and painting; frozen players appear grayscale | 5 s |
| 🧪 | Magic Potion | All other players run out of ink — they cannot paint, their bristles disappear, and any 💣 / ✨ items they pick up have no effect until ink returns (🖌 is the exception — it restores ink immediately and applies its radius bonus). The picker also instantly recovers their own ink (if drained by a previous Potion) and clears the 🩹 speed-penalty bandage from a recent collision. | 8 s (drain on others) |
| 💣 | Paint Bomb | Instantly paints a large circle (radius 3 world units) at your current position | Instant |
| ✨ | Small Paint Bombs | Scatters 24 small paint circles (radius 0.8) at random positions across the whole arena | Instant |
Note: The Brush effect stacks with your current paint radius when calculating the final value. The Shoe removes any active speed penalty before applying the boost, so you always get the full ×1.7 speed.
Note: While you are ink-drained by a 🧪 Potion, picking up a 💣 Paint Bomb or ✨ Small Paint Bombs still removes the item from the field but applies no effect — there's no point scattering paint when you can't paint. The 👟 Shoe and ⏰ Clock still work normally. The 🖌 Magic Brush is the exception: it restores your ink immediately and then applies its radius bonus, making it a useful recovery tool when ink-drained.
Note: All active magic-item effects (speed, radius, freeze, ink drain) are immediately cancelled on both players when a collision occurs.
8. Player Collisions
When two players collide:
- Effect cancellation — all active magic-item effects (Shoe speed, Brush radius, Clock freeze, Potion ink drain) are immediately cancelled for both players.
- Jump — both players are launched in opposite directions (away from the collision point) with a parabolic arc lasting ~1 second. Player input is suspended during the arc — position is driven entirely by the collision impulse. Painting is suspended while airborne.
- Speed penalty — upon landing, both players move at 50% of normal speed for 10 seconds. A 🩹 bandage icon appears above the affected brush for the duration of the penalty.
- Cooldown — a ~2 s cooldown (the ~1 s airborne arc plus a 1 s recovery) prevents the same pair from immediately re-triggering a collision.
The jump push is strongest at the moment of collision and fades as the arc completes. The push force scales with both players' speed states at the moment of impact — the average of each player's speed factor is applied. A 🩹 speed-penalised player contributes a factor of 0.5 (half push); a 👟 Shoe-boosted player contributes 1.7 (stronger push); a normal player contributes 1.0. Two bandaged players bounce less far than two at full speed; two Shoe-boosted players bounce farther. All effects are cancelled immediately before the push is applied, so the factor is computed from the pre-collision state.
Note: Frozen players (from the ⏰ Clock) are not shielded from collisions — running into a frozen opponent unfreezes them immediately (and cancels all other effects on both players).
9. HUD
The heads-up display has three parts: a three-zone status bar across the bottom, a pickup/event notification stack in the top-right, and (in development builds only) a debug bar across the top.
| Element | Description |
|---|---|
| Status bar | Bottom-centre, three zones: Round N / X (current round / wins needed to take the match), Time (progress bar that fills left-to-right as time elapses + remaining M:SS label; turns red in the final 10 s), and Single / Team Battle label. |
| Minimap | Bottom-left of the canvas. 160×120 canvas updated each frame, showing live paint coverage, a white-fill colour-bordered dot per active player, and an emoji marker for each magic item currently on the field. Toggle on/off from Settings. Hidden while head-to-head split screen is active. |
| Split-screen panes | When Split screen is on in a local match with ≥2 humans, the canvas is partitioned into one viewport per human (2 = side-by-side columns; 3 = players 1 & 2 on the bottom row, player 3 centered above; 4 = 2×2 grid with players 1 & 2 on the bottom row and 3 & 4 on top), each rendered by its own camera tracking that human's player. Thin black divider strips frame the seams. A per-pane portrait card is shown at the centre of each viewport during the countdown (morphs from the loading-screen portrait via a view-transition). |
| Head-to-head rotation | When Head-to-head layout is on alongside split screen, each pane is rolled to read upright for the player seated on its side of the device (2-pane: ±90°; 3-4-pane: top row rolled 180°). The minimap, bottom status bar, and pickup-notification stack are hidden while head-to-head is active. |
| Pickup notifications | Top-right stack. Each time any player picks up a magic item, a brief toast slides in showing that player's portrait and name — visible to all players. Hidden while head-to-head split screen is active. |
| Event notifications (Online) | Same top-right stack. Slides in when a guest disconnects (replaced by AI), is evicted, or reconnects — shows the player's portrait and name. |
| Player coverage | Hidden during normal play. Press # in development builds to toggle the debug bar — it shows the item-spawn picker plus a colour-coded Pn xx% badge for each active player. |
| Pause menu | Full-screen overlay shown when ESC is pressed (or the pause button on touch devices), with Resume, Settings, and Return to Main Menu options. In Online mode as host, also lists connected guests with an Evict option per guest. |
| Pause button (touch) | Circular button in the top-left corner, visible on touch devices only. |
10. CPU Opponents
CPU players range from gentle to merciless. Difficulty controls how quickly and accurately a bot re-evaluates its target:
| Level | Reactions | Feel |
|---|---|---|
| Easy | Slow (3–5 s); wanders ~35 % of the time | Forgiving — overshoots and drifts, never dodges. Good for learning the game. |
| Normal | Moderate (1.5–2.5 s) | Balanced default. Escapes wall traps and dodges incoming charges. |
| Hard | Fast (0.4–0.7 s) | Wide awareness, plans in quadrants, leads its charges, dodges competently. |
| 😈 Hell | Near real-time (0.08–0.18 s) | Ruthless and precise — tracks you exactly and fights you for every item it can reach first. Not recommended for the faint of heart. |
Bots are more than fixed difficulty dials. Each is given a hidden personality — painting fresh ground, hunting opponents, rushing the best item, contesting the frontier, or covering a teammate — and shifts strategy live as the match unfolds: chasing items by value, freezing or draining a surging leader, dodging a charge to protect a buff, and ganging up on whoever is ahead. They also learn across rounds — a bot that won by charging grows bolder, and one that has watched you dominate starts treating you as a priority rival — so the deciding round of a best-of-5 can feel markedly different from round 1.
The Tips & Strategy section below turns these behaviours into concrete counter-play. For the full behavioural model and difficulty tuning see developer-manual.md; for the game-theory rationale behind each rule see theory.md.
11. Tips & Strategy
- Unclaimed territory is the priority. The unpainted (canvas-coloured) floor gives you the biggest gains. Aim for gaps between trails rather than re-painting opponents' areas early on.
- Use the arena boundary deliberately. Grazing the invisible boundary at a shallow angle lets you slide along it and paint the perimeter efficiently. Sharp corners are a trap — rotate early.
- Time the Clock carefully. Freezing opponents with ⏰ is most valuable when you're near unpainted space, not when you're in the middle of your own territory.
- The Potion disrupts momentum — and denies paint-power items. 🧪 is especially powerful against a player who has just collected a Shoe or Brush (the speed/radius bonus is wasted while they're de-inked) and against any 🖌 / 💣 / ✨ they pick up during the 8 s drain (those items have no effect on a drained player). Throw a Potion when you see paint-power items spawning to deny your opponent both options at once. A collision restores their ink instantly.
- Being de-inked makes you a collision target for aggressive CPU bots. When a CPU bot's own ink is drained, it immediately charges the nearest opponent to recover via collision — regardless of what strategy it was following. If you've just been Potion'd, expect aggressive bots to come at you.
- Bombs are decisive mid-game. 💣 used in a dense cluster of neutral or enemy territory can swing 2–4% of the floor in one instant (the larger arena dilutes the relative impact).
- In Team mode, split up. You and your teammate paint separate halves of the arena for maximum combined coverage. All CPU bots in team mode — regardless of personality — avoid repainting their teammate's territory, so CPU teams naturally self-divide the arena without explicit coordination.
- Speed penalty timing matters. After a collision you move at 50% speed for 10 s. Picking up a 👟 Magic Shoe while bandaged immediately removes the penalty and applies the full ×1.7 boost — making it the best early recovery item after a collision. Avoid fighting for the same bonus item with an opponent — a collision just before picking it up wastes both players' time and cancels any active bonuses.
- Collisions strip all effects. Use a collision deliberately to cancel a dangerous opponent's Shoe or Clock buff — but it will cancel your own effects too.
- Unfreezing with a collision. Running into a frozen player immediately unfreezes them, so don't rely on the Clock to keep an opponent out of your way if you plan to move through the same area.
- CPU opponents are adaptive — and faster when the stakes are high. Each bot has a hidden base personality that shapes its style, but the active behaviour shifts in response to the live situation. When the strategy switches to aggressive the bot also starts thinking faster; when it shifts to defensive it slows down. When an opponent is frozen or de-inked, aggressive bots look past them and go for active threats — frozen/de-inked players are not threatening, so charging them wastes movement. Instead the bot shifts toward painting while the coast is clear.
- Bots prioritise items by value, not proximity. A losing CPU will rush a Shoe or Bomb even from a distance; a winning CPU will sprint for a Clock to freeze you. Grabbing a high-value item before a bot reaches it is often more impactful than painting an extra strip of floor.
- Corner traps work on bots too. CPU players actively avoid targeting positions near the arena boundary, so they move more fluidly through the centre. Luring a Hard or Hell bot into a corner can buy you a few extra seconds.
- Hard and Hell bots think in quadrants. Each cycle they scan the whole arena and direct attention toward the most-opportunity quadrant — for aggressive bots that means the quadrant most covered in your paint; for defensive bots, the most contested zone. You can exploit this: heavy activity in one area will keep drawing certain bots there, leaving the opposite side open longer.
- Trailing bots repaint your territory. The further a CPU falls behind, the more it treats your painted tiles like empty space — every stroke both grows its score and shrinks yours. The attraction scales continuously with its deficit, so a bot trailing by 20 % is dramatically more likely to overpaint you than one trailing by 5 %. Get a Clock or Potion early if you build a large lead; stalling a chasing bot matters as much as painting new ground.
- In multi-player games, all trailing bots converge on the leader — and harder the further they trail. When a bot is losing by more than 5 %, it gives extra weight to overpainting the leader's territory. The weight scales with the deficit: a bot trailing by 30 % applies double the coalition pressure of one trailing by 15 %. Multiple trailing bots independently doing this converge on the same leader, with the most desperate bots applying the most pressure. If you build a large lead, expect increasingly aggressive ganging-up.
- Bots remember what worked — and remember you. Across rounds in a multi-round match, each CPU adjusts the weight it gives each strategy based on its finishing rank. A bot that won while playing aggressively leans more aggressive the next round; one that lost defensively moves away from that style. By round 3 or 4, bots will have meaningfully adapted to how the match has gone — expect their play to feel different in the deciding round compared to round 1. Beyond strategy bias, bots also track each opponent's round-end percentage over the last five rounds. If you or a CPU has dominated (averaged > 30 % coverage over two or more rounds), other bots begin treating that player as a priority rival and shift toward aggressive or defensive responses against them.
- Aggressive bots get bolder when they're winning. The charge probability for aggressive-strategy bots is not fixed — it adapts with the bot's accumulated learning. A bot that has won several rounds while playing aggressively can charge up to 85 % of the time; a bot that has been losing moderates to as low as 15 %. If you notice a bot becoming unusually relentless, it has likely learned that charging works.
- Carrying a 👟 Shoe or 🖌 Brush makes you a magnet — and makes bots hide their own. Aggressive bots actively pursue buffed opponents because a collision strips the buff. A Shoe-buffed player at long range can outrank a bare player nearby in a bot's charge ranking. Conversely, when a bot collects a Shoe or Brush its own charge probability drops by a quarter, so a buffed bot will paint and dodge rather than ram — chasing a recently-buffed CPU is therefore less rewarding than usual.
- Bots predict where you're turning, not just where you are. Hard and Hell bots extrapolate the target's heading and turn rate up to 0.4–0.8 s ahead before committing to a charge. Holding a turn key gives them a clean lead solution; releasing both keys (or pressing left+right together to nullify the turn) flattens the prediction to a straight line, which is easier to side-step. A late, sharp turn 200 ms before the bot lands its charge is the most reliable way to break interception.
- Carrying a 👟 Shoe near a Shoe-buffed opponent is double-bait. When both bots in a potential collision are Shoe-boosted, the kinetic exchange is at its maximum (1.7× normal push) — bots see this as the strongest possible charge target and are pulled toward it disproportionately. If you and another player both grab Shoes and run anywhere near each other, expect aggressive CPU bots to converge on the matchup. Pair this with the self-buff penalty (a Shoe-buffed bot is less likely to charge in the first place) and the only confident charger in that scenario is an unbuffed CPU — those are the bots you should be watching when both you and another opponent are showing 👟.
- A 🩹 bandaged CPU is a low-momentum threat. A bandaged-vs-bandaged collision produces only half the normal push, so two bandaged players ramming each other is a waste of time and bots treat it as such. If you've just been in a collision and are still wearing a 🩹 bandage, a bandaged CPU near you is much less likely to deliberately charge — its denial weight on you is halved. Once your bandage lifts (10 s after the collision) the threat returns to normal.
- A surging opponent makes the ⏰ Clock a top priority — and the harder they surge, the harder bots race for it. Whenever any player is gaining ground faster than the difficulty-normalised fast-gainer threshold, the Clock's value rises by a bonus that scales continuously with the surge magnitude (up to +1.0 above the base 2.5×/1.8×). If the surger is also the current leader, the bonus is doubled — a leader hitting a 💣 Paint Bomb effectively makes any visible Clock the single highest-value item on the field (up to base + 2.0). If you're the one surging by chaining items, expect every CPU within range to redirect toward any Clock spawn that appears in the next few seconds.
- A bandaged CPU near you is doubly less likely to charge unless you're buffed. On top of the 50 % speed reduction, a bandaged CPU subtracts another 0.15 from its charge probability when no strip-worthy target is in range — colliding with a bare opponent while bandaged just refreshes its own 10 s bandage timer for nothing. The penalty does not apply if you (or another opponent in its threat pool) are carrying an active 👟 Shoe or 🖌 Brush. So during the 10 s after a collision: stay away from buffed players if you want the bot to leave you alone, or pick up a Shoe/Brush yourself to draw the bandaged CPU back into engagement.
- Urgency builds throughout the round, not just at the end. Bots track the ratio of their lead deficit to time remaining. A 10 % deficit with 30 s left feels the same as a 5 % deficit with 15 s left — both produce the same urgency level and the same strategy shift toward aggressive and opportunist play. Because the formula is
|lead| / remainingSec, the urgency curve auto-scales to whatever round length you picked: bots play patiently early in a 9-minute match and reach the same maximum desperation in the final seconds as in a 3-minute match. - Grab the Clock at any score deficit. ⏰ is valued at 2.5× by bots whether they are winning or losing — they treat it as both a finishing tool and a catch-up tool. If you see a Clock on the field and you're in a close race, prioritise reaching it first.
- Painting fast makes you a target. If you are rapidly claiming unclaimed territory, nearby bots will detect your gain rate each think cycle and give your paint an extra priority for overpainting. A burst of fast painting is high-value but also draws attention — you may find bots re-routing toward your territory mid-round.
- Easy bots are genuinely unpredictable; Hell bots are not. Strategy selection is probabilistic, and the unpredictability scales inversely with difficulty. An Easy bot might play defensively in a losing position simply because its strategy mixing is very wide. A Hell bot in the same position will almost always switch to aggressive or opportunist — its behaviour is consistent and readable, which is what makes it hard to play against rather than just random.