Skip to content

feat: Bridge & CTF games, player SDK, docs site, game tests, tournament game_type#73

Merged
DIodide merged 5 commits intostagingfrom
feat/game-test-harness
Mar 18, 2026
Merged

feat: Bridge & CTF games, player SDK, docs site, game tests, tournament game_type#73
DIodide merged 5 commits intostagingfrom
feat/game-test-harness

Conversation

@DIodide
Copy link
Member

@DIodide DIodide commented Mar 14, 2026

Summary

Major platform update adding two new game types, a player-facing SDK, documentation site, comprehensive game tests, arena building infrastructure, and tournament game type support.

New Game Types

  • Bridge (1v1) — Two platforms over void, build across and enter enemy goal zone. First to 5 wins, 5-min time limit with sudden death
  • CTF (4v4) — Flag pickup/carry/drop/capture/return mechanics on a 50x50 arena. 5-second respawn, 30-second disconnect grace period. First to 3 captures wins, 8-min time limit

Beacon Plugin Rearchitecture

  • Split MatchPollingService (744→393 lines) into MatchInitializer, MatchWorldManager, and focused polling
  • Removed all legacy fallback code from MatchPollingService and MatchEventListener
  • Wired EntityDamageByEntityEvent through BaseGame.handleDamage()
  • Added SchematicLoader for WorldEdit .schem file loading (with programmatic fallback when WorldEdit not installed)
  • Fixed match lifecycle: disconnects during countdown now properly trigger forfeit
  • Fixed CTF both-teams-disconnect hanging forever — now terminates match
  • Added winner_team_id resolution in MatchManager.endMatch() for reliable Convex updates
  • Bumped Java compiler target to 17 (required by Paper 1.20.6+)

Player SDK (@blockwarriors/sdk)

  • Strategy pattern API wrapping BotClient — players implement onSpawn, onTick, onDeath, onDamage, onChat
  • Starter bot template with single-bot and multi-bot launchers
  • New bot-client package extracted from bot-orchestrator

Documentation Site (/docs)

  • 10-page docs site at /docs with sidebar navigation
  • Getting started guide, Bot API reference, game rules (PvP, Bridge, CTF), tournaments, FAQ
  • Added "Docs" link to landing page navbar

Game Tests (packages/game-tests)

  • 4 test scenarios, all passing deterministically:
    • pvp-1v1 (37s) — Blue attacks, red forfeits → blue wins
    • bridge-1v1 (49s) — Blue plays, red forfeits → blue wins
    • ctf-4v4 (102s) — 8 bots spawn, red team forfeits → blue wins
    • tournament-flow (24s) — Creates tournament with game_type, verifies bridge/CTF token counts
  • Forfeit-based patterns ensure tests never stall on timeout
  • Process-level error handler for bot keepalive timeouts

Tournament Game Type Support

  • Added game_type field to tournaments schema
  • createTournament accepts gameType parameter (pvp, bridge, ctf)
  • createTournamentGame resolves matchType: "auto" from tournament's game_type
  • Game Type selector added to tournament creation UI
  • Fixed hardcoded 'pvp' in tournament match detail page and HTTP endpoint
  • Added winner_team_id direct support in match update API

Arena Building Infrastructure

  • WorldEdit 7.4.0 dependency (provided scope) with SchematicLoader utility
  • BaseGame.loadArena() — schematic-first with programmatic fallback
  • softdepend: [WorldEdit, FastAsyncWorldEdit] in plugin.yml
  • Graceful NoClassDefFoundError handling when WorldEdit not installed
  • Improved programmatic arenas for all 3 game types

Config Changes

  • CTF changed from 5v5 to 4v4 (tokensPerTeam: 4)
  • Bot keepalive timeout increased to 180s (from 60s)
  • CTF arena reduced from 80x80 to 50x50 with staggered player teleports

Test Plan

  • npm run test:game — all 4 scenarios pass (pvp-1v1, bridge-1v1, ctf-4v4, tournament-flow)
  • mvn clean package — Java BUILD SUCCESS
  • npx tsc --noEmit -p packages/game-tests/tsconfig.json — TypeScript clean
  • npm run deploy:beacon — deploys and server restarts successfully
  • Convex codegen + deploy — schema changes applied
  • Manual: verify /docs pages render correctly on web
  • Manual: create a tournament with game_type=bridge via UI

🤖 Generated with Claude Code

