From 1e48fcf573ae2af71a03bc75e115225153e907a5 Mon Sep 17 00:00:00 2001 From: arisklar6 Date: Tue, 8 Sep 2026 20:25:10 +0000 Subject: [PATCH 1/2] Rename product framing from CTF/Paintbot to Battle Royale in docs Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../skills/live-ffa-viewer-testing/SKILL.md | 4 +- .gitignore | 2 +- AGENTS.md | 2 +- README.md | 68 ++++++++++++++----- REPLAY_BRIEF.md | 2 +- caos-tools/test.sh | 2 +- docs/MAPKIT.md | 4 +- docs/PROTOCOL.md | 6 +- docs/RULES.md | 29 +++++--- docs/designs/expand-replay-reporter.md | 2 +- docs/designs/map-editor.md | 2 +- flake.nix | 8 +-- players/baseline/README.md | 2 +- tools/ladder/README.md | 6 +- 14 files changed, 93 insertions(+), 46 deletions(-) diff --git a/.agents/skills/live-ffa-viewer-testing/SKILL.md b/.agents/skills/live-ffa-viewer-testing/SKILL.md index 9861521b..c97045df 100644 --- a/.agents/skills/live-ffa-viewer-testing/SKILL.md +++ b/.agents/skills/live-ffa-viewer-testing/SKILL.md @@ -1,9 +1,9 @@ --- name: live-ffa-viewer-testing -description: Boot a live CTF/FFA (battle-royale) server with bots and inspect the board visually in the browser viewer — for testing rendering/presentation changes (map art, palettes, HUD) end-to-end instead of only via unit tests. +description: Boot a live Battle Royale (FFA) or legacy CTF server with bots and inspect the board visually in the browser viewer — for testing rendering/presentation changes (map art, palettes, HUD) end-to-end instead of only via unit tests. --- -# Live FFA/CTF board testing in the browser viewer +# Live Battle Royale / CTF board testing in the browser viewer ## Build diff --git a/.gitignore b/.gitignore index eafdc9f5..06c2ac9f 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,7 @@ players/modulabot/test/parity /data/rig_real/*.png # Local coworld package build output. CI builds the real package to build/ from -# the tracked coworld_manifest_paintbot.json; dist/ is a local convenience artifact. +# the tracked coworld_manifest_battleroyale.json; dist/ is a local convenience artifact. /dist/ trench-demo.bitreplay pool-preview/ diff --git a/AGENTS.md b/AGENTS.md index 86770f5a..aacf7f48 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,4 +1,4 @@ -# Agent operating guide — coworld-ctf +# Agent operating guide — coworld-battle-royale Orientation for coding agents (Claude Code, Codex, etc.) working in this repo. Gameplay rules live in [docs/RULES.md](docs/RULES.md); this file diff --git a/README.md b/README.md index 1dea159b..4638a297 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,65 @@ -# Coworld CTF — AI Capture-the-Flag Shooter - -Coworld CTF is a two-team capture-the-flag shooter for the Coworld platform. Two -teams (Red and Blue) start on opposite edges of a symmetric arena, each with its -own flag on a home pedestal. Players move, take cover behind obstacles, and -shoot. Steal the enemy flag and carry it home — or wipe the enemy team — to win. +# Coworld Battle Royale — AI Free-for-All Shooter + +Coworld Battle Royale is a free-for-all shooter for the Coworld platform. The +shipped config (`config.br.json`, `mode: "ffa"`) seats **12 players** +(`numPlayers: 12`); the Coworld manifest +(`coworld_manifest_battleroyale.json`) ships the `br-12` and `br-16` variants. +Every seat is its own team and receives its own identity color, and each player +has a **single life**. Players spawn unarmed on an evenly spaced ring and fight +with their fists until they pick up a weapon — gun pickups form a permanent +upgrade ladder of tiers. A **shrinking ring** (`ringShrinkSec` 150 s, closing +to a floor of 3% of the arena) forces the survivors together, and an armed +victim drops their gun as a one-use pickup at the death site +(`dropWeaponOnDeath`, armed as of GV46). **Placements** decide the results. Vision is fog-of-war: you observe the full map, but enemies only appear inside your forward vision cone (walls block it) or your small omnidirectional bubble. It is a fork of [Crewrift](https://github.com/Metta-AI/coworld-crewrift). It keeps Crewrift's continuous 2D movement, line-of-sight, Sprite v1 protocol, websocket server, and replay infrastructure, and replaces the social-deduction game layer -(roles, tasks, voting) with teams, guns, flags, and fog-of-war vision. +(roles, tasks, voting) with teams, guns, and fog-of-war vision. The **full, authoritative ruleset lives in [`docs/RULES.md`](docs/RULES.md)**. The summary below is just an orientation. -This repo publishes one `battleroyale` Coworld manifest with the `br-12` and -`br-16` variants. The battle-royale league is a free-for-all: every seat is its -own team and receives its own identity color. CTF compatibility remains in the -engine and tests, but is not the artifact published by this repository. - If docs, commands, runtime behavior, logs, or replays disagree while you are -building or submitting a CTF policy, preserve the evidence and file a GitHub issue +building or submitting a policy, preserve the evidence and file a GitHub issue instead of silently working around it. Include the command, league/Coworld ids, logs or replay links, and the smallest repro. -## Rules at a glance +## Battle Royale at a glance + +- **Free-for-all, single life.** Every seat is its own team with its own + identity color. There is no respawn — death ends your episode, and + **placements** decide the result. +- **Unarmed start.** Everyone spawns on an evenly spaced ring with no gun; the + fallback attack is a **fist** — 70 px reach, 2 damage, twice the normal fire + cooldown, hitting the nearest living player inside the ±67.5° aim cone. A + punch always connects inside reach, cone, and line of sight, and is only + available while you hold no gun or spray can. +- **Weapon tiers are a permanent upgrade ladder.** Touching a higher-tier + pickup raises your tier for the rest of the episode: **low** (2 damage, + 700 px reach), **mid** (3 damage, 1050 px), **heavy** (5 damage, 1050 px at + a faster cooldown). No weapon has ammo, durability, or a magazine — the only + way to lose a gun is to die. +- **Drop on death (GV46).** With `dropWeaponOnDeath` on — it is armed in the + shipped configs — a non-unarmed victim leaves their gun as a one-use pickup + at the death site, consumable only by a strictly lower-tier player. Grenades + and spray cans drop nothing. +- **The ring shrinks.** The safe zone closes over the match + (`ringShrinkSec` 150 s in `config.br.json`) down to a final floor of 3% of + the arena (`ringFloorAreaPct`). +- **Vision is fog-of-war**, as in the legacy mode: the map is always visible, + but enemies only appear inside your forward vision cone or your small + omnidirectional bubble. + +See [`docs/RULES.md`](docs/RULES.md) for exact mechanics and tuning defaults. + +## Legacy CTF mode — rules at a glance + +The bullets below describe the two-team capture-the-heart mode that remains in +the engine and tests (`config.json`, `mode: "ctf"`); it is not the Coworld this +repo publishes. "Flag" below is the heart: the mode reskinned flags as hearts. - **8 vs 8.** Red spawns on the **left** edge, Blue on the **right**. Each team's flag sits on a pedestal inside its spawn pocket. @@ -72,8 +106,8 @@ See [`docs/RULES.md`](docs/RULES.md) for exact mechanics and tuning defaults. ## Campaign mode (territory leagues) -Ctf and Paintbot also run **campaign leagues** (e.g. "CTF Campaign", "Paintbot -Campaign"): territory wars on a cell grid where an LLM strategist issues +The Coworld platform also runs **campaign leagues** (e.g. "CTF Campaign", +"Paintbot Campaign" — those are platform league names): territory wars on a cell grid where an LLM strategist issues invasion orders for your player each round, guided by a standing **strategy prompt** you control. Each contested cell is settled by the policies playing a normal match on the cell's variant (which sets the battle mode — 1v1 duel, @@ -161,7 +195,7 @@ docker run --rm -d \ ## Policy starting points -CTF policies speak the shared Bitworld Sprite v1 protocol: +Policies speak the shared Bitworld Sprite v1 protocol: The runner starts every policy with a `COWORLD_PLAYER_WS_URL` environment diff --git a/REPLAY_BRIEF.md b/REPLAY_BRIEF.md index e4b8fbc2..2f9eb9b5 100644 --- a/REPLAY_BRIEF.md +++ b/REPLAY_BRIEF.md @@ -94,7 +94,7 @@ Ranked by drama: ## Tempo map 24 ticks/s (`ReplayFps`). `maxTicks 10000` ≈ 6:56 of game time (config.json:13 — but certification runs -`maxTicks 300` ≈ 12.5s in `coworld_manifest_paintbot.json` certification, so the clock derives from `sim.config.maxTicks`, +`maxTicks 300` ≈ 12.5s in `coworld_manifest_battleroyale.json` certification, so the clock derives from `sim.config.maxTicks`, never a hardcode). Engine playback speeds `[1,2,3,4,8,16]` (replays.nim:40). Dead time = both flags home, no contact — where speed collapses; contact windows and any beat hold their read time (DEPTH_TARGET tempo levers). diff --git a/caos-tools/test.sh b/caos-tools/test.sh index b7c09454..363e1ceb 100755 --- a/caos-tools/test.sh +++ b/caos-tools/test.sh @@ -88,7 +88,7 @@ narrow) # COMPILED in. Verified as the only top-level files any .nim actually reads # (Dockerfile and AGENTS.md appear in comments only). narrow_tree /cas/ws src tests tools players client data \ - config.json coworld_manifest_paintbot.json + config.json coworld_manifest_battleroyale.json deps=$(caos curry --base:@=/cas/args/base \ "--worker1:@=/cas/args/in/caos-tools/lib/deps.sh") || fail "currying deps" diff --git a/docs/MAPKIT.md b/docs/MAPKIT.md index b9ae5405..49f35557 100644 --- a/docs/MAPKIT.md +++ b/docs/MAPKIT.md @@ -1,6 +1,6 @@ -# mapkit — LLM-authored, interesting-but-fair CTF maps +# mapkit — LLM-authored, interesting-but-fair maps -`tools/mapkit.nim` is a CLI for generating and hand-editing CTF maps in the +`tools/mapkit.nim` is a CLI for generating and hand-editing maps in the native `mapSpec` format. It is a peer to the [map editor](designs/map-editor.md) service: it never reimplements geometry, it drives the same sim procs (`generateMapAttempt`, `mapSpecJson`/`mapFromSpecJson`, `validateGeneratedMap`, diff --git a/docs/PROTOCOL.md b/docs/PROTOCOL.md index a780967c..fb6f559a 100644 --- a/docs/PROTOCOL.md +++ b/docs/PROTOCOL.md @@ -1,16 +1,16 @@ -# CTF wire protocol — Sprite v1 plus CTF extensions +# Coworld Battle Royale wire protocol — Sprite v1 plus game extensions Both the player endpoints (`/player`, POV observation streams) and the global/spectator endpoint speak [Sprite v1](https://github.com/Metta-AI/bitworld/blob/master/docs/sprite_v1.md). -This document lists everything CTF adds or changes relative to that base +This document lists everything the game adds or changes relative to that base document; anything not mentioned here matches Sprite v1 exactly. Game semantics — mechanics, sprite labels, tuning defaults — live in [`RULES.md`](RULES.md). ## Player input: bit 7 is the C button -Sprite v1 reserves player-input bit `7` ("must be sent as 0"). CTF assigns it: +Sprite v1 reserves player-input bit `7` ("must be sent as 0"). The game assigns it: | Bit | Value | Meaning | | ---: | ---: | --- | diff --git a/docs/RULES.md b/docs/RULES.md index 77343400..c4db68bc 100644 --- a/docs/RULES.md +++ b/docs/RULES.md @@ -1,11 +1,18 @@ -# Coworld CTF — Game Rules - -Coworld CTF is a two-team capture-the-heart shooter for the Coworld platform. Two -teams start on opposite edges of a symmetric arena, each with its own heart on a -home pedestal. Players move, take cover behind obstacles, and shoot. Steal the -enemy heart and carry it home — or eliminate the enemy team — to win. Vision is +# Coworld Battle Royale — Game Rules + +Coworld Battle Royale is a free-for-all shooter for the Coworld platform +(`config.br.json`, `mode: "ffa"`, 12 seats; the manifest ships the `br-12` and +`br-16` variants). Every seat is its own team and receives its own identity +color. Each player has a single life, spawns unarmed on an evenly spaced ring, +and fights with fists until they pick up a weapon tier. A shrinking ring +(`ringShrinkSec` 150 s, to a 3%-of-the-arena floor) forces the survivors +together, an armed victim drops a one-use gun at the death site +(`dropWeaponOnDeath`, GV46), and placements decide the results. Vision is fog-of-war: the map is always visible, but enemies only appear inside your -forward vision cone or your small omnidirectional bubble. +forward vision cone or your small omnidirectional bubble. The engine also +retains the original two-team capture-the-heart (CTF) mode; sections below +that describe teams, hearts, and captures apply to that mode, and +Battle-Royale-specific rules are called out where they differ. It is a fork of [Crewrift](https://github.com/Metta-AI/coworld-crewrift): it keeps Crewrift's continuous 2D movement, line-of-sight, sprite protocol, server, and @@ -16,6 +23,8 @@ tasks, voting) with teams, guns, hearts, and fog-of-war vision. ## Overview +The bullets below describe the legacy CTF mode. + - **16 players, 8 vs 8.** Red team spawns along the **left edge**, Blue along the **right edge**. - **Two team hearts**, one on each team's **home pedestal** inside its spawn @@ -1276,13 +1285,13 @@ This section is a build plan, not player-facing rules. image with walk/wall layers. Red/Blue spawn strips on the left/right edges, heart pedestal at center, obstacles mirrored across the vertical axis, home-edge capture zones at the leftmost/rightmost columns. -- New team-based `config.json` and `coworld_manifest_paintbot.json` (slots carry `team` +- New team-based `config.json` and `coworld_manifest_battleroyale.json` (slots carry `team` instead of `role`; results schema reports team/kills/deaths/captures). - A **baseline bot** (Crewrift's `notsus` equivalent) speaking Sprite v1. - A **CTF grader** scoring episodes from wins. **Resolved:** CTF needed team-based seating and win/loss ranking rather than -Crewrift's social-deduction scheme. This is no longer a per-game concern — both -the Ctf and Paintbot leagues run on the platform ladder service +Crewrift's social-deduction scheme. This is no longer a per-game concern — +the Battle Royale league runs on the platform ladder service (`commissioner_key=platform`), which owns seating and ranking. This repo ships the game and baseline player only; it declares no commissioner runnable. diff --git a/docs/designs/expand-replay-reporter.md b/docs/designs/expand-replay-reporter.md index 17dd2e67..c92c55d9 100644 --- a/docs/designs/expand-replay-reporter.md +++ b/docs/designs/expand-replay-reporter.md @@ -39,7 +39,7 @@ document gives the reasoning behind each. `report_output` (an empty `[]` when there are no events); a missing / unfetchable / undecodable replay, or a hash-validation failure, → `report_failed`. (§5.4) -7. **Manifest: defer + document.** Leave `coworld_manifest_paintbot.json` untouched; +7. **Manifest: defer + document.** Leave `coworld_manifest_battleroyale.json` untouched; document the intended `reporter[]` entry in the reporter README and wire it when the platform runtime and the new manifest schema land here. (§5.5) 8. **Testing: unit tests + mock WS client.** The platform reporter runtime is diff --git a/docs/designs/map-editor.md b/docs/designs/map-editor.md index a5b5398d..3ee75a7f 100644 --- a/docs/designs/map-editor.md +++ b/docs/designs/map-editor.md @@ -1,6 +1,6 @@ # Map Editor Design -A visual editor for CTF / Paintbot maps that reads and writes the existing +A visual editor for Battle Royale / CTF maps that reads and writes the existing `mapSpec` JSON format, with the Nim sim as the single source of truth for all geometry, derivation, and validation. diff --git a/flake.nix b/flake.nix index 1ee2baa9..62a44268 100644 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,5 @@ { - description = "Coworld CTF — Nim capture-the-flag game server, bots, and tooling"; + description = "Coworld Battle Royale — Nim free-for-all shooter game server, bots, and tooling"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; @@ -62,7 +62,7 @@ ''; meta = { - description = "Nim package manager used by coworld-ctf (nimby.lock)"; + description = "Nim package manager used by coworld-battle-royale (nimby.lock)"; homepage = "https://github.com/treeform/nimby"; license = pkgs.lib.licenses.mit; mainProgram = "nimby"; @@ -135,7 +135,7 @@ in { default = pkgs.mkShell { - name = "coworld-ctf"; + name = "coworld-battle-royale"; packages = [ # Nim toolchain. nixpkgs-unstable ships 2.2.10, the version the @@ -174,7 +174,7 @@ # real interactive terminal. shellHook = '' if [ -t 1 ]; then - echo "coworld-ctf dev shell — nim $(nim --version | head -1 | cut -d' ' -f4), node $(node --version), python $(python3 --version | cut -d' ' -f2)" + echo "coworld-battle-royale dev shell — nim $(nim --version | head -1 | cut -d' ' -f4), node $(node --version), python $(python3 --version | cut -d' ' -f2)" if [ ! -f nim.cfg ]; then echo echo " nim.cfg is missing — sync the pinned Nim deps first:" diff --git a/players/baseline/README.md b/players/baseline/README.md index 79299a7e..c4cba3fe 100644 --- a/players/baseline/README.md +++ b/players/baseline/README.md @@ -1,4 +1,4 @@ -# baseline — Coworld CTF bot (8v8, fog-of-war) +# baseline — Coworld Battle Royale bot (8v8/FFA, fog-of-war) A capture-the-flag reference bot that speaks the Bitworld Sprite v1 protocol. Its WebSocket disables Nagle buffering so separate input and chat messages diff --git a/tools/ladder/README.md b/tools/ladder/README.md index 2c083121..7e2edd38 100644 --- a/tools/ladder/README.md +++ b/tools/ladder/README.md @@ -1,6 +1,10 @@ # Ladder assessment tools -Judge a submitted policy on the LIVE Elo ladder. Run everything with the +Judge a submitted policy on the LIVE Elo ladder. **This tooling is +CTF-league-only** (`ctfapi.py` hardcodes the CTF league id, and the named +tenures/rounds below are CTF league history); the Battle Royale league is a +separate league, so point these scripts at it only by passing its id +explicitly. Run everything with the cogherence player's venv, which holds the working login: ```sh From 12b7292cf0aff0443bbfad2dcbe0ca84e75b972c Mon Sep 17 00:00:00 2001 From: arisklar6 Date: Tue, 8 Sep 2026 20:26:11 +0000 Subject: [PATCH 2/2] README: finiteAmmo is a dormant knob, not absent Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4638a297..9938f712 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,9 @@ logs or replay links, and the smallest repro. - **Weapon tiers are a permanent upgrade ladder.** Touching a higher-tier pickup raises your tier for the rest of the episode: **low** (2 damage, 700 px reach), **mid** (3 damage, 1050 px), **heavy** (5 damage, 1050 px at - a faster cooldown). No weapon has ammo, durability, or a magazine — the only - way to lose a gun is to die. + a faster cooldown). With the shipped config, no weapon has ammo, durability, + or a magazine (`finiteAmmo` is a dormant knob) — the only way to lose a gun + is to die. - **Drop on death (GV46).** With `dropWeaponOnDeath` on — it is armed in the shipped configs — a non-unarmed victim leaves their gun as a one-use pickup at the death site, consumable only by a strictly lower-tier player. Grenades