SlopScore
00 crowd

claude-of-legends

A mini 5v5 MOBA in the browser: one deterministic TypeScript sim, an authoritative server, and every bot behind a trainable Policy contract.
Open repo on GitHub Open the demogithub.com/killian01/claude-of-legends
TypeScript · ★ 1 · 1 forks · MIT · paperwork by the Cap'mmostly ai (inferred)light human (inferred)works-on-my-machine (inferred)game
listed 48 minutes ago by killian01 · last checked 48 minutes ago
The owner didn't write this. This repo never submitted itself. The Cap'm found it on a truffle trawl and wrote its paperwork from what GitHub already shows. Picked by hand by the Cap'm on 2026-09-28: A mini 5v5 MOBA in the browser: one deterministic TypeScript sim, an authoritative server, and every bot behin; its own README says "The whole game was vibe coded with Claude in a 48 hour sprint, then polished in the open; the commit history is the real build log, kept int". 1 stars; MIT license. The owner did not submit this. Votes count; awards don't until the owner claims it.

I'm not calling your project slop! Geeze, it's a joke... Do you own this repo?

Log in with GitHub as killian01. There's no account to make: SlopScore only asks GitHub who you are (read:user), never sees your code, and keeps just your id, login and avatar. Then you can:

  • Keep it, on your terms. Commit your own slopscore.md (spec) and press Refresh. Your paperwork replaces the Cap'm's, and you can submit it for Slop of the Day.
  • Take it down. One click on Remove. It stays gone; the trawl never brings it back.

Log in with GitHub

Can't log in as the owner? Request a takedown. No login needed, and a trawled listing comes down right away.

GitHub says
A mini 5v5 MOBA in the browser: one deterministic TypeScript sim, an authoritative server, and every bot behind a trainable Policy contract.
website
https://claudeoflegends.com
topics
browser-gamedeterministicgamemobamultiplayerreinforcement-learningthreejstypescriptwebsockets
created
2026-08-26 · pushed 53 minutes ago · 541 commits · 4 contributors
languages
TypeScript 89%JavaScript 8%Python 2%Shell 0%HTML 0%Dockerfile 0%
paperwork
code of conductcode of conduct filecontributingpull request templatelicensereadme 100% health
dependencies
✓ 152 deps, none with known advisories · OSV.dev, checked 49 minutes ago

Disclosures, inferred by the Cap'm

slopbucket
vibe-coded
category
game
ai_generated
mostly
human_touch
light
status
works-on-my-machine
language (detected)
dockerfilehtmljavascriptpythonshelltypescript
topic (detected)
browser-gamedeterministicgamemobamultiplayerreinforcement-learningthreejstypescriptwebsockets
license (detected)
mit

The Cap'm's log

The Cap'm wrote this paperwork, not the owner. This repo never submitted itself to SlopScore. The Cap'm picked it by hand: A mini 5v5 MOBA in the browser: one deterministic TypeScript sim, an authoritative server, and every bot behin; its own README says "The whole game was vibe coded with Claude in a 48 hour sprint, then polished in the open; the commit history is the real build log, kept int". It carries the MIT license. The disclosures above are his best guess from what GitHub shows.

Is this yours? Commit a real slopscore.md and press Refresh to replace this, or remove the listing in one click. There's no account to make: you log in with GitHub.

README — the repo's own words, folded up so the grading fits on one screen
Claude of Legends

A 5v5 MOBA born in a 48 hour vibe coding sprint: three lanes, ten champions, free in your browser right now.

Play now: https://claudeoflegends.com/

CI TypeScript Three.js Vite Vitest License: MIT Version PRs welcome Discord

Play now · Discord · Quick start · How to play · Train a bot · Make a champion · Contributing

Want to build something here? The eleventh champion is one new file and three table entries: docs/adding-a-champion.md. A smarter bot is a playbook, no engine code at all. Small and self-contained: good first issue.

A fight on the plaza of the Star Orchard, where the mid lane crosses

What this is

A complete mini MOBA you can play right now: three lanes, ten champions with full kits, jungle camps, three neutral creatures to fight over, fog of war, items, skins, a ladder, a Forge where you build a champion of your own, and an authoritative server for online play. No install. Online play needs a free account; the practice match against bots does not. An account is a name and a password, or one click on Continue with Discord: that button creates an account from a Discord identity and signs it back in (ADR 0009).

The whole game was vibe coded with Claude in a 48 hour sprint, then polished in the open; the commit history is the real build log, kept intact. It runs on the architecture proven by world-of-claudecraft: one deterministic TypeScript simulation core that runs identically in the browser, on the server, and headless, with every non-human participant driven by a single Policy abstraction.

Home screen

How it was built