DIodide and others added 5 commits March 13, 2026 02:56
…Beacon plugin

Phase 0 — Beacon rearchitecture:
- Split MatchPollingService (744→393 lines) into MatchInitializer, MatchWorldManager
- Remove all legacy fallback code from MatchPollingService and MatchEventListener
- Wire EntityDamageByEntityEvent through BaseGame.handleDamage()

Phase 0.5 — Public /docs route:
- Add 10-page docs site at /docs with sidebar navigation
- Covers getting started, bot API reference, game rules (PvP, Bridge, CTF),
  tournaments, and FAQ
- Add "Docs" link to landing page navbar

Phase 1 — Player SDK:
- Create @blockwarriors/sdk with Strategy pattern API wrapping BotClient
- Add starter-bot template with single-bot and multi-bot launchers
- Create bot-client and game-tests packages

Phase 2 — Bridge game (1v1):
- Two platforms over void, build across, score by entering enemy goal zone
- First to 5 wins, 5-minute time limit with sudden death

Phase 3 — CTF game (4v4):
- Flag pickup/carry/drop/capture/return mechanics
- 80x80 arena with team bases and mid-field cover
- 5-second respawn, 30-second disconnect grace period
- First to 3 captures wins, 8-minute time limit
- Update CTF config from 5v5 to 4v4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…x match lifecycle

Game tests:
- Add forfeit-based test scenarios for PvP, Bridge, CTF (deterministic, <60s each)
- Add tournament flow test verifying game_type propagation and token counts
- Add process-level error handler for bot keepalive timeouts
- All 4 tests pass: pvp-1v1 (37s), bridge-1v1 (49s), ctf-4v4 (102s), tournament-flow (24s)

Arena building:
- Add WorldEdit 7.4.0 dependency (provided scope) with SchematicLoader utility
- BaseGame.loadArena() tries schematic first, falls back to programmatic generation
- Catch NoClassDefFoundError when WorldEdit not installed on server
- Improve Bridge arena (checkerboard floor, goal arches, pillars)
- Reduce CTF arena from 80x80 to 50x50 with staggered player teleports
- Add simple PvP arena platform at y=64

Tournament flow:
- Add game_type field to tournaments schema
- createTournament accepts gameType parameter (pvp, bridge, ctf)
- createTournamentGame resolves "auto" matchType from tournament's game_type
- Add Game Type selector to tournament creation UI
- Fix hardcoded 'pvp' in tournament match detail page
- Add winner_team_id support to match update API

Match lifecycle fixes:
- Fix match never finishing: Convex HTTP handler was passing undefined fields
- Fix disconnect during countdown ignored: use hasEnded() instead of isActive()
- Fix CTF both-teams-disconnect hanging forever: terminate match
- Store team IDs on MatchManager for winner team resolution
- Increase bot keepalive timeout to 180s

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixes CI lint failure: 'CodeBlock' is defined but never used.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use explicit typed object instead of Record<string, unknown> to satisfy
Convex mutation type constraints while still excluding undefined fields.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tead)

The node CI job doesn't have Java installed, so mvn test fails.
The beacon CI job already runs the full Maven build with tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@DIodide
Copy link
Member Author

DIodide commented Mar 18, 2026

Self-Review

All CI checks pass (node, beacon, GitGuardian). Merging to staging.

Verified:

  • All 4 game tests pass deterministically: pvp-1v1 (37s), bridge-1v1 (49s), ctf-4v4 (102s), tournament-flow (24s)
  • Maven BUILD SUCCESS with WorldEdit 7.4.0 (provided scope, graceful fallback)
  • TypeScript clean, ESLint clean
  • Beacon deploys and restarts on dev server
  • Convex schema changes applied

Key decisions:

  • Forfeit-based tests ensure deterministic completion without timeout stalls
  • CTF arena 50x50 (down from 80x80) to avoid tick lag with 8 bots on dev server
  • WorldEdit softdepend with NoClassDefFoundError catch — no crash without WorldEdit
  • Tournament game_type defaults to "pvp" for backward compatibility
  • Removed Maven test from validate (beacon CI job already covers it with Java)

Note for @DIodide: Please verify the 2 manual items before promoting to main:

  1. /docs pages render correctly on web
  2. Tournament creation UI game type selector works

@DIodide DIodide merged commit 42dc1d6 into staging Mar 18, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant