Private
Public Access
1
0
Files
it232Abschied/README.md
Sebastian Unterschütz a05e79f0d1
All checks were successful
Dynamic Branch Deploy / build-and-deploy (push) Successful in 2m27s
add hot Chunk reload
2025-11-30 12:33:04 +01:00

5.8 KiB

🏃 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

  1. 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
    
  2. Run:

    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:
    docker run -d -p 6379:6379 redis:alpine
    
  2. 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

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! 🏃💨