claudeandClaude Opus 5 7b710471df Make the arenas' cover actually stop bullets
The player's muzzle was fixed last commit; every enemy and boss emitter
has one too, and theirs reach further. A ring sits 46px out, an arc
sweep's outer arms sit past 100px, and a wall-gap curtain spans the whole
arena -- most of a curtain is nowhere near the thing that fired it. The
pool samples geometry once per tick and never sees the jump, so all of
those were spawning bullets on the far side of whatever stood between.

That matters here more than it sounds, because both boss arenas are
authored out of cover. The hall has pillars; the vault has barricades,
and its own comment says they are there so that knowing where the Cantor
is does not hand you a firing lane to it. A barricade blocks bullets and
deliberately does NOT block sight -- so it is exactly the cover this bug
cancelled. Measured before fixing: the Warden's curtain put 13 shots
through a one-tile wall and its arc sweep 13 more; the Cantor's curtain,
16.

Two checks, not one. The path test skips its own starting tile so a
shooter in a doorway still resolves, and that skip let a telegraphed
burst whose centre and ring sit inside one wall tile through -- born in
the wall, announced to every client, dead on the next tick. The
destination is now asked separately, so a bullet never exists inside
geometry.

A telegraphed strike passes its own marker as the source rather than the
boss: that burst is born where the player was warned, and a pillar
between the boss and the spot has nothing to say about it. A strike
marked on cover is now simply a dud, which is cover working; pinned by a
test so it stays a known shape.

First attempt at this used a turret behind a barricade and proved
nothing -- a turret's 24px offset cannot clear its own 16px radius plus a
32px tile, so the test could not have failed. Replaced with the two
emitters that can reach, plus both real arenas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 17:24:34 +02:00
2026-09-03 16:03:57 +02:00
2026-09-03 16:03:57 +02:00
2026-09-07 16:20:10 +02:00
2026-09-03 16:03:57 +02:00
2026-09-07 16:20:10 +02:00
2026-09-03 16:03:57 +02:00
2026-09-07 16:20:10 +02:00

Transcience

Top-down twin-stick bullet-hell with a dedicated, server-authoritative backend. Godot 4.7, GDScript, no external runtime dependencies.

Play

tools/server.sh                      # dedicated server on :27015
tools/client.sh --join --name ada    # connect a client

Or run one client and press Host and play for a listen server.

Controls — WASD move, mouse aim, LMB fire, E to pick up loot and to use the hub's portals and quartermaster, 1–4 use an inventory slot, shift+1–4 drop one, hold F for one second to escape a dungeon, Esc menu, F1 hitbox overlay. Every one of those is rebindable in Settings.

What is here

Twin-stick bullet hell Server-simulated bullet field, ~300 concurrent bullets at 0.28 ms/tick — around 60x headroom against the 60 Hz budget.
Authoritative multiplayer Clients send input and nothing else. Hits, damage, death, loot, upgrades and instance transfers are all server decisions. Prediction and reconciliation for the local player.
Enemies Five readable movements (static, drift, orbit, approach, strafe) composed with bullet emitters. Nothing deals contact damage; every threat is a bullet you can see.
Two bosses The Warden of the Fold stands still through four phases. The Cantor of the Vault walks a circuit, chases, orbits, and marks the floor before it strikes. Both are pure data.
Three dungeons Two real runs, one per boss, plus a Proving Grounds: the same content at a fraction of the health and ten times the drop rate, for testing by hand.
Characters Up to five living per account, permadeath, levels 1–15, experience shared across the party undivided.
Inventory and loot Four slots, always on screen. Loot is either world-shared or instanced per player, and the instanced kind is filtered on the wire rather than hidden in the client.
Upgrades Seven, drawn three at a time and spent at a hub NPC. Damage, fire rate, extra projectiles, splitting, poison, and a legendary that deletes enemy bullets.
Emergency escape A one-second channel back to the hub that damage does not interrupt — because if it did, quitting the process would be the better escape. Dropping your connection runs the same channel.
Settings Rebindable controls and volumes, and an in-game credits screen.

Develop

tools/check.sh    # parse-check every script          ~5s
tools/test.sh     # 468 GUT tests, headless           ~4s
tools/smoke.sh    # server + 4 bot clients over ENet  ~40s

Read CLAUDE.md first — it is short, and the Godot CLI gotchas in it will otherwise cost an afternoon.

Docs

Not ready for the internet

LocalAuthProvider lets any client claim any account id. It exists to have the same shape as Steamworks so swapping is one class, and it must be replaced before this is reachable from anywhere untrusted. There is no transport encryption either. See docs/ROADMAP.md.

S
Description
No description provided
Readme
2.4 MiB
0 Stars 1 Watchers 0 Forks
Languages
GDScript 98.6%
Shell 1.2%
Python 0.2%