Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to automate your murder mystery: immersive ...

How to automate your murder mystery: immersive games in your home

Have you hosted a murder mystery party but dreaded the paper puzzles and constant character confusion? For Halloween, we tricked out our party with Node.js by building a electromagnetic treasure chest, IoT-powered dramatic deaths, and digital character sheet. We relied on JavaScript to enhance the immerse role-playing game and elevated our home into an escape track. Come learn how to use your programming skills to become the ultimate party host!

Tiger Oakes

November 13, 2024
Tweet

More Decks by Tiger Oakes

Other Decks in Programming

Transcript

  1. DETECTIVE TIGER & DAPHNE OAKES: How to automate your Murder

    Mystery Build immersive games in your home!
  2. About us Tiger Oakes Performance-focused senior engineer at Microsoft @notwoods.bsky.social

    tigeroakes.com Daphne Danger Oakes Software engineer at Grow Therapy and comedian daphneoakes.com youtube.com/@daphne.danger
  3. What is a murder mystery party? Party game where your

    friends are transformed into fictional characters! • Themed party with costumes • Investigating a “murder” • Obtain clues, evidence, & secrets …and you can enhance your party with escape room puzzles and effects!
  4. Party game where your friends are transformed into fictional characters!

    • Themed party with costumes • Investigating a “murder” • Obtain clues, evidence, & secrets …and you can enhance your party with escape room puzzles and effects! What is a murder mystery party?
  5. Building from kits https://www.foulplayco.com/murder-at-menlo-park Pre-written story and character kits can

    be found online from lots of stores! • Strong base for enhancements • Props can be customized We like kits from Foulplay Games!
  6. Murder solving tools 01 List of suspects Digital character sheet

    with guest photos 02 Special effects Murder made dramatic with lights and sound effect 03 Treasure chest A locked treasure chest with evidence inside
  7. HOW TO AUTOMATE YOUR MURDER MYSTERY 01 List of suspects

    Digital character sheet with guest photos
  8. How it was built Web app loaded onto tablets at

    party 1. Svelte: UI framework (& animation) 2. Convex: Database (& realtime syncing) 3. Thumbor: Image processing (& machine learning)
  9. Svelte Update when our data changes Reuse the same UI

    elements on multiple pages Built-in CSS modules Easy built-in entrance and state change animations UI linked to state Reusable components Bundled CSS Animation UI with sepia old-timey look
  10. <script> import { slide } from 'svelte/transition'; let { src

    } = $props(); </script> <div class="avatar-container" in:slide> <img {src} alt="" // </div> <style> .avatar-container { … } </style> Svelte
  11. <script> import * as themes from './theme-list'; let { theme

    } = $props(); </script> <svelte:head> <link rel="stylesheet" href={themes[theme]} // </svelte:head> Svelte CSS themes
  12. Convex Works as a database, web socket server, and image

    storage bucket Updates client state automatically to update the UI Stores images and generates a link for images in database tables Strict typing for both the database rows and the server actions Database Realtime sync Image storage TypeScript Store guest name and character info
  13. import { query } from './_generated/server'; export const listAllCharacters =

    query({ args: { partyId: v.id('parties') }, async handler(ctx, args): Promise<Character[]> { const party = await ctx.db.get(partyId); return await ctx.db .query('characters') .withIndex('by_game', (q) => q.eq('gameId', party.gameId)) .order('asc') .collect(); } }); Convex server
  14. Convex client <script lang="ts"> import { useQuery } from 'convex-svelte';

    import { api } from './/.//convex/_generated/api'; // Types automatically inferred from the server const query = useQuery(api.party.listAllCharacters, { partyId: data.partyId }); </script> <ul> {#each query.data as character (character.id)} <Character {guest} // {/each} </ul>
  15. Thumbor Find face using Machine Learning and center the crop

    around it Send a smaller image size and filter it No need to manage binary blobs on the server No image processing for us Crop to face Recolor & resize Generate URL Change image format Make pictures uniform
  16. Thumbor usage </ Before --> <img src="http://convex.local/avatar.jpg" // </ After

    --> <img src="http://thumbor.local /100x100/smart/http%3A%2F%2Fconvex.local%2Favatar.jpg" //
  17. Thumbor-ES import { buildThumborUrl } from 'thumbor-es'; // /100x100/smart/filters:contrast(2)/<oldUrl> const

    url = await buildThumborUrl({ image: oldUrl, resize: { width: 100, height: 100 }, smart: true, , filters: [contrast(2)] }); Response.redirect(url, 303);
  18. Thumbor JSON API // /meta/smart/<oldUrl> const metadataUrl = await buildThumborUrl({

    endpoint: 'metadata', image: oldUrl, smart: true }); const response = await fetch(metadataUrl); const metadata = await response.json(); // Use detected face to crop the image const face = metadata.focal_points?/find((p) => p.origin =// 'Face Detection') return await buildThumborUrl({ endpoint: 'image', image: oldUrl, crop: cropAroundFace(face), });
  19. Self-Hosted 1. Convex and Thumbor can be self-hosted 2. Run

    at a party with spotty Wi-Fi 3. Not limited to one computer 4. Communicate to same router on local network Everything works on intranet!
  20. HOW TO AUTOMATE YOUR MURDER MYSTERY 02 Special effects Murder

    made dramatic with light and sound effect
  21. Smart lights & speakers Connects to Wi-Fi or similar network

    Speakers: Alexa/Google Home Bulbs: Philips Hue/LIFX/IKEA TRÅDFRI Switches: Hue/TP-Link Kasa
  22. Home Assistant Universal app for talking to smart home devices

    (ex. smart lights) https://home-assistant.io/
  23. HOW TO AUTOMATE YOUR MURDER MYSTERY 03 Treasure chest A

    locked treasure chest with evidence inside
  24. Me: can we go to an escape room? Mom: we

    have escape room at home Escape room at home:
  25. Architecture Parts of electromagnet circuit 1 Magnet Exert force so

    that the lid can’t be opened 2 Switch Toggle the magnet circuit on and off 3 Server Use software to control the switch
  26. Server software import { Gpio } from 'onoff'; // Control

    GPIO pin 18 const magnetRelay = new Gpio(18, 'out'); // Turn signal on, which connects magnet circut await magnetRelay.write(1); // Turn signal off, which breaks magnet circut await magnetRelay.write(0);
  27. Server software import { Gpio } from 'onoff'; const magnetRelay

    = new Gpio(18, 'out'); async function onRequest(request: Request): Response { const signalOn = await magnetRelay.read() =// 1; switch (request.method) { case 'GET': return Response.json(signalOn); case 'POST': await magnetRelay.write(signalOn ? 0 : 1); return Response.json(!signalOn); } }
  28. Password entry client code <script> let { locked } =

    $props(); </script> <header> <h1>Trunk is <b>{locked ? 'LOCKED' : 'UNLOCKED'}</b></h1> </header> <form method="POST"> {#if locked} <input name="code" type="text" size={4} // {/if} <button type="submit">{locked ? 'Unlock' : 'Lock'}</button> </form>
  29. Password entry server code // +page.server.js import { RASPBERRY_PI_URL }

    from '$env/static/private’; // Load state by checking if the magnet is locked or not export async function load({ fetch }) { const response = await fetch(RASPBERRY_PI_URL, { method: 'GET' }); return { locked: await response.json() }; }; // We don't need any client-side JavaScript export const csr = false;
  30. Password entry server code // +page.server.js import { RASPBERRY_PI_URL, EXPECTED_PASSWORD

    } from '$env/static/private'; export const actions = { // Handle POST from <form> submission async default({ request, fetch }) { const formData = await request.formData(); const code = formData.get('code') as string | null; // Only talk to the Raspberry Pi if the correct password is entered if (code?/trim().toUpperCase() =// EXPECTED_PASSWORD) { await fetch(RASPBERRY_PI_URL, { method: 'POST' }); return { locked: false }; } }, };
  31. Takeaways …and invite us! No hardware experience is required. If

    anything, software experience helps! Your software skills can be used for more than just apps! 1 2 3 Host a murder mystery party Anyone can work on home automation projects Software can be creative
  32. Slidesgo Flaticon Freepik CREDITS: This presentation template was created by

    Slidesgo, and includes icons by Flaticon, and infographics & images by Freepik TIGER & DAPHNE OAKES Thanks! @notwoods.bsky.social youtube.com/@daphne.danger tigeroakes.com daphneoakes.com