WizzyWorks
An interactive museum installation where visitors design and launch personalized fireworks on a giant projection screen using their smartphones. Exhibited at Tekniska Museet (Swedish Museum of Technology) in Stockholm on 31 October 2025 as part of the museum’s autumn holiday programme.
This was a group project done as part of the DH2413 Advanced Graphics and Interaction course at KTH Royal Institute of Technology.
Demo
What It Is
WizzyWorks turns a smartphone into a physical launch pad. Visitors scan a QR code to open a web interface where they customize up to nine fireworks: shapes, colors, or freehand drawings. They then place their phone on the floor in front of a large projection screen, tap to ignite, and step back to watch their creation explode across the display. A camera-based positioning system detects where each phone is placed and renders the fireworks at the corresponding screen location, making the act of placing your phone feel like a real launch.
The result is a shared experience: multiple visitors launch simultaneously, filling the projection with overlapping bursts of light and sound.
What I Did
My primary contribution was building the Python bridge that glued the system together. This involved:
- Bridge component: Received firework configuration data from the server via WebSocket, ran OpenCV to capture ArUco markers displayed on each phone screen, and combined position and firework data into JSON files ready for the Godot renderer.
- OpenCV + ArUco integration: Processed the camera feed to detect ArUco markers displayed on phone screens, calculating each phone’s real-world position and mapping it to screen coordinates.
- Server deployment: Containerized and deployed the backend to Azure Container Apps, managing environment configuration and ensuring reliable uptime during the exhibition.
- Firework types: Implemented additional firework variants (Willow, Chrysanthemum, and one firework show type) in the Godot rendering engine.
Technical Details
The system is composed of four loosely coupled components communicating in real time:
| Component | Technology |
|---|---|
| Visitor web interface | React + WebSockets |
| Position detection | Python, OpenCV, ArUco markers |
| Backend / message router | Python, WebSockets, UDP |
| Fireworks renderer | Godot (particle systems, shaders) |
| Deployment | Azure Container Apps |
Firework rendering in Godot uses custom particle systems and shader effects to produce eight distinct types: Pistil, Fire Flies, Willow, Chrysanthemum, Saturn, Tornado, Cluster, and Sparkle. A dynamic night sky shader with bloom lighting provides the backdrop.
Position tracking works by displaying an ArUco marker on each phone’s screen. A calibrated overhead camera feeds frames into OpenCV, which detects the markers and computes their coordinates. These are normalized and forwarded to Godot so each firework launches from the correct position on screen.
Interaction Design
One of the most deliberate interaction choices was requiring visitors to physically place their phone on the floor rather than launching directly from the screen. This creates a moment of physical commitment. You put your device down, press fire, and back away, which generates genuine anticipation and engagement. The shared projection means strangers’ fireworks intermingle, turning a personal creation into a collective display.
Reflection
WizzyWorks was the first project I’d worked on that ended up in front of a real public audience: museum visitors of all ages, not just classmates or course examiners. Watching someone scan the QR code, spend a few minutes drawing their firework, place their phone down, and then light up when it exploded on the big screen was genuinely satisfying in a way that a good grade never quite replicates.
The backend work I did (stitching together WebSockets, OpenCV, and Godot over UDP) felt like classic systems programming, but the context gave it weight. We saw at the exhibition that some parents had spent a long time designing fireworks with their children, only to hit a connection error and lose everything on reload. We added a re-send retry when submitting fireworks to the server, which reduced the problem, but it did not eliminate it entirely. That kind of real-world friction is a different teacher than any course assignment.
If I were to continue the project, I’d want to invest more in the customisation experience. Visitors could choose shapes and colors, but the freehand drawing option was where the most delight happened. People drew hearts, letters, their own names. More expressive input would make the personal-to-shared arc of the experience even stronger.
Big thanks to Rej, Alvar, Markus, and Oskar for making this project what it was. Everyone brought something distinct to the table and it genuinely showed in the final result. Getting to exhibit at Tekniska Museet together was a highlight of the year.
Gallery