Skip to content

πŸ‘½ An Among Us-themed infrared shooting gallery game built with ESP32 devices and a Node.js scoreboard

License

Notifications You must be signed in to change notification settings

statico/imposter-attack-2024

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

13 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Imposter Attack 2024

MagiQuest wand input Laser tag toy gun input
Gameplay with a wand controller Gameplay with a pistol controller

This is the code behind Imposter Attack, an infrared shooting gallery game I made for Halloween 2024 that uses battery-powered ESP32 targets and a Node.js-based scoreboard server.

Important

πŸ‘‰ Full writeup here: https://blog.langworth.com/imposter-attack πŸ‘ˆ

Warning

I didn't plan on open-sourcing this originally, so it's quite a mess and has a bunch of stuff hardcoded. Feel free to send a pull request if you want to clean it up.

Prerequisites

  • Python 3.x
  • pyenv (Python version manager)
  • Node.js v20 or newer
  • Two or more ESP32 devices
  • MicroPython firmware

devtool

This is a tool to copy dependencies and files to a MicroPython board over serial. It wraps mpremote in order to watch a directory for changes, automatically copy them to the board, and then monitor the serial port for output.

To install dependencies, run pip install -r devtool/requirements.txt.

Then run devtool.py <directory>, like devtool.py target.

scoreboard

This is the scoreboard and game server. To run it:

  • Make sure an ESP32 device running the bridge code is connected to your computer
  • Install pnpm
  • Run pnpm install
  • Run pnpm dev
  • Go to http://localhost:4000/ for the scoreboard and http://localhost:4000/admin.html for the admin interface

To add music, download the files into scoreboard/public/music/game or scoreboard/public/music/menu and add them to the gameMusicFiles or menuMusicFiles array in scoreboard/public/scoreboard.js.

const gameMusicFiles = [
  "among-us-hide-and-seek.mp3",
	...
]

const menuMusicFiles = [
  "pigstep.mp3",
	...
]

You'll need to add your own sound effects referenced in scoreboard.js since I don't have the license to distribute the ones I used. You can find sound effects on Freesound or OpenGameArt.org, or you can make some with sfxr if you like the retro sound.

Change scoreboard.js like so:

const startSound = new Howl({ src: ["/sfx/round-start.mp3"] });
const endSound = new Howl({ src: ["/sfx/victory-crew.mp3"] });
const bossAppearSound = new Howl({ src: ["/sfx/impostor-roar.mp3"] });
const bossDeathSound = new Howl({ src: ["/sfx/boss-death.mp3"] });

target

This is the code that runs on the ESP32 devices, which communicate with the bridge, which communicates with the scoreboard. Get started downloading the firmware and modifying 01_flash.sh with the path to the firmware. Then run 01_flash.sh to flash the MicroPython firmware to the ESP32, then run 02_install.sh to install the code and dependencies.

When iterating quickly, it's easiest to keep the ESP32 plugged in use devtool.py to watch the target directory for changes and automatically copy files to the ESP32.

In the field when devices aren't connected, I use uOTA to update the firmware over the wifi network. The devices don't connect to the wifi network until requested to update. This requires running a simple HTTP server (I run npx http-server -p 4444 in the webroot directory) and then running 03_update.sh to build a tarball and trigger the update. The devices will connect to the wifi network and update themselves.

Make sure to update the target/main.py file with the correct WiFi credentials:

WIFI_SSID = "mywifi"
WIFI_PASSWORD = "sekrit"

You'll also want to update target/uota.cfg with your IP address or where you're serving the webroot directory:

{
  "url": "http://192.168.0.123:4444"
  // ...
}

bridge

This is a simple bridge that receives messages from the ESP-NOW network and sends them to the serial port. It also receives messages from the serial port and sends them to the ESP-NOW network. This is how the targets communicate with scoreboard. All devices speak JSON.

You can use the 01_flash.sh command to flash the MicroPython firmware to the ESP32. Then you can use the standard mpremote command to copy main.py to the board, or use my own devtool.py command if you want to make frequent changes.

Recommended Music

I used yt-dlp to download the music from YouTube and sox to convert the Opus files to MP3 (but you could also use ffmpeg). Put these in scoreboard/public/music/game or scoreboard/public/music/menu and add them to the gameMusicFiles or menuMusicFiles array in scoreboard/public/scoreboard.js.

Game Music

Menu Music

Credits

License

Unless otherwise specified, all code is MIT licensed.


game in idle mode