🏃 Escape the Teacher
A high-performance, server-authoritative 2D endless runner built with Go, Redis, and WebSockets.
📖 About the Project
"Escape the Teacher" is a web game developed as a school project. You play as a student caught cheating, running away from an angry teacher. The game features increasing difficulty, power-ups, boss phases, and a competitive global leaderboard.
Unlike typical browser games, this project implements competitive multiplayer architecture usually found in games like Agar.io or FPS titles. The browser is just a "dumb" terminal; the server simulates the entire world.
✨ Features
🎮 Gameplay
- Endless Progression: The game speeds up over time.
- Controls:
- Jump: Space / Arrow Up / Tap / Left Click.
- Crouch: Arrow Down / Swipe Down (Mobile).
- Power-Ups:
- 🛡️ Godmode: Survives 3 hits.
- ⚾ Baseball Bat: Eliminates the next teacher obstacle.
- 👟 Jumpboots: Grants higher jumping power.
- 💰 Coins: Bonus points.
- Level Editor: Custom chunks (platforms, enemies) can be designed in a secure Admin UI and are streamed into the game live.
- Juice: Particle effects and retro sound system.
🛡️ Security & Admin
- Server-Authoritative: Physics runs on the server. Cheating (speedhack, godmode) is impossible.
- Admin Panel: Create levels, manage badwords, and moderate the leaderboard.
- Proof System: Players receive an 8-character "Claim Code" to prove their high score offline.
🏗️ Technical Architecture
We moved from a traditional HTTP-Request model to a Realtime Streaming Architecture.
- Backend (Go):
- Runs the physics simulation at a fixed 20 TPS (Ticks Per Second).
- Generates level segments ("Chunks") 5 seconds into the future.
- Streams object positions via WebSockets to the client.
- Frontend (JS):
- Client-Side Prediction: Inputs are applied immediately for zero-latency feel.
- Buffering: Incoming server data is buffered and played back smoothly.
- Interpolation: Although physics runs at 20 FPS, the game renders at 60+ FPS by interpolating positions (
lerp).
- Database (Redis):
- Stores active sessions, highscores, and custom level chunks.
Tech Stack
- Backend: Go (Golang) 1.22+ (
gorilla/websocket) - Frontend: Vanilla JavaScript (Canvas API)
- Database: Redis
- Containerization: Docker (Multi-Stage Build)
- Orchestration: Kubernetes
🔧 Engineering Challenges & Solutions
1. The "Netflix" Approach (Streaming vs. RNG)
- Problem: Syncing Random Number Generators (RNG) between Client and Server caused "Butterfly Effects" where one wrong number broke the whole game state.
- Solution: Streaming. The client no longer generates anything. The server generates objects in the future and streams them into a buffer on the client. The client simply plays back what it receives.
2. Lag Compensation & RTT
- Problem: If the internet lags, the server's objects appear too late on the client, causing "Ghost Kills".
- Solution: RTT (Round Trip Time) Measurement. The client constantly measures the Ping. Incoming objects are visually shifted based on latency (
Latency * Speed), so they appear exactly where they are on the server.
3. Low Tick-Rate & Interpolation
- Problem: To save server CPU, we run physics at only 20 TPS. This usually looks choppy (like a slideshow).
- Solution: Linear Interpolation. The rendering loop runs at 60/144 FPS and calculates the visual position between two physics ticks. The game looks buttery smooth despite low server load.
4. "Instant" Death
- Problem: Waiting for the server to confirm "You died" feels laggy.
- Solution: Optimistic Client Death. The client detects collisions locally and stops the game visually (
Game Over). It sends aDEATHsignal to the server, which then validates and saves the highscore.
🚀 Getting Started
Using Docker (Recommended)
-
Clone the repository:
git clone [https://git.zb-server.de/ZB-Server/it232Abschied.git](https://git.zb-server.de/ZB-Server/it232Abschied.git) cd it232Abschied -
Run:
docker-compose up --build -d -
Play: Open
http://localhost:8080 -
Admin: Open
http://localhost:8080/admin(User:lehrer, Pass:geheim123)
Local Development
- Start Redis:
docker run -d -p 6379:6379 redis:alpine - Start the Server:
go run .
📂 Project Structure
.
├── k8s/ \# Kubernetes manifests
├── static/ \# Frontend files
│ ├── assets/ \# Images & Audio
│ ├── js/ \# Game Engine
│ │ ├── audio.js \# Sound Manager
│ │ ├── logic.js \# Physics & Buffer Logic
│ │ ├── render.js \# Drawing & Interpolation
│ │ ├── network.js \# WebSocket & RTT Sync
│ │ └── ...
│ ├── index.html \# Entry Point
│ └── style.css \# Styling
├── secure/ \# Protected Admin Files (Editor)
├── main.go \# HTTP Routes & Setup
├── websocket.go \# Game Loop & Streaming Logic
├── simulation.go \# Physics Core
├── types.go \# Data Structures
└── Dockerfile \# Multi-Stage Build
📜 Legal
This is a non-commercial educational project.
- Privacy: No tracking cookies.
- Assets: Font "Press Start 2P" hosted locally. Sounds generated via bfxr.net.
Run for your grade! 🏃💨