Files
shweet 93cdf46d5a Room and lobby chat, /host, /fashion, player-colored lines, context tips, and American spelling
- Chat goes to your room (the sandbox, or your game) by default, and to the whole lobby with /all or a leading !.
  Lines from elsewhere say where they came from ([Sandbox], [Game 2]), lobby-wide ones from your room say [All].
  Typing shows only to your room. Protocol 8.
- Hosting: everyone is told who hosts now, and the host can hand it over with /host "player".
- /fashion <item> wears a fashion locally, like /color.
- Lines that mention a player show in that player's color, looked up as they draw.
- Tips are tagged with the item and situations they fit, and those that fit are 1.5x as likely. They turn over every
  10 seconds on one continuous run, show under the menu too, and can be turned off with Tips in HUD / Gameplay. The
  HUD hotbars hide while the menu is up (except on its item tabs).
- American spelling throughout: color, center, gray, mustache, and so on.
2026-11-10 19:37:19 -05:00

3.7 KiB

Smack a Brother

1

2

3

4

Online platform fighter. Lobbies of up to 16 players, games of up to 8. Play it in the browser here.

Clarification

This application was developed with the assistance of a large language model.

Build

After cloning and entering the repository's directory, make sure to initialize the submodules:

git submodule update --init --recursive

Everything (SDL, libdatachannel, simdjson) is built statically from the submodules. The game's resources are in resources/ and get linked next to the executable.

Linux

Needs OpenSSL, plus the X11/Wayland and audio headers SDL builds against.

mkdir build
cd build
cmake ..
make

Web

Needs the Emscripten SDK.

emcmake cmake -B build-web -DCMAKE_BUILD_TYPE=Release
cmake --build build-web

This makes smack-a-brother.html, .js, .wasm and .data. Rename the .html to index.html and serve all four.

Server

The server builds on its own, without SDL. It needs OpenSSL (libssl-dev on Debian).

cmake -S server -B build-server -DCMAKE_BUILD_TYPE=Release
cmake --build build-server

Run it with:

smack-a-brother-server [port] [first UDP port] [last UDP port]

Defaults are 47800, 47810 and 47899. It only listens on 127.0.0.1, so put it behind a reverse proxy that handles TLS. For nginx:

location /smack-a-brother/ws {
    proxy_pass http://127.0.0.1:47800;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 120s;
}

Open the UDP range in the firewall (e.g. ufw allow 47810:47899/udp).

Netcode

  • The server runs every lobby: a sandbox everyone in the lobby shares, plus the games queued in it. Each is its own simulation. All of them run on one thread, at 60 ticks a second.
  • Clients send their inputs ahead of time. Each tick the server takes what has arrived (repeating a player's last inputs if they're late), steps the simulation, and sends everyone the inputs it used. Every 60 ticks it also sends a checksum.
  • Clients run the same simulation about 3 ticks ahead of the server, guessing other players' inputs. When the server's inputs differ from the guess, the client rolls back and replays.
  • The simulation is deterministic on every platform (strict floating point, own math functions), so desktop and web play together.
  • Clients connect over a WebSocket first (lobbies, chat, WebRTC signaling). Then they open a WebRTC connection to the server with two data channels: a reliable one, and an unreliable one for inputs and frames. If WebRTC can't connect, everything stays on the WebSocket.
  • STUN: stun.l.google.com:19302.
  • The server address is set in Settings. Default: wss://shweetz.net/smack-a-brother/ws.

Joining a lobby directly

  • Desktop: smack-a-brother --join CODE
  • Web: https://shweetz.net/smack-a-brother/?lobby=CODE

Environment variables

  • SAB_SERVER_URL: use a different server, e.g. ws://127.0.0.1:47800
  • SAB_NET_LAG: add this many milliseconds of lag
  • SAB_NET_LOSS: drop this percent of input packets
  • SAB_NET_STATS: log how the client is keeping up with the server

License

The game's code and art are released into the public domain under CC0 1.0. Not covered by that: the Ithaca font (SIL Open Font License, see resources/font/LICENSE.txt), the sound effects cut from the Sound Ideas libraries (see resources/sfx/SOURCES.md), and the libraries in external/, each under its own license.