Documentation

Docs

How Capo City is built, what the numbers actually are, and how to run your own copy. For the player-facing guide see How to play.

Overview

Capo City is a real-time isometric city rendered on a single HTML canvas. The whole game — renderer, pathfinding, economy, UI — lives in one self-contained file, city.html, with no build step and no runtime dependencies. It works offline and from a file:// URL.

Economy reference

Every tunable number in one place.

ConstantValueNote
Starting CASH500Fresh save
Numbers route130 base · 6.5s · +4 heatPavement markers
Dock work190 base · 8.5s · +7 heatWaterfront strip
Level bonus+12% per levelMultiplies base pay
Payout variance×0.85 – ×1.25Uniform random
Daily cap25,000 CASHResets at local midnight
XP per job28Plus 6 $CAPO points
Heat decay0.22 / second≈13 per minute
Safehouse cooling7 / secondPlus loyalty top-up
Detectives spawnheat ≥ 70Payouts halved at the same threshold
Detectives leaveheat < 35
Shakedown10% of CASH, max 600Resets heat to 38
Need drain0.055 / secondAll five needs, ≈30 min from full to empty
Station refill9 / secondWhile standing in the block
Level curve0, 300, 800, 1600, 2800, 4600, 7200, 11000, 16500, 24000, 34000XP thresholds

City generation

The city is deterministic: the turf name is hashed (FNV-1a) into a seed for a mulberry32 PRNG, so the same turf always produces the same city on every device.

Seasons and the pot

A season runs 7 days from launch. The pot splits across the top ten by rank weight (11 − rank)^1.45, normalised — so rank 1 takes roughly a quarter of the pot and rank 10 takes a few percent.

Until a live trading-leaderboard feed is wired up, the board and pot are simulated from the turf seed. The sidebar shows a DEMO SEASON badge whenever that is the case, and the city never presents simulated figures as live data.

Token

FieldValue
Ticker$CAPO
ChainSolana
Venuepump.fun — standard bonding curve
Launch12 August, 5:00 PM UTC
PresaleNone
Team allocationNone
ContractSOON

There is exactly one contract address and it does not exist before 12 August, 5:00 PM UTC. It will appear on this site and in the pinned post on X at the same moment. Any address circulating before then is a scam.

Architecture

frontend/                 static, deploy anywhere
  index.html              landing page
  how-to-play.html        player guide
  docs.html               this page
  city.html               the game (self-contained, no build)
  js/config.js            single source of truth: name, launch, CA, API URL
  js/site.js              nav, countdown, CA copy
  js/api.js               backend client — no-ops when API_URL is empty
  css/site.css            shared site styles
  assets/                 wordmark, badge, banner, OG, favicons

backend/                  optional — the city runs fully without it
  src/server.js           Express + WebSocket, server-authoritative payouts
  supabase/schema.sql     tables, indexes and row level security
  Dockerfile              Railway deploy target

The frontend degrades cleanly. With API_URL empty the city is single-player: local save, simulated leaderboard, local wire. Set API_URL and the same build switches on live chat, presence, a shared leaderboard and server-checked payouts — no code changes.

Backend setup

1. Supabase

Create a project, open the SQL editor and run backend/supabase/schema.sql. It creates the tables, indexes and row level security policies. Copy the project URL, the anon key and the service role key.

2. Railway

Point Railway at backend/. It builds from the Dockerfile. Set these variables:

SUPABASE_URL=https://xxxx.supabase.co
SUPABASE_SERVICE_KEY=eyJ...        # service role — server only, never ship to the browser
ALLOWED_ORIGINS=https://capocity.fun,https://www.capocity.fun
PORT=8080

The service role key bypasses row level security. It belongs only in Railway's environment. The browser gets the anon key, and only if you use Supabase directly from the client.

3. Point the frontend at it

Set API_URL in frontend/js/config.js to your Railway URL and redeploy the frontend. That is the whole switch-over.

API reference

MethodPathDoes
GET/healthLiveness probe.
POST/api/sessionCreates or resumes a player by client id, returns their state.
GET/api/leaderboard?turf=Top ten for a turf, with pot and cuts.
POST/api/job/startOpens a server-side job window. Returns a job id.
POST/api/job/claimClaims a finished job. The server checks elapsed time, the daily cap and heat before paying.
POST/api/market/buyBuys an item. Checks balance and remaining supply in one transaction.
GET/api/chat?turf=Last 50 messages on a turf.
WS/ws?turf=Live chat, presence and player positions for a turf.

Payouts are never trusted from the client. /api/job/start records a server timestamp and /api/job/claim refuses anything that comes back faster than the job's real duration, or that would push the player past the daily cap.

Run it yourself

# frontend — any static server
cd frontend
python3 -m http.server 4173

# backend — optional
cd backend
cp .env.example .env      # fill in your Supabase keys
npm install
npm run dev

The frontend has no build step, so whatever is in frontend/ is exactly what ships. Deploy it to Vercel, Netlify, Cloudflare Pages, GitHub Pages or an S3 bucket — set the output directory to frontend and there is nothing else to configure.

Launch checklist

  1. Frontend deployed to capocity.fun, DNS pointed, HTTPS live.
  2. Open Graph images resolving — check with the X card validator before the day.
  3. X and Telegram bios pointing at capocity.fun.
  4. Mint on pump.fun at 5:00 PM UTC on 12 August.
  5. Paste the address into CA in js/config.js and upload that one file. Every page loads it with a timestamp, so it is picked up immediately — no cache purge needed.
  6. Pin the CA post on X. Confirm the site and the pinned post match, character for character.

Capo City is a browser game and a memecoin. It is not an investment product, it is not a security, and nothing on this site is financial advice.

In-game CASH, XP and $CAPO points exist only inside the game. They have no monetary value, they are not tradeable, and they are not redeemable for the token or anything else.

Leaderboard figures, PnL and pot values shown while the DEMO SEASON badge is visible are simulated and do not describe any real trader or any real money.

Crypto assets are volatile and you can lose everything you put in. Only ever risk what you are happy to lose, and always verify the contract address against the pinned post on X before you buy.

Enter the city