The first commit is dated 26 August 2026. A playable 5v5 came out of the first 48 hours (docs/plan-48h.md); the table below is where eleven days in the open left it, written one commit at a time by one maintainer and Claude Code in a terminal.

Commits 380
TypeScript, tests excluded 66,489 lines
Tests 1,229 cases in 167 files, 23,330 lines
Decisions written down 18 ADRs in docs/adr/
Champions 10, every one with a full kit

Counted on 6 September 2026; the repository is the current version.

The last two rows are the ones that matter. The test suite is larger than the simulation core it covers, 23,330 lines against 14,892, and every decision that could have gone another way has a page in docs/adr/ saying what was chosen and what was given up for it. That is not a tax on the speed. A model writes code fast enough that the bottleneck moves to knowing whether the code is right, so the tests and the decision records are what the speed gets spent on.

Three constraints did the rest of the work. The simulation is deterministic on a fixed 20 Hz tick with every random number drawn from a seeded Rng, so a bug is a seed and a replay instead of a story (tests/determinism.test.ts). That same core runs in the browser, on the server and headless, with no second implementation to drift out of step (ADR 0001). And every non-human participant, from a lane bot to a playbook someone trained in the Academy, is the one Policy interface, so the bots never became a subsystem nobody dared touch (ADR 0002).

The commit history is the real build log and it has been kept intact. To see what adding to it looks like, docs/adding-a-champion.md walks a champion from empty file to champion select.

Quick start

Node 22 or newer and pnpm. nvm use picks the right one from .nvmrc; 22 is not a preference, the server's stores are built on node:sqlite.

pnpm install
pnpm dev

Open http://localhost:5173 and pick "Play offline now": a full 5v5 against bots, no server needed.

For online play, run the server in a second terminal:

pnpm server        # authoritative server on :8787
pnpm dev           # client; /ws is proxied to the server

Then "Play online" to queue (empty seats fill with bots on request), or "Create private lobby" and share the 5-letter code with friends.

Every match is played on the Star Orchard, the authored Blender map: practice, ranked, lobbies and the bots' Arena alike. See the map.

How to play

  • Right-click: move or attack. A: attack-move. S: stop and hold. B: recall.
  • Q W E R: abilities, cast at the cursor (hold for the range preview). Level them with Alt+key or by clicking the plus.
  • D F: sigils (picked in champion select). P: shop. Tab: scoreboard.
  • Enter: chat. G: ping. Esc: menu. Space recenters; screen edges pan.
  • Push a lane, take towers, and destroy the enemy Sanctum to win. The Pyrefang and the Voidmaul rise on the two corner rings from 4:00 and hand whoever slays them a permanent favor and gold for the whole team; the Warden, from 12:00, grants the bigger, temporary Boon, at the plaza first and then at a pit drawn among the forests' rooms, told when it rises; late in the match each ring's creature returns as its Ascendant, a body for a full team whose death hands the Wrath. The forests hold three kinds of camp, and every house team fields a jungler to clear them.
  • Or field a bot instead of playing by hand (docs/design/bots.md). In the Academy (the Bots tile on the home, or its bar) write its playbook by talking to the coach or editing the plays, spar it against house bots in seconds, then queue with it and coach it live: right-click sends it somewhere, right-click on an enemy focuses it, the coach bar carries Warden, Ring, back, group, hold and free. Deposit it in the Arena and read the Briefing in the morning. Three ladders rank the three ways to play: by hand, your bot live, your bot in the Arena.

Every bot is a Policy: train one

Every non-human participant is a deterministic function (observation, rng) -> action behind one versioned contract (src/sim/policy.ts, ADR 0002). The observation is team vision, never global state, and the decision budget that rate-limits actions applies identically to humans and bots (ADR 0003): a bot cannot out-click a person, only out-think one.

That makes the game a reinforcement learning environment as much as a MOBA:

  • pnpm env runs a full match headless over NDJSON on stdio, one step per decision slot, so a trainer outside the repo can drive any seat (headless/README.md).
  • Every house bot, the Laner and the three styles beside it, is a playbook (src/sim/content/playbooks/, ADR 0013): an ordered list of plays run by the interpreter in src/sim/playbook/, the same one every account's bot runs. A new trigger or behavior there is a contribution every bot on the server can use the next morning; a smarter default playbook is a self-contained, well-tested pull request.
  • A parity test pins that a policy attached in-sim and driven remotely produces the identical world.

Community bots, scripted or trained, are the flagship contribution this project is built around. The other one is a champion.

Make a champion, in the game or in the repo

Two ways, and they share nothing but the engine underneath.

