Skip to content

A Scala 3 fullstack project featuring real-time multiplayer games. An exercise in building a comprehensive stack for professional Scala development

Notifications You must be signed in to change notification settings

epic-64/cascade

Repository files navigation

Cascade

Coverage Lines of Code Scala Sbt Scala.js Cask

Full-stack web application using Scala 3, Scala.js, Cask, and WebSockets.

Live Environments

Features

Counter App with Real-Time Sync

  • Simple shared counter that syncs across all browser tabs
  • Click to increment or decrement
  • Watch updates appear instantly everywhere
  • Demonstrates real-time WebSocket synchronization

Color Rush - Multiplayer Game

  • Fast-paced color matching challenge
  • Compete against other players in real-time
  • 10 rounds with speed bonuses
  • Live scoreboard updates as you play

AI Drawing Challenge - Multiplayer Game

  • Draw prompts and let AI caption your artwork
  • OpenAI Vision API analyzes drawings
  • AI judge picks the best match with witty commentary
  • Players vote for their favorite drawing
  • Real-time lobby system with WebSocket sync
  • Bring your own OpenAI API key

Quick Start

Terminal 1 - Transpile client (watch mode):

sbt ~"js/fastLinkJS"

Terminal 2 - Start server:

sbt "jvm/run"

Browser:

http://localhost:8080

Open multiple tabs and watch them sync!

Commands

Compile:

sbt compile

Clean compile:

sbt clean compile

Run tests:

sbt "jvm/test"

Start server:

sbt "jvm/run"

Transpile client (dev):

sbt "js/fastLinkJS"

Transpile client (watch):

sbt ~"js/fastLinkJS"

Transpile client (production):

sbt "js/fullLinkJS"

Generate coverage report:

ENABLE_COVERAGE=true sbt clean coverage test coverageReport

Count lines of code:

./scripts/count-loc.sh

Endpoints

Landing Page:

  • GET / → Landing page with overview of available apps

Counter Demo:

  • GET /counter → Counter app (HTML client)
  • GET /api/counter → Get counter value (JSON)
  • POST /api/counter/increment → Increment counter
  • POST /api/counter/decrement → Decrement counter
  • WS /ws/counter → WebSocket for real-time updates

Color Rush Game:

  • GET /color-rush → Color Rush game client
  • WS /ws/color-rush/:gameId → Game WebSocket endpoint

AI Drawing Challenge:

  • GET /drawing → AI Drawing Challenge game client
  • WS /ws/drawing/:lobbyId → Lobby WebSocket endpoint

Static Assets:

  • GET /static/* → Static files (HTML, CSS, JS)
    • /static/js/main.js → Compiled Scala.js (includes all apps)
    • /static/index.html, /static/counter.html, /static/color-rush.html, /static/drawing-game.html → HTML files
    • /static/base.css, /static/counter.css, /static/color-rush.css, /static/drawing-game.css → Stylesheets

System:

  • GET /health → Server health and statistics (JSON)
    • Status, uptime, memory usage, system info

Project Goals

Stack:

  • ✅ Scala 3 for both server and client
  • ✅ Cask for lightweight server framework
  • ✅ Scala.js for client-side code sharing
  • ✅ WebSockets for real-time communication
  • ✅ Cache-busting system for static assets
    • ✅ currently solved via client-side hack (manually append server version as query param on static asset URLs)
    • ⏳ build proper solution with hashed filenames and manifest mapping
  • ⏳ Database persistence, ORM (PostgreSQL + Doobie?)
  • ⏳ DB migration system (Flyway, Liquibase?)
  • ⏳ Cache across instances / across restarts (Redis?)
  • ⏳ Internationalization (German, English)

Testing:

  • ✅ ScalaTest
    • ✅ jvm: works out of the box
    • ✅ js: requires jsdom plugin
    • ✅ cross-project setup to cross-compile shared sources
  • ✅ isolated endpoint tests (BDD)
    • ✅ full endpoint traversal (requests.get(path)) with coverage
    • ✅ support for mocking side effects
  • ✅ WebSocket tests
  • ⏳ e2e tests
    • ⏳ Selenium, Cypress, Katalon? To be decided.
    • ⏳ CI integration (headless)

Continuous Integration:

  • ✅ CI pipeline running tests
  • ✅ Test coverage report (sbt-scoverage)
    • ❌ unfortunately, ScalaJS is not supported by scoverage, so we cover only the jvm target
  • ✅ Lines of Code tracking (auto-generated on each CI run)
  • ✅ Cloud deployment (railway), deploy on push
    • main → staging environment
    • production → production environment

Monitoring:

  • ✅ health endpoint
  • ⏳ endpoint for inspecting number of active games and websockets (with age)
  • ⏳ Exception tracing (Sentry, Datadog, BetterStack?)
  • ⏳ Log aggregation (Logstash, Datadog, BetterStack?)
  • ⏳ Health and Performance monitoring

Known Issues / Todos

  • Missing tests for Drawing game

Previous Challenges

  • ✅ WebSocket closes on its own after some time of inactivity (1-2 minutes)
    • fixed by implementing a heartbeat mechanism: client sends ping every N seconds
  • ✅ WebSocket connection is lost on page refresh
    • fixed by storing player id in localStorage and rejoining the game/lobby on page load if player id is found

Documentation

  • Health Endpoint - Detailed documentation of the /health endpoint and its stats
  • Game Cleanup - Documentation of automatic game/lobby cleanup mechanisms

About

A Scala 3 fullstack project featuring real-time multiplayer games. An exercise in building a comprehensive stack for professional Scala development

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •