Battle Painters

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

  1. Overview
  2. Getting Started
  3. Main Menu
  4. Game Modes
  5. Controls
  6. Gameplay
  7. Magic Items
  8. Player Collisions
  9. HUD
  10. CPU Opponents
  11. 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:

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:

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:

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

Painting

Winning a Round

When the timer reaches zero, the floor is tallied pixel by pixel:

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.


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:

  1. Effect cancellation — all active magic-item effects (Shoe speed, Brush radius, Clock freeze, Potion ink drain) are immediately cancelled for both players.
  2. 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.
  3. 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.
  4. 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