Skip to content

kimgoetzke/mooplas

Repository files navigation

Randolf

This repository contains a basic multiplayer game inspired by Achtung, die Kurve!, written in Rust using Bevy Engine (v0.18) and Avian Physics. The goal of the project was to explore network programming when real-time movement is involved.

⬆️ Play the local multiplayer build on itch.io. A signalling server for the online multiplayer build is not currently deployed.

Features

  • Implementation of Achtung, die Kurve! (also known as Curve Fever)
  • Local multiplayer (up to 5 players)
  • Online multiplayer (up to 8 players)
  • Native and browser-friendly online multiplayer (plus a standalone signalling server)
  • You can mix and match local and online players in the same game
  • Touch controls for mobile devices
  • Cross-platform (Linux, Windows, WebAssembly)

Networking overview

  • Two compile-time backends, selected via Cargo feature flags:
    • online_renet — native only; UDP transport via bevy_renet with a netcode protocol
    • online_matchbox — native and WASM; WebRTC data channels via bevy_matchbox, required for browser builds
  • Both backends use a client-server topology: one instance acts as host, all others connect as clients
  • Wire data is serialised with postcard and sent over three channels: Unreliable, ReliableUnordered, and ReliableOrdered
  • The matchbox backend brokers initial WebRTC connections through a WebSocket signalling server (mooplas_signalling_server, see README); ICE uses Google's public STUN (stun.l.google.com:19302)
  • The WASM implementation supports room joining: the host generates an 8-character room ID and shares it with clients; clients enter it in the join menu to connect
  • SIGNALLING_SERVER_URL is baked in at build time (defaults to ws://localhost:3536); for native development the signalling server starts embedded in the host process

Demo

Online multiplayer:

Demo GIF

Lobby with touch controls enabled:

Screenshots 2

In-game:

Screenshots 3

How to develop

Using Nix Flakes, JetBrains RustRover & Direnv

You can run this project in any way you like, but I have set things up to make it easy to develop using JetBrains RustRover. For this, you'll need:

This way, you'll just need to direnv allow in the project directory after which all prerequisites (incl. Rust, Cargo, all Bevy dependencies, etc.) will be available to you. The JetBrains plugin will ensure that the environment is available to your IDE and you can run the project from there (vs cargo build and cargo run in the terminal).

How to deal with RustRover making problems again

RustRover will always fail to sync the project when you open it because it doesn't wait for direnv. Just re-sync immediately after the failure and it will work.

Did RustRover forget where the Rust standard library is again? Run the below and update the path in the settings:

find /nix/store -type d -name rust_lib_src
Running out of disk space?

cargo sweep is your friend and comes with the Flake. For example, the below will delete all build artefacts that are older than 7 days:

cargo sweep -t 7

To clean everything except for the latest build:

cargo sweep --stamp

<Insert any number of cargo build, cargo test, etc. commands>

cargo sweep --file
Using the Nix flake

Upgrade the flake by running nix flake update --flake . in the repository's base directory.

How to build WASM for the web

Note

Browser builds intended for online multiplayer should use the Matchbox backend (--features online_matchbox) and a reachable signalling server URL.

Prerequisites

  1. Run (already included in the Flake if using Nix):
    rustup target add wasm32-unknown-unknown
  2. Set RUSTFLAGS environment variable:
    1. Linux:
      export RUSTFLAGS="--cfg=web_sys_unstable_apis --cfg=getrandom_backend=\"wasm_js\""
    2. Windows:
      $env:RUSTFLAGS="--cfg=web_sys_unstable_apis --cfg=getrandom_backend=`"wasm_js`""
  3. Set SIGNALLING_SERVER_URL when building for production. If omitted, the build falls back to ws://localhost:3536, which is useful for native/local development but not for deployed HTTPS browser builds.
    1. Linux:
      export SIGNALLING_SERVER_URL="wss://signal.example.com"
    2. Windows:
      $env:SIGNALLING_SERVER_URL="wss://signal.example.com"
  4. Make sure you have Node.js with serve installed

Building

Then you can build the WASM file:

  1. Build the WASM file:
    SIGNALLING_SERVER_URL='ws://localhost:3536' RUSTFLAGS='--cfg=web_sys_unstable_apis --cfg=getrandom_backend="wasm_js"' cargo build --target wasm32-unknown-unknown --release --manifest-path mooplas_game/Cargo.toml --package mooplas_game --bin mooplas_game --no-default-features --features online_matchbox
    For local development builds you can omit SIGNALLING_SERVER_URL and the game will use ws://localhost:3536.
  2. Clean the /www/public directory and copy the game's assets over:
    • Linux:
      ./scripts/clean-mooplas-files.sh
      ./scripts/copy-assets.sh
    • Windows:
      ./scripts/clean-wasm-files.ps1
      ./scripts/copy-assets.ps1
  3. Run wasm-bindgen to generate the JS bindings and move all relevant files to the /www/public directory:
    1. Linux:
      wasm-bindgen --out-dir ./www/public --target web ./target/wasm32-unknown-unknown/release/mooplas_game.wasm
    2. Windows:
      wasm-bindgen.exe --out-dir ./www/public --target web ./target/wasm32-unknown-unknown/release/mooplas_game.wasm
  4. Zip the WASM file if needed (e.g. for itch.io):
    zip -r mooplas.zip ./www/public

Optimising

You can optimise the WASM file (from the Unofficial Bevy Cheat Book):

# Optimize for size (z profile).
wasm-opt -Oz -o output.wasm input.wasm

# Optimize for size (s profile).
wasm-opt -Os -o output.wasm input.wasm

# Optimize for speed.
wasm-opt -O3 -o output.wasm input.wasm

# Optimize for both size and speed.
wasm-opt -O -ol 100 -s 100 -o output.wasm input.wasm

Running

Finally, to run the game in your browser locally, run the below and paste the URL copied to your clipboard into your browser:

npx serve ./www/public

About

A sort of online multiplayer implementation of Achtung, die Kurve! in Bevy.

Topics

Resources

License

Stars

Watchers

Forks

Contributors