Breach
A multiplayer cyber-defence lab where the server, not the players, decides what happened.
- Context
- BuildingBloCS Game Jam, team of four
- My part
- Ideation and game design, the in-game lab guide, part of the pitch deck, and code
- Stack
- Python, Pygame, asyncio, WebSockets, OpenAI
- Year
- 2026

The problem
The CSIT brief asked for a game that teaches Python basics, binary exploitation (pwn) and reverse engineering. For a beginner these arrive as three unrelated subjects with no fixed route through them, and a quiz teaches the words without giving anyone a reason to care about them.
We were four Applied AI students with almost no cybersecurity background, five days, and by the second day no working idea. Whatever we built had to make those three topics matter under pressure, stay fair with several people on the same network, and still work on stage when the Wi-Fi or an API did not.
How it works
Three or more players join one lab. Each picks a specialty no one else holds, readies up and votes on difficulty; the server breaks ties at random, then secretly makes one player the attacker. Nobody else is told who it is. The round lasts 200 seconds.
- Three systemsData Center runs on Python basics, Network Core on pwn, Power Grid on reverse engineering. Each starts at 50% health, the baseline the round is judged against.
- DefendersWalk up to a system and solve its repair question: +10 health, +5 more when the question matches their specialty. A wrong answer locks them out of that system for 30 seconds.
- The attackerSolves attack questions on the same systems for Attack Points, then spends them: BLACKOUT (1) darkens a defender’s screen for 10 seconds, FALSE_ALERT (2) drops a healthy system to critical, MALWARE_INJECTION (3) takes 15 health plus any banked specialty bonus.
- The clockAt zero, the lab’s average health against the 50% baseline decides it: held or recovered, defenders win; net damage, the attacker does. Every system at 100%, or every system at 0%, ends it early.
- Learning loopEvery answer comes back with the correct answer, a one-line lesson, an explanation and where it matters in real security work. A cheatsheet and a tabbed lab guide open mid-round; the end screen pages through strengths, weak topics and each missed question beside the right answer.
Lobby

Attack

The server
One asyncio WebSocket server owns every rule. Clients send intents (move, interact, submit, use ability) and draw what comes back, 20 times a second.
- Per-player stateEach client gets its own view: its own role, points and cooldowns, and nobody else’s role until the round is over. The attacker stays hidden in the traffic too.
- Validated actionsMovement is clamped per message and collides server-side. Range, cooldowns and system health are checked when a challenge opens and again when it is answered, so a player cannot open a question and walk off, or answer into a system that has since locked them out or been finished.
- Answers stay homeA challenge goes out without its answer and is bound to the player who opened it. The server checks the submission against that session and only then reveals the answer and the lesson.
- Pure rulesHealth, status, scoring and the win check live in a separate pure module, with unit tests for clamping, baseline scoring and both early endings.
Decisions
Judge the round on lab health, not a flag
The first playable version was a flag hunt: restored systems gave up fragments, and all three unlocked a Core Server where defenders typed the final flag. It turned the round into one yes-or-no moment at the very end. We cut it for a 50% baseline and a 200-second clock, so every answer on either side moves the same number and a round can be close.
Attackers learn the same topics from the other side
An attacker who only pressed a sabotage button would learn nothing. Attack questions cover the same system from the offensive angle (which Python mistake leaks a token, which pwntools helper packs an address) and earn points rather than damage, so every ability is paid for in the same skills the defenders are repairing with.
The model prepares the next question; it never makes a player wait
Every challenge opens instantly on a locally generated, randomised question. In the background, OpenAI writes the next one to a strict JSON schema, aimed at the concept that player just missed or, after two right answers, at a new one. Output with the wrong option count, an out-of-range answer index or a multi-word short answer is dropped. With no key, a timeout or bad output, the game simply keeps using local questions.
One specialty each, and a bonus for using it
Specialties are unique per lobby and add +5 on their own system, for either side. It nudges a team to spread across the three topics instead of crowding the easiest one, and gives each beginner one area to get good at first.
Teach inside the round, review after it
A lesson after every answer, a cheatsheet and a lab guide during play, and a per-question report at the end. I wrote the guide: tabs for the overview, both roles and the controls, with each system’s live health, so a new player can learn the round without leaving it.
Results
1st
Place in the CSIT Category, BuildingBloCS Game Jam 2026
3
Topics from the CSIT brief, each a system both sides fight over
0
Challenges that wait on the model: every one opens on a local question
A game-jam result, not a study: we never measured whether players learned more than they would from a quiz. The demo broke midway through the week, and on the day our video failed to load; the judge told us to keep going. The build that won is a single-server LAN game with 9 passing unit tests on its rules and question shape.
Limits
- No playtest data or learning-outcome measure; the teaching value is a design claim.
- Model-written questions are checked for shape, not for correctness; a wrong answer key would slip through.
- One in-memory server, one round at a time, LAN only, no authentication: any client can reset the lab.
- The hidden attacker has no counterplay yet: defenders cannot accuse or vote anyone out.