In the game: the Forge. Name it, paint its splash from a prompt, and write the kit: a passive and four abilities, composed from the same primitives the roster is built out of, inside a power budget a deterministic validator enforces. Nothing a player writes ever runs as code in the sim, because a forged champion is data on the same engine as the ten (ADR 0010). From the splash you approved, the Forge derives the model reference, builds the 3D body and its weapon, and then rigs and animates it on a second, deliberate click, so you see the model before paying for the motion. Yours plays in the Forge queue, mixed with roster champions, on that queue's own rating. Everything the server pays a provider for is priced in embers, from a weekly allowance that rolls over, and any job that fails refunds exactly what it took (ADR 0017).

In the repo: a pull request. One new file, src/sim/content/champions/<id>.ts, three table entries and two tests to edit. No engine work, no server work, and no art at all, which is the part nobody believes:

  • The body is a model you point at, not one you make. public/models/champions/ ships two rigged CC0 characters no champion uses yet, knight.glb and goblin.glb, and any champion's model is fair game too.
  • The ability icons are optional. With none, the procedural painter draws all four from the spec, which is what five of the forty icons in the game are right now.
  • The splash art is optional. With none, champion select shows the in-engine cinematic render of the model instead: the chain in src/ui/champion_art.ts resolves the painted illustration first, then that render, then the instant procedural figure under both.

So a kit with no assets lands complete and sits on the screen looking like the rest of the roster. The art is a later pull request, yours or someone else's. docs/adding-a-champion.md walks the whole path, and it was written by doing it.

Production

One process, one port: the server serves the built client and the WebSocket. Locally:

pnpm start         # builds client + server, then runs on :8787

With Docker:

docker build -t claude-of-legends .
docker run -p 8787:8787 -v loc-data:/app/data claude-of-legends

On a public host the game runs behind a proxy that owns TLS and the public ports. docker-compose.yml at the repo root is that deployment: the container publishes no port, and the front proxy reaches it over a shared Docker network.

docker compose up -d --build

The full runbook (the proxy contract, verification, updates, backups, sizing) is docs/deploy.md.

PORT overrides the listen port, for the server and for the dev client's proxy alike, so two checkouts run side by side with one line in each .env. Player identities and the match log live as JSON files under data/ (DATA_DIR overrides the location); mount it as a volume or careers reset with the container.

TLS termination (for wss) belongs to whatever proxy sits in front, and the proxy has to be declared, or the server counts every player as one machine:

TRUST_PROXY=1      # how many proxies sit in front (0, the default: none)
ALLOWED_ORIGINS=   # pages allowed to open a socket besides the one we serve

TRUST_PROXY is a hop count, not a switch: with 1, the address the nearest proxy saw is the player, which is what the per-machine socket limit counts and what X-Forwarded-Host is read from. The proxy must overwrite X-Forwarded-For and X-Real-IP rather than append to what the client sent, or a player can pick their own bucket. Leave the count at 0 when the port faces the internet directly, or a forged header buys an attacker any address it likes.

The client is served by this same process, so a page from the host in the request is always allowed and ALLOWED_ORIGINS stays empty for a normal deploy. Name origins in it (comma separated) only when the client is also served from somewhere else; * turns the check off.

Development

  • pnpm test (Vitest, includes structural gates), pnpm check (strict tsc), pnpm lint (Biome).
  • Repo map and invariants: CLAUDE.md. Domain glossary: CONTEXT.md. Decisions: docs/adr/. Design: docs/design/. Deferred work: docs/roadmap.md and docs/review/.
  • Dev-only pages: /dev_champions.html (champion visual gallery, with ?portraits and ?focus=<id> modes) and /vfx.html (spell VFX).

Come say hello on Discord: that is where players find each other for a game, and where a kit or a bot gets talked through before it becomes a pull request.

Contributions are welcome: CONTRIBUTING.md has the setup and the pull request checklist. Issues labeled good first issue are the best entry points. Security issues go through SECURITY.md, privately, never a public issue.

The site loads nothing from anyone else's server, sets one cookie (your session), and counts its audience with an open source counter running on its own machine, so that a quiet launch can be told apart from a front page that loses people. PRIVACY.md is the whole of it, and it points at the file behind each claim so you can check rather than believe.

All project content, in the game and in the docs, is in English, with original fantasy naming only (no borrowed IP, see docs/adr/0004-original-naming-no-borrowed-ip.md).

License: MIT for the code (LICENSE). Art and model assets are covered by CREDITS.md (CC0 packs by KayKit and Quaternius, plus the three.js basis transcoder).

Read the rest on GitHub

Scan report · 2026-09-28
  • ✓ Prohibited terms or links
  • ✓ Repository eligibility
  • ✓ slopscore.md paperwork
  • ✓ Content policy
  • ✓ Risk review

0 comments

log in to comment.

report this listing — log in to report