> SYS_INIT v2.2 // PROJECT DETAIL

Resident Evil Escape Game

A twelve-module escape game in one case: ESP32 puzzle stations talking over MQTT, a fifteen-minute timer and a touch console for the game master.

PROJECT: RELEASED PUBLISHED: 2025-08-11 UPDATED: 2026-08-02 VERSION: 1.1.3
White cube-shaped console with an Umbrella Corporation logo on the front, a row of twelve blue indicator LEDs in a metal strip, a top panel of switches, a keypad and a key switch, and a monitor mounted above it

Project overview

The Resident Evil Escape Game packs a complete escape room into a single white case. One or two players have fifteen minutes to neutralise the virus, working through a chain of puzzles spread across the panels on the lid — a polarisation test, a contamination control panel, a cable matrix, a genetic colour sequence, a mutation panel and a security protocol, ending at the key switch.

Behind those panels sit twelve independent modules. Each runs its own ESP32 with a fixed address on the game network and talks to a Raspberry Pi acting as MQTT broker. Nothing is wired module to module, which is what allows a game to be set up, torn down and transported as one object rather than a room.

The game has run at two company events and at Maker Faire Hannover 2025, and a revised version goes to Maker Faire 2026.

Everything created for this project — firmware, board designs and the printed parts — is published under the PolyForm Noncommercial License. The project has no commercial background and is not for sale. Resident Evil, the Umbrella Corporation and all associated names and logos are the property of Capcom; this is a fan-made exhibition piece and none of those elements are covered by the project licence.

Electronics and control

Every module is the same idea repeated: an ESP32 with a fixed IP, subscribed to its own command topic under umbrella/, plus the shared umbrella/ping. Three of the boards were designed specifically for this build — a switch carrier, an RFID carrier and a relay carrier — all sharing one ESP32-S3 footprint so the bring-up procedure is identical across them.

Panel Module Address Key part
Polarisationstest Magnet Riddle .17
Kontaminations-Kontrollpanel Keypad .14 PCF8574 at 0x20
Kabelmatrix Bridged Riddle .15
Genetische Farbsequenz Colour Riddle .11 MFRC522
Mutationspanel Switch Riddle .10
Sicherheitsprotokoll RFID Reader .16 MFRC522
Final key switch Cerberus .12
LCD Display .13 LCD 20 x 4 at 0x27
Status LEDs, twelve front indicators .18
Relay Board .19
Gimmick Board, the two front tubes .20 2 x 48 WS2812B, FastLED
Game Master Console Waveshare ESP32-S3 Touch AMOLED 2.41

Power for the whole installation comes from an ATX PC supply. With twelve controllers, two LED tubes, four electronic locks and a Raspberry Pi in one enclosure, the separate 12 V, 5 V and 3.3 V rails and the current available on each are worth more than the space a purpose-built supply would have saved.

Audio does not come out of the modules at all. The Raspberry Pi output runs through an HDMI splitter that separates picture from sound: the picture goes to the monitor above the case, the sound goes to an amplifier and a speaker at the rear. Keeping the soundtrack on the media player rather than on a module means video and audio can never drift apart.

Two modules own shared state rather than just reporting their own. Cerberus publishes the active puzzle variant as a retained message on umbrella/riddle/master, and the LCD module owns the countdown and publishes it retained on umbrella/timer/state. Any module that reboots picks both up from the broker on reconnect instead of waiting for the next broadcast.

The two translucent tubes flanking the front are driven by the gimmick board and visualise the virus and the antivirus as the game progresses. They were originally meant to hang off the status LED module together with the front indicators; the power supply would not carry both, so the tubes moved to a board of their own. The unused path is still present in the status module.

The twelve indicator LEDs on the front of the case serve two different purposes depending on when you look at them. Before a run they are a readiness display — they confirm that every module is online, which is the check that matters when the case has just been carried into a hall and switched on. During the game the same row shows how far the players have got.

Mechanical construction

All panels are 3D printed in Qidi ASA on a Qidi X-Max 3, and that is a deliberate choice rather than a compromise. Drawing a row of evenly spaced holes in CAD and letting the printer place them is more reliable than marking and drilling them by hand, and the panels are full of switch, socket and display cutouts that all have to line up with each other. ASA also takes the handling a public installation gets better than PLA would.

The printed panels are sprayed in gloss white and the lettering is cut vinyl applied over the paint.

The case is a white cube with aluminium corner profiles, translucent tubes at the front corners and a metal strip carrying the indicator LEDs. A monitor mounts above the lid for the player-facing display.

The rear of the case carries the service connections: an HDMI socket and a USB socket for the monitor, and an RJ45 socket wired straight to the Raspberry Pi. That last one matters more than it looks — it means the broker and the media player can be reached with a laptop and a patch cable at an event, without opening a case that has twelve modules wired into it.

Software

Each module runs Arduino firmware on the ESP32 with PubSubClient for MQTT and Arduino_JSON for the command payloads. Commands arrive as JSON on a per-module topic, so the same message format works for a keypad, a relay board and a display without a shared protocol layer.

The GitLab repository has a CI/CD stage that scrambles the puzzle solutions on the way into the published version. That is what makes it possible to open the source at all: the architecture, the MQTT structure and the module firmware are readable, while the answers a player would need are not the ones in the public tree.

