sour is a complete multiplayer Sauerbraten experience in the web delivered as a single Docker image.

Related tags

Miscellaneous sour
Overview

sour

sour is a complete multiplayer Sauerbraten experience in the web delivered as a single Docker image.

Overview

I have always loved playing Sauerbraten because of its simplicity: it's fast to download, easy to pick up, and keeps you in the action with instant respawns. Despite playing lots of games over the course of my life I haven't really found anything that scratches the same itch.

Some years ago I found BananaBread, which was a basic tech demo that uses Emscripten to compile Sauerbraten for the web. The project was limited in scope and done at a time when bandwidth was a lot more precious. It also lacked multiplayer out of the box.

My goal was to ship an updated version of it in a single Docker image that I could deploy anywhere and play without forcing anyone to download the whole game. That's where sour comes in.

Getting started

All you need is Earthly to build. Just run earthly +docker and it will make the sour:latest image.

To use, the sour image, expose ports 1234 and 28785 when you run a container like this:

docker run --rm -it -p 1234:1234 -p 28785:28785 sour:latest

It's worth nothing that you can change the first mapping (1234) to whatever you want (e.g 80) but the second one has to be 28785, since the frontend expects the proxy service to be at that port.

Architecture

The current implementation involves three services, each of which corresponds to a directory in services/:

  • client/: A fork of BananaBread with lots of modifications to add support for QServCollect's protocol and the WebSocket intermediary. There are also significant UI changes.
  • server/: A fork of QServCollect, which is a dedicated Sauerbraten server.
  • proxy/: A fork of wsproxy which I changed to only allow proxying from TCP 28785 to UDP 28786. This was the quickest way I found to get client/server communication working, though presumably you could just do this in a Python script.

License

Each project that was forked into this repository has its own original license intact, though the glue code and subsequent modifications I have made are licensed according to the MIT license specified in LICENSE.

