Inspiration

When I was a kid, I got a Wii, and it blew my mind. For the first time, games weren't just about pressing buttons: you moved, aimed and swung, and the game responded.

Back in 2006, that experience required a $250 console. Twenty years later, we all carry a device in our pocket with the same sensors and far more power. As engineers, it's our job to make the most of it.

That's why we built WandDuels: to turn the phone you already own into a wand, get people off their couches, and bring them together to play in the same room again.

What it does

WandDuels is a two-player wizard duel for Fire TV where each player's own phone is the magic wand. No gamepads, no extra hardware, just the phone in your pocket.

  • Join in seconds. The TV shows a QR code. Each player scans it and their phone becomes a wand. Nobody types anything, and nobody needs to know the TV's IP address.
  • Point and draw. Swing the phone and your cursor moves on the TV, like a gyro mouse. Hold the button, draw a shape in the air, and let go to cast it.
  • Five spells, five shapes:
    • Horizontal line: Force Dart, a fast, weak attack
    • Circle: Force Orb, a slow, heavy attack
    • Vertical line: Force Veil, a quick shield
    • Square: Force Wall, a strong shield
    • Z: Paralyzing Bolt, which stops your opponent from casting for a few seconds
  • Real duel mechanics. Attacks cross the arena and collide mid-air, and the stronger one keeps going. Shields soak damage and let any overflow through. Each spell has its own cooldown. The first wizard to reach zero life loses.
  • Hardcore mode. Raise your wand overhead and say "fire", "grass" or "water" to take on that element. The matchups work like rock-paper-scissors and change how hard each hit lands.
  • A finished game around it. It has a Home screen you can drive with the Fire TV remote, a How to Play screen, a pause menu, and phones that show which wizard they control.

How we built it

  • Three-part monorepo (npm workspaces):
    • apps/tv: the Fire TV app, built with React Native for TV (react-native-tvos 0.87) on Fire OS. It runs the whole game: the fixed-tick duel clock, spell recognition, collisions, shields, damage and rendering with Reanimated and SVG.
    • apps/controller: the phone app, an Expo (React Native 0.86) dev build. It reads the gyroscope and accelerometer and handles the cast button, haptics and on-device speech recognition.
    • packages/protocol: a pure TypeScript wire contract that both apps compile against. It contains no React Native code, which lets the two apps run different React Native versions.
  • Local networking without a server. The Fire TV hosts a raw TCP server (react-native-tcp-socket) and advertises itself over Zeroconf/mDNS. Phones connect straight to it and exchange newline-delimited JSON. Motion streams at up to 60 Hz, and a phone that's held still sends nothing.
  • A pointer model that avoids drift. We use relative motion, like a mouse, instead of trying to work out where the phone is aimed in the room, so there's no drift to correct. Each cursor is clamped to its player's half of the screen, so overshooting an edge quietly re-centres it. A gravity estimate from the accelerometer means the same swing moves the cursor the same way however you hold the phone.
  • Our own shape recognizer. We wrote a geometric classifier with tunable tolerances instead of a $1-style template matcher, because rotation invariance would make a horizontal line and a vertical line look like the same spell. It's pure, so we could test recognition quality without a device.
  • Voice that works offline. Hardcore uses on-device speech recognition, primed with just the three element words, and starts only when you tilt the wand up past 60°. The cast button and the voice channel never run at the same time.
  • Measured on real hardware. We timed drawing on a real Fire TV Stick and found closed shapes (circle, square) take about twice as long as we'd guessed, while straight strokes matched our estimates. We tuned the balance around those numbers.
  • Tuning without rebuilding. Every gameplay number (force, travel time, cooldowns, recognizer tolerances) lives in one tuning.ts file. For playtests, the TV can load overrides from AWS AppConfig through a small read-only Lambda (deployed with CloudFormation) when it launches. The TV checks every override and falls back to the bundled values if anything is wrong or it's offline.
  • AI-assisted, spec-driven process. We built it with Claude Code using the BMAD method, plus the Amazon Devices Builder Tools MCP for Fire TV guidance. The work went from a spec through UX design, architecture and 28 stories in four phases: pairing, the duel, Hardcore and a visual redesign. Pure logic like the recognizer, duel clock, collisions and tilt has unit tests (77 test files).

