1
0
Fork
You've already forked tess-joust
2
No description
  • C 74.9%
  • HTML 10.3%
  • Shell 10.2%
  • Meson 3%
  • Nix 1.6%
2026年06月22日 20:15:43 -04:00
frontend Show number of adapters that are rfkilled 2026年06月06日 19:33:21 -07:00
mock_psmoveapi Fixes for clang 2025年09月07日 12:03:37 -07:00
src Seed RNG at startup instead of at game start 2026年06月22日 20:15:15 -04:00
.envrc Add shell.nix for building. normal stuff works. yay 2025年06月02日 20:44:22 -04:00
.gitignore Add config file support 2025年06月04日 10:21:37 -04:00
default.nix Add shell.nix for building. normal stuff works. yay 2025年06月02日 20:44:22 -04:00
hardware.md Update docs 2025年08月14日 10:07:57 -07:00
install_service.sh I'm dumb 2024年10月12日 10:48:07 -07:00
LICENSE.txt Initial commit 2024年06月06日 04:11:42 -07:00
manual_pairing.md Fix paths in docs 2026年05月29日 18:03:20 -07:00
meson.build Bump from tcstd (old name) to latest cleat 2026年05月29日 17:40:23 -07:00
meson_options.txt Add ability to use mock psmoveapi 2025年06月18日 00:31:40 -04:00
psmoveapi.nix Add shell.nix for building. normal stuff works. yay 2025年06月02日 20:44:22 -04:00
raspi_setup.md Update raspi_setup.md 2026年06月17日 19:09:02 -04:00
README.md Document players_per_team config option 2025年09月07日 13:10:08 -07:00
setup.sh Show number of adapters that are rfkilled 2026年06月06日 19:33:21 -07:00
shell.nix Add shell.nix for building. normal stuff works. yay 2025年06月02日 20:44:22 -04:00
tess-joust.service Add config file support 2025年06月04日 10:21:37 -04:00
todo.md Add todo 2026年06月22日 20:15:43 -04:00
valgrind_run.sh Clean up valgrind artifacts 2026年05月30日 20:50:13 -07:00

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.