Comments
  • Add a completed bb.html build folder

    Add a completed bb.html build folder

    I have been trying to build this for the last 3 days and I just cannot get it to work, so I've given up and I was wondering if you could add a completed build?

    Thank you!

    opened by nuggetofwisdom 16
  • Heroku?

    Heroku?

    Would it be possible to host this on heroku? I wanna add it to my site because, well, Bananabread is awesome so this is too. If so, can you add the Deploy to Heroku button or just put a tutorial here?

    opened by Erisfiregamer1 8
  • Healthboost, Armor & Quad appears too early

    Healthboost, Armor & Quad appears too early

    When joining the Sour server on Sourga.me; the Healthboost, Green & Yellow Armor, and Quad Damage items appear on the screen before they are actually spawned. You can not pick them up until they spawn in game. Then will then disappear like they are supposed to when picked up.

    Tested on Sourga.me using Chromium on Linux.

    opened by kwadroke 7
  • Nginx error

    Nginx error

    ============================ ❌ FAILURE [2. Build 🔧] ============================

    Repeating the output of the command that caused the failure +image-slim failed | --> RUN apt-get update && apt-get install -y nginx +image-slim failed | Ign:1 http://archive.ubuntu.com/ubuntu groovy InRelease +image-slim failed | Ign:2 http://security.ubuntu.com/ubuntu groovy-security InRelease +image-slim failed | Ign:3 http://archive.ubuntu.com/ubuntu groovy-updates InRelease +image-slim failed | Err:4 http://security.ubuntu.com/ubuntu groovy-security Release +image-slim failed | 404 Not Found [IP: 91.189.88.142 80] +image-slim failed | Ign:5 http://archive.ubuntu.com/ubuntu groovy-backports InRelease +image-slim failed | Err:6 http://archive.ubuntu.com/ubuntu groovy Release +image-slim failed | 404 Not Found [IP: 91.189.88.142 80] +image-slim failed | Err:7 http://archive.ubuntu.com/ubuntu groovy-updates Release +image-slim failed | 404 Not Found [IP: 91.189.88.142 80] +image-slim failed | Err:8 http://archive.ubuntu.com/ubuntu groovy-backports Release +image-slim failed | 404 Not Found [IP: 91.189.88.142 80] +image-slim failed | Reading package lists... +image-slim failed | E: The repository 'http://security.ubuntu.com/ubuntu groovy-security Release' does not have a Release file. +image-slim failed | E: The repository 'http://archive.ubuntu.com/ubuntu groovy Release' does not have a Release file. +image-slim failed | E: The repository 'http://archive.ubuntu.com/ubuntu groovy-updates Release' does not have a Release file. +image-slim failed | E: The repository 'http://archive.ubuntu.com/ubuntu groovy-backports Release' does not have a Release file. +image-slim failed | Command /bin/sh -c 'apt-get update && apt-get install -y nginx' failed with exit code 100 +image-slim failed | +image-slim failed | ERROR: Command exited with non-zero code: RUN apt-get update && apt-get install -y nginx Error: build target: build main: bkClient.Build: failed to solve: process "/bin/sh -c PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /usr/bin/earth_debugger /bin/sh -c 'apt-get update && apt-get install -y nginx'" did not complete successfully: exit code: 100

    opened by ETechTechnologies 7
  • Building is broken, and where can this be hosted?

    Building is broken, and where can this be hosted?

    First off, love the project. Definitely would be cool! However, we people are poor and need to host this for free. Also, building is [BARK]ed. Where can we host and play this, and when will building be fixed??

    opened by Erisfiregamer1 5
  • Game

    Game "Locks up" almost immediately after data is loaded and game is ready to play

    While attempting to play on sourga.me. Ater the game loads and is ready to play, the game locks up. I can hit Escape to release the mouse. The browser itself is still responding, just no response in-game.

    Fedora Linux 35 Browser: Version 100.0.4896.60 (Official Build, ungoogled-chromium) (64-bit) (Also had same issue starting on 2022-04-03 on Chromum 98.x)

    From The Console:

    WebGL: INVALID_VALUE: texImage2D: invalid internalformat
    sauerbraten.js:10410 WebGL: too many errors, no more errors will be reported to the console for this context.
    _glTexImage2D @ sauerbraten.js:10410
    $createtexture(int, int, int, void*, int, int, unsigned int, unsigned int, int, int, int, bool, unsigned int, bool) @ 008b38ce:0xe1b4
    $newtexture(Texture*, char const*, ImageData&, int, bool, bool, bool, int) @ 008b38ce:0x53fef
    $textureload(char const*, int, bool, bool) @ 008b38ce:0x81c5
    $loadcaustics(bool) @ 008b38ce:0x7e38b
    $setupmaterials(int, int) @ 008b38ce:0x72295
    $allchanged5(void*) @ 008b38ce:0xf58db
    func @ sauerbraten.js:5554
    Browser_mainLoop_runner @ sauerbraten.js:4940
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    index.tsx:268 main loop blocker "allchanged5" took 612 ms
    index.tsx:268 The Complex by Dacker & Nieb
    index.tsx:268 main loop blocker "allchanged_next" took 3 ms
    unsafe-startup.js:59 glMapBufferRange is only supported when access is MAP_WRITE|INVALIDATE_BUFFER
    printErr @ unsafe-startup.js:59
    _emscripten_glMapBufferRange @ sauerbraten.js:8610
    $gle::begin(unsigned int, int) @ 008b38ce:0xcb928
    $flushwater(int, bool) @ 008b38ce:0x44b46
    $renderwater() @ 008b38ce:0x5091b
    $glaretexture::dorender() @ 008b38ce:0x145e97
    $rendertarget::render(int, int, int, float, int) @ 008b38ce:0x75a26
    $main_loop_caller() @ 008b38ce:0x13cb1d
    callUserCallback @ sauerbraten.js:4989
    runIter @ sauerbraten.js:5051
    Browser_mainLoop_runner @ sauerbraten.js:4966
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    setTimeout (async)
    Browser_mainLoop_runner @ sauerbraten.js:4954
    unsafe-startup.js:94 RuntimeError: null function or function signature mismatch
        at gle::end() (008b38ce:0x5507)
        at flushwater(int, bool) (008b38ce:0x44cc4)
        at renderwater() (008b38ce:0x5091b)
        at glaretexture::dorender() (008b38ce:0x145e97)
        at rendertarget::render(int, int, int, float, int) (008b38ce:0x75a26)
        at main_loop_caller() (008b38ce:0x13cb1d)
        at callUserCallback (sauerbraten.js:4989:3)
        at Object.runIter (sauerbraten.js:5051:4)
        at Browser_mainLoop_runner (sauerbraten.js:4966:20)
    
    opened by kwadroke 4
  • Link to here from BananaBread?

    Link to here from BananaBread?

    Really awesome stuff here!

    What do you think about linking to here from the BananaBread repo? Now and then people ask there about whether there is any news in this space.

    opened by kripken 4
  • Update README; Correct Docker Command

    Update README; Correct Docker Command

    I receive the following error when running the Docker command from the README.

    └─$ sudo docker run --rm -it -p 1234:1234 28785:28785/udp ghcr.io/cfoust/sour
    [sudo] password for christian: 
    Unable to find image '28785:28785/udp:latest' locally
    

    I received this both on my home server and Linux laptop.

    Docker version 20.10.11, build dea9396
    

    Correction is just specifying the -p flag again before the second port mapping.

    opened by gamemann 3
  • I'ts not opnening

    I'ts not opnening

    Before your latest update all i would see is the text that it show as soon as you click on the link but it would not load i even waited about an hour and no change and with your latest update it is now just a white screen is there anyway you can revert/fix the game?

    opened by ZEGERMANMAN 3
  • Unable to use mouse after browser captures it in Firefox

    Unable to use mouse after browser captures it in Firefox

    Tested on Mozilla Firefox 98 on Linux - untested on other OSes. When the browser captures the mouse when attempting to select something, the mouse moves on its own to the Top Left corner of the screen. It will continue to attempt to do this as long as the mouse is captured, making playing the game impossible.

    Tested on sourga.me.

    opened by kwadroke 1
  • Add <noscript> HTML to let users know they need to enable Javascript

    Add

    If a user visits the site with Javascript disabled in their browser (or a browser that doesn't support Javascript), the page comes up blank. This can look like the site is down.

    Please add a noscript tag line to let the user know the site is available and they need to enable Javascript for the site/game to work.

    Example:

    ...</script>
       <noscript>Please enable Javascript to play Sour</noscript>
      </body>
    
    opened by kwadroke 1
Owner
Caleb Foust
I'm a vim addict, AMA
Caleb Foust
Photon OS DPDK and Packet Generator, RT Test, TF2 docker image.

photongen Photon OS DPDK and packet generator , cyclictest , TF2 with CUDA docker image. DPKD libs The build proccess builds and installs all shared l

spyroot 5 Sep 13, 2022
A simple Z-Machine implementation in a single C file. Now with online multiplayer! :)

This is an implementation of Infocom's Z-Machine. The Z-Machine is a virtual machine that's something like a high-level CPU. To keep their games portable and easier to write, Infocom's games all use this fake processor and ship with a platform-specific Z-Machine "emulator" ... so a game could run wherever someone had implemented the Z-Machine.

Ryan C. Gordon 92 Dec 28, 2022
runing qemu in Docker by BOA

myQemu runing qemu in Docker by BOA It currently only supports mipsel configuration, other architectures have not been added yet, please wait for subs

null 20 Nov 9, 2022
Running Docker container on Raspberry Pi (armhf)

Running Docker container on Raspberry Pi (armhf)

null 1 Nov 8, 2022
Dockerfile/docker-compose Elasticsearch with plugins elasticsearch-analysis-vietnamese and coccoc-tokenizer

docker-es-cococ-tokenizer Dockerfile/docker-compose Elasticsearch with plugins elasticsearch-analysis-vietnamese and coccoc-tokenizer Deployment docke

Nguyễn Nhật Minh Tú 7 Nov 8, 2022
Northstar-dedicated - Docker container for the Northstar dedicated server. Also includes general notes on running the dedi on Linux. WIP.

northstar-dedicated Docker image for the Northstar dedicated server. Not ready yet (it'll probably be another day or two). Versioning Tentative. Stabl

null 83 Jan 6, 2023
CVE-2021-4034 POC and Docker and Analysis write up

CVE-2021-4034 POC and Docker and Analysis write up

breeze 9 Oct 22, 2022
A repository containing our learnings and implementations for the project "Anchor: The Docker Clone" under IEEE-NITK

Anchor: The Docker Clone A repository containing our learnings and implementations for the project "Anchor: The Docker Clone" under IEEE-NITK Currentl

Rakshita Varadarajan 1 Feb 7, 2022
CVE-2021-3156 POC and Docker and Analysis write up

CVE-2021-3156 [toc] 漏洞简介 漏洞编号: CVE-2021-3156 漏洞产品: sudo 影响版本: 1.8.2-1.8.31sp12; 1.9.0-1.9.5sp1 利用后果: 本地提权 源码获取: https://www.sudo.ws/getting/source/ 环境

breeze 1 Oct 22, 2022
CVE-2022-0185 POC and Docker and Analysis write up

CVE-2022-0185 linux 内核提权(逃逸) [toc] 漏洞简介 漏洞编号: CVE-2022-0185 漏洞评分: 漏洞产品: linux kernel - fsconfig syscall 影响范围: linux kernel 5.1-rc1 ~ 5.16.2 利用条件: linu

breeze 25 Dec 4, 2022
Gamemode roleplay de Hyaxe para San Andreas Multiplayer.

Hyaxe Roleplay Gamemode roleplay de Hyaxe para San Andreas Multiplayer Colaboradores Gracias a las siguientes personas que han colaborado programando

Yahir Vlatko Kozel 7 Apr 15, 2022
🎮 Plants vs. Zombies multiplayer battle, developed via reverse engineering, inline hook and dynamic-link library injection. Two online players defend and attack as the plant side and zombie side respectively.

Plants vs. Zombies Online Battle This project has two original repositories: https://github.com/czs108/Plants-vs.-Zombies-Online-Battle https://github

Liugw 71 Oct 14, 2021
Tomb Raider III multiplayer modification.

Tomb Raider III Multiplayer Mod. Multiplayer Modification for Tomb Raider III. Website: https://tr3mp.net/ If you own the base source of \patch projec

Tony 3 Dec 25, 2021
A port of the FNF Sonic.EXE mod to PS1. (Sunky and Multiplayer Update)

PSXFunkin VS Sonic.EXE on the PS1 ooga booga hes gonna getcha Compilation Refer to COMPILE.md here Disclaimer This project is not endorsed by the orig

Lord Scout 3 Sep 29, 2021
Quake Enhanced Capture the Flag multiplayer mod

QECTF Quake Enhanced Capture the Flag multiplayer mod What is it? This is a multiplayer deathmatch mod for Quake Enhanced that adds basic capture the

null 4 Jun 21, 2022
Experimental Worms Armageddon WormKit module that implements real-time online multiplayer for racing schemes

wkRealTime v.0.0.4d Experimental Worms Armageddon WormKit module that implements real-time online multiplayer for racing schemes. Installation Place w

null 15 Jul 12, 2022
Multiplayer tic-tac-toe game using Arduino board and XBee module

Arduino Tic-Tac-Toe This project is implementation of tic-tac-teo game on Arduino board. This game is multi-player and must be run on two seperated bo

Mahdi Rezaie 5 Sep 20, 2022
A recreation of Among Us, but as a multiplayer text adventure

Among FOSS A recreation of Among Us, but as a multiplayer text adventure instead of a graphical client. Building Dependencies json-c ➔ Parsing and sen

f1nniboy 5 Sep 8, 2022
An operating system. Its main goal? Readable code, developer experience and documentation.

OS Dependencies Required for development. sudo apt install build-essential nasm grub-pc-bin grub-common xorriso Required for building cross-compiler.

Stijn Rogiest 1 Nov 15, 2022