Challenges we ran into

  • Switching from Vega OS to Fire OS. We started the TV app on Vega OS with React Native for Vega. In our design the TV is the host: both phones connect directly to it over the local Wi-Fi, with no cloud service and no laptop in between. But React Native for Vega only documents outgoing network connections (a WebSocket client). It has no API for listening to incoming ones, so the TV couldn't accept a phone's connection unless we wrote a native C++ Turbo Module. That was too much native work for a hackathon timeline. Fire OS is Android, where any app can open a listening socket with the ordinary INTERNET permission. So we dropped the Vega scaffold and rebuilt the TV app on Fire OS with React Native for TV (react-native-tvos). As a bonus, we got the whole standard React Native library ecosystem back, including Reanimated, the TCP socket library and Zeroconf.

  • Making a phone feel like a wand. An absolute "laser pointer" drifts with the gyroscope, so we switched to relative motion with edge clamping. Then players rolled the phone in their hands and the cursor went the wrong way, so we added gravity tracking to keep the aim the same however the phone is held.

  • Performance on a 2018 stick. Ordinary duels ran smoothly, but when both wizards drew long strokes at once the game dropped to about 28 fps and visibly stuttered. Three changes fixed the biggest costs:

    • Spell trails: we removed the glow drawn behind each stroke. That halved the number of Views on screen, and parts of a stroke already drawn stopped being redrawn.
    • Shields: the fade now moves in 20 steps instead of updating every frame, so a standing shield isn't redrawn 60 times a second.
    • Fizzles: shards of a failed stroke are now static Views under a single fading layer, instead of each running its own animation.
  • Recording the demo. Recording on the Fire TV itself made things worse. screenrecord --bugreport cut the stick's frame rate by 91% and played the duel at a quarter of real speed in the video, and even plain full-HD capture only saved about 4 distinct frames per second. We solved it by buying an HDMI capture card and recording the TV's output from outside. The stick does no recording work, so the video shows the game running at its real speed.

Accomplishments that we're proud of

  • My first Fire TV app. I've built plenty of mobile and web apps, but never anything for a TV. WandDuels is my first app on this platform. It runs on a 2018 Fire TV Stick 4K, works entirely with the remote's D-pad, and talks to two phones over the local network.
  • It's really fun to play. I started playing with my brother to test and tune the game, and later to record the demo. Then we kept wanting "one more duel", long after the testing was done. That's the best evidence I have that the wand-and-spell idea works.
  • My first AWS integration outside of work. The TV can load game-balance overrides from AWS AppConfig through a small Lambda when it launches, so we could tune a duel between playtests without rebuilding the app. This was the first time I added an AWS service to a personal project.
  • It feels like a finished game. It has a Home screen, a How to Play screen, a pause menu, consistent visuals across the TV and the phones, and its own app icons. I already have improvements in mind and more items on the roadmap, but this version already feels polished and complete, not like a prototype.

What we learned

  • Building for a TV isn't so different from building for a phone. Fire OS is Android, so the tools we already knew all carried over: React Native, TypeScript, Gradle, adb and the npm ecosystem. Both apps even share one protocol package. What did change: the TV has to work entirely with a D-pad remote, the UI has to read from across a room, and the hardware is much weaker than a modern phone.
  • On low-end TV hardware, what counts is how much gets redrawn. Our biggest performance wins came from doing less work: fewer Views, fewer re-renders and fewer animated values, not cleverer code. Even a smooth fade or a per-shard animation adds up when it runs 60 times a second.
  • How to connect a project to an AWS service, and how AWS AppConfig works. We defined the whole backend as one CloudFormation template: AppConfig, plus a small Lambda behind a Function URL, so the TV holds no credentials. We learned how AppConfig's profiles, versions and deployments fit together, how to validate overrides with a JSON Schema before they ship, and to always keep the game working on its bundled values when AWS is out of reach.

What's next for WandDuels

  • Polish the details. Keep improving quality and performance in the smaller details, so every duel feels seamless and fluid on the Fire TV Stick, even in its busiest moments.
  • Keep playtesting and tuning. Keep playing, adjusting and playing again to make every duel as fun as possible. The AppConfig tuning loop makes that quick.
  • Meet the store standards. Bring the TV app in line with the Amazon Appstore requirements. Today it's a sideloaded build signed with a debug key. Bring the phone controller, currently a development build, in line with the Apple App Store and Google Play requirements.
  • More spells, and maybe mana. I already have many more spells in mind. I'm also exploring a mana system, where every cast spends from a pool of mana. That would make picking the right spell, and the right moment to cast it, part of the strategy and make duels more engaging.
  • Publish the apps. Release WandDuels on the Amazon Appstore, and the controller on the App Store and Google Play, so anyone with a Fire TV and a phone can start a duel.
Share this project:

Updates

Submission history