# **🏃 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**. 1. **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. 2. **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`). 3. **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 a `DEATH` signal to the server, which then validates and saves the highscore. ## **🚀 Getting Started** ### **Using Docker (Recommended)** 1. **Clone the repository:** ```bash git clone [https://git.zb-server.de/ZB-Server/it232Abschied.git](https://git.zb-server.de/ZB-Server/it232Abschied.git) cd it232Abschied ``` 2. **Run:** ```bash docker-compose up --build -d ``` 3. **Play:** Open `http://localhost:8080` 4. **Admin:** Open `http://localhost:8080/admin` (User: `lehrer`, Pass: `geheim123`) ### **Local Development** 1. Start Redis: ```bash docker run -d -p 6379:6379 redis:alpine ``` 2. Start the Server: ```bash 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! 🏃💨**