Larger buffers are allocated in PSRAM rather than on the heap, and the modules run a custom partition table with a single large application partition.

The Raspberry Pi runs a Python daemon that is broker, media player and watchdog at once. It loops an idle video on the monitor until a game starts, then plays a briefing chosen by the active puzzle variant, followed by a clip for each phase and for each of the two bad endings. Volume is a game master command and is written to disk atomically — temporary file, fsync, then rename — so a power cut cannot leave a corrupt setting behind. A separate thread pings every ten seconds and marks any module that has been silent for thirty seconds as offline, which is what feeds the readiness display on the front.

Lessons learned

Retained messages are what make a twelve-node game survivable. A module that loses power or crashes mid-run has to come back knowing which puzzle variant is active and how much time is left. Publishing both as retained MQTT messages means recovery is automatic and silent — the alternative is a module that rejoins in the wrong state, which on a show floor is indistinguishable from a broken puzzle.

Check the power budget before assigning peripherals to a module. The two front tubes and the twelve indicators were meant to share one controller. The supply could not carry both, and the fix was not a bigger regulator but a second board with its own feed. Splitting by current draw rather than by logical grouping is the lesson; the abandoned path is still visible in the firmware.

Design for the room, not the workshop. A game master command exists purely to replay the briefing, because at a trade fair the audio is simply lost to the noise around the stand and players miss what they were told. It is not a feature anyone specifies at the design stage — it comes from watching a group stand there having heard nothing.

Open source and a puzzle game are not automatically compatible. Publishing the firmware means publishing the answers unless something is done about it. Handling that in CI/CD rather than by keeping two branches by hand means the public repository cannot drift out of sync with the working one, and there is no manual step to forget before a push.

Key features

Twelve networked modules

Each puzzle runs on its own ESP32 and reports to a Raspberry Pi broker, so a single failure never takes the game down.

Fifteen minutes to neutralise the virus

One or two players work through the puzzle chain against a countdown owned by the display module.

State survives a restart

The active puzzle variant and the timer are published as retained MQTT messages, so a module that reboots mid-game rejoins where the game currently stands.

Solutions stripped at publish time

A GitLab CI/CD stage scrambles the puzzle answers on the way into the public repository, so the source can be open without spoiling the game.

Video-driven story

A Raspberry Pi plays a looping idle video, a briefing that differs per puzzle variant, and a clip for every phase and ending.

Game master touch console

A Waveshare AMOLED panel adjusts the timer, shows module status and releases a puzzle when a group stalls.

Bill of materials

Qty Component Description Notes
12 ESP32 / ESP32-S3 development board One controller per module, each with its own fixed address on the game network
1 Raspberry Pi MQTT broker, media player for the story videos and watchdog for all twelve modules
3 Custom module board, ESP32-S3 Switches, RFID and relay carrier boards designed for this project Umbrella Riddle Switches, Umbrella Riddle RFID and Umbrella Riddle Relayboard
2 MFRC522 RFID reader Card reading for the security protocol and colour sequence modules
1 PCF8574 I2C expander Keypad scanning at I2C address 0x20
1 LCD 20 x 4 with I2C backpack Timer and status display at I2C address 0x27
96 WS2812B LED Two strips of 48 inside the front tubes, driven by the gimmick module over FastLED
12 Panel indicator LED Front strip showing module readiness before the game and position during it
1 Waveshare ESP32-S3 Touch AMOLED 2.41 Game master console RM690B0 display with FT6336 touch, driven through bb_spi_lcd and bb_captouch
2 Relay Switched by the relay module to release the locks
4 Electronic door lock Released when the corresponding stage of the game is solved
1 ASA filament, Qidi Material for all printed panels and structural parts Printed on a Qidi X-Max 3, sprayed in gloss white
12 Toggle switch Inputs on the mutation panel
4 Jack socket, 6.3 mm Patch points of the cable matrix
1 Key switch Final action that ends the game
1 ATX PC power supply Single supply for the whole installation Chosen for its separate 12 V, 5 V and 3.3 V rails and the current headroom on each
1 HDMI splitter with audio extraction Separates picture and sound from the Raspberry Pi output
1 Audio amplifier Drives the speaker at the rear of the case
1 Speaker Rear-mounted, carries the video soundtrack into the room
1 Panel HDMI socket Feeds the external monitor
1 Panel USB socket Supplies power to the external monitor
1 Panel RJ45 socket Wired network access to the Raspberry Pi without opening the case
2 Translucent tube with WS2812B strip Front tubes visualising the virus and the antivirus, 48 LEDs each
1 External monitor Player-facing display above the case, driven by the Raspberry Pi over HDMI
View all projects →

An interactive Star Wars themed console for a fan club stand: RFID acrylic cards call up ship blueprints, and an ultrasonic radar sweeps the room.

ElectronicsProp Making3D PrintingInteractive
View project →

A three-part laser shooting gallery: a blaster, a control case and a bar of Porg targets that calibrate themselves and count how many you saved.

ElectronicsInteractiveProp Making3D Printing
View project →

A Fallout-inspired escape game built from seven electronics puzzle boxes that unlock a motorised vault door, designed to teach microcontrollers and sensors.

ESP32ElectronicsInteractive3D Printing
View project →