- C 74.9%
- HTML 10.3%
- Shell 10.2%
- Meson 3%
- Nix 1.6%
Tess Joust
Yet another version of the Raspberry Pi/PS Move controller game
About
Joust is a game played outside with motion controllers. The aim is to knock other players out by making their controllers shake without getting knocked out yourself. Each round tends to last a couple minutes. It looks like this.
There are several implementations:
Tess Joust is an implementation that aims to be simple, reliable and (relatively) easy to deploy. The UX is mostly copied from Jonty's Oust.
It's built from scratch in C, and as far as I know it's the only implementation that uses an up-to-date version of the psmoveapi library (at time of writing).
See hardware.md for discussion and links to the hardware you need to buy to run a game.
See raspi_setup.md for instructions on setting up a Raspberry Pi to run the game.
Setup
The first step is to run setup.sh. Clones dependencies into deps and builds the project. It can be re-run if anything gets wonky, and must be run if you pull/checkout a commit with different dependency versions. If setup.sh succeeds ./build/tess-joust should exist and be runnable. If it fails install dependencies or make tweaks and run it again. See ./setup.sh --help for more info.
To develop on an OS that has trouble building the psmoveapi library you can use ./setup.sh --mock-psmoveapi. Currently the mock implementation always has 0 controllers, so it's usefulness is limited.
If you want to autostart tess-joust on computer startup (useful if you're running on a machine without a screen/input), run ./install_service.sh as root. You can later run ./install_service.sh --uninstall to stop, disable and uninstall it.
tess-joust is mostly tested running as root. It should (?) work as a normal user if you disable automatic controller pairing.
If systemctl stop bluetooth does not actually stop the bluetooth service it's likely because it's being automatically reactivated by the desktop environment. You can disable --now it, or remove /etc/systemd/system/dbus-org.bluez.service (unclear what negative side-effects this may have).
Pairing controllers
Controllers should be automatically paired if plugged in while tess-joust is running and a game is not active. Pairing a controller turns off and on bluetooth, which disconnects all other controllers. tess-joust intelligently distributes new controllers to the currently active bluetooth adapter with the least number paired (since each adapter has a cap around 6 or 7). To unpair all controllers and start over use the web interface to "set" any value for "unpair_all". For more advanced manually pairing see manual_pairing.md.
Connecting controllers
Controllers can connect over Bluetooth even when tess-joust isn't running. To turn the controller on press the PS button (the circular inset button on the front of the controller) and wait for the small LED at the bottom to remain solid. It may sometimes connect but still blink if the battery is low.
Disconnecting controllers
You can turn a controller off by holding the PS button for a number of seconds. All controllers will also eventually turn off if the computer is off or it's Bluetooth is disabled.
You can disconnect and turn off all controllers with systemctl restart bluetooth, pressing the PS button on each one will have it reconnect.
You can make controllers inactive (so they don't effect the game) without disconnecting them. See Deactivating controllers.
Configuration
Configuration can optionally be set with a joust.config file in the project directory. Each line of the file should be a KEY=val pair except for empty lines and # comments. The configuration options are:
| Option | Description |
|---|---|
| server_addr | If set, a configuration web server is launched on this IP/port. Should generally be 0.0.0.0:80 for production, or 1.0.0.127:80 for development. Port 8080 can be used instead of 80 if you're not running as root |
| excess_g_limit | Controller sensitivity. Specifically number Gs above 1G to allow controllers to move before they die. Should generally be 0.5-1 |
| players_per_team | Number of players on each team, generally 1 or 2, defaults to 1 |
| automatic_pairing | Set to 0 to disable automatic pairing, this may help run as non-root (untested) |
Gameplay
The game is designed to be quite easy to pick up, but there are a number of features for game management and debugging.
Flow
Controllers start off dead. When the game is over, all players must press trigger to mark their controllers as ready. The game then starts and controllers turn blue. If a controller moves too fast, it turns read and that player is considered dead. When only one player is left their controller turns green and they win that round.
States
A controller can be in any of the following states:
| Color | State | Description | Actions |
|---|---|---|---|
| Blue | Alive | The controller is still alive in an active game | When it is close to the acceleration threshold it rumbles and flashes white. When it passes it it moves to the dead state. When only one controller is still alive it moves to the win state |
| Red | Dead | The controller accelerated too much and is now dead | It will still rumble when it accelerates above the threshold again (this allows people to practice after they've been knocked out). Once the game is over the trigger brings the controller into the ready state |
| Dim white | Ready | The controller is ready to join the next game | When all controllers are either inactive or ready, a game starts and the ready controllers become alive |
| Dim Orange | Inactive | The controller is on and connected, but not active in the current game and will not be active in future games | The trigger brings the controller into the ready state, so it will join future games |
Deactivating controllers
If you press move (the big ovel button) and select (the button on the left side) at the same time, the controller enters the inactive state reguardless of what state it was in previously. It's impossible for an inactive controller to join the current game, but if you press trigger it enters the ready state and will join the next game. This allows you to change the number of players on the fly.
Chacking battery
Holding the circle button makes the controller change color to reflect it's current battery level. Red is very low, green is good, in between is in between. Unfortunately, the battery levels the controllers expose are not very granular.