9 janvier 2019
ISS Escape game
3 minutes de lecture
Nous aimons bricoler, coder et tester de nouveaux concepts régulièrement. L'occasion s'est de nouveau présentée lors d'une soirée dans nos locaux, présentation ici de notre premier escape game et des différentes étapes de sa réalisation. 🚀
🗒 Scénario
Nous disposions d’une petite salle de 4m carrés et la thématique de l’espace est récurrente dans nos locaux. Un channel Slack #space
est d’ailleurs dédié à l’actualité sur l’espace et plus particulièrement au suivi des différents lancements de fusées. Nous sommes donc partis sur un scénario avec cette salle devenant un module défaillant de la station spatiale internationale dont il faut s’échapper. Une suite d'énigmes amène les joueurs à accéder à un serveur central pour activer l’évacuation d’urgence.
L'écran du serveur central utilisant une application simulant un environnement type SF. Dispo sur GitHub https://github.com/GitSquared/edex-ui
🕵️ Énigmes
Ayant chacun participé à plusieurs escapes games, les énigmes ont été créées plus rapidement que nous le pensions en repensant au thème et au matériel qui était déjà à notre disposition. Dans la plupart de ces jeux on retrouve des combinaisons de cadenas, des correspondances avec des formes et des codes couleurs ainsi que des objets à trouver. Nous voulions avoir une durée relativement courte pour 2 joueurs c'est pourquoi l’ensemble comporte seulement 5 énigmes.
Une ardoise avec plusieurs codes dont certains chiffres sont écrits au marqueur indélébile est la première énigme à trouver, plusieurs joueurs n’osaient pas l’effacer même avec des indications les encourageant. C'est pourquoi nous jetions un œil régulièrement et communiquions via talkie walkie pour aider les joueurs.
Un autre code devait être trouvé grâce à une lampe à lumière noire révélant des signes écrits au feutre UV. Le code final d’accès du serveur central nécessitait de jouer quelques notes sur une guitare avec un accordeur afin de le révéler. Ce-dernier permettant d'appeler les secours et ainsi terminer le jeu.
Aussi une machine à fumée, des couvertures de survie et les musiques du film Interstellar ajoutaient une ambiance pesante sur les participants 😈.
⚛️ Bonus app
Pour garder le score (et surtout parce que l’on aime vraiment coder) une petite web app React a été créée. Les données sont stockées sur Firebase, ce qui permet d’utiliser la base de données temps réel et d’ajouter un service worker pour recevoir une notification lorsque les participants accèdent à la commande d’urgence et peuvent enfin s'échapper !
Firebase
L'affichage des scores est affiché sur une tablette à côté de la salle et nous souhaitions aussi recevoir les notifications sur nos smartphones.
Firebase s'est avéré répondre aux besoins mais la documentation officielle manque d'exemple pour les notifications web avec service worker. Voici donc comment nous demandons côté client à s'inscrire sur un topic de notification
// Request permission with the browser, get a unique token and subscribe to a topic
const messaging = firebase.messaging()
messaging.usePublicVapidKey('XXX')
await messaging.requestPermission()
const token = await messaging.getToken()
fetch(`https://europe-west1-escape-game-
XXXX.cloudfunctions.net/app/subscribe/${token}`)
messaging.onMessage((payload) => {
console.log('Notification Received', payload)
})
Il faut ensuite implémenter la partie serveur sur cloud functions pour envoyer la notification lors qu'une partie se termine.
const functions = require('firebase-functions')
const admin = require('firebase-admin')
const express = require('express')
const cors = require('cors')({ origin: true })
admin.initializeApp(functions.config().firebase)
const app = express()
app.use(cors)
// Send a notification when a game end
exports.updateGame = functions
.region('europe-west1')
.firestore.document('games/{gameId}')
.onUpdate((change, context) => {
const newValue = change.after.data()
const previousValue = change.before.data()
if (!previousValue.endedAt && newValue.endedAt) {
admin.messaging().send({
notification: {
title: `${newValue.player1} et ${newValue.player2} sont sauvés !`,
},
topic: 'notifications',
})
}
})
// Subscribe a token to a topic
app.use(cors)
app.get('/subscribe/:token', (req, res) => {
admin.messaging().subscribeToTopic([req.params.token], 'notifications')
})
exports.app = functions.region('europe-west1').https.onRequest(app)
Pour plus de détails le dépôt GitHub est disponible.
Je m'échappe 👋🚀.