IUT Quest
Un jeu de piste géolocalisé qui fait courir 12 équipes dans tout Blois, entre épreuves chronométrées et défis à prouver en photo.
Fiche projet
- Catégorie
- Full-stack
- Année
- 2026
- Rôle
- Développeur full-stack (front · tests · back)
- Durée
- 1 mois
- Type
- SAÉ 4012, projet de groupe
- Statut
- Démo en ligne
- 12équipes engagées
- 6épreuves collectives
- 100+défis au catalogue
- 100+utilisateurs de l'appli
Présentation
IUT Quest est un jeu de piste grandeur nature inspiré de Pékin Express, conçu pour le challenge inter-filières de l'IUT de Blois. Le temps d'une journée, jusqu'à 12 équipes de 6 à 10 personnes (étudiants, enseignants et personnel administratif) s'affrontent à travers toute la ville.
Le parcours s'étend sur les deux sites de l'IUT, la bibliothèque universitaire, le centre-ville et le château. Chaque équipe enchaîne six grandes épreuves collectives planifiées à l'avance, et pioche en parallèle dans un catalogue d'une centaine de défis libres en photo, vidéo ou texte, valant de 5 à 30 points selon leur difficulté. L'équipe qui totalise le plus de points repart avec le trophée.
Équipe (4 personnes)
- Djibril : maquette
- Louis et Paul : back-end
- Clément : front-end et une partie des traitements PHP
Organisation : Kanban sur Trello, une branche Git par tâche, relecture systématique avant chaque merge.
Mon rôle
- Front-end de l'application publique utilisée par les équipes sur le terrain.
- Interface mobile-first, installable en PWA : les joueurs sont dehors toute la journée, sur téléphone, en 4G.
- Carte en temps réel : intégration de Leaflet et de la géolocalisation du navigateur. Une fois le suivi autorisé,
watchPositionalimente la session et pousse régulièrement la position vers l'API. Chaque équipe voit les autres se déplacer, chacune avec sa couleur, à côté des lieux clés de l'événement. - Côté serveur : plusieurs traitements PHP avec leurs contrôleurs Laravel et vues Blade.
- Côté interface : profil et progression de l'équipe, barre d'avancement, minuteur de fin d'événement, vérification du format des médias avant envoi, et verrouillage du classement une heure avant la fin, pour éviter les contestations de dernière minute.
Stack technique
| Techno | Usage |
|---|---|
| Laravel | Framework PHP MVC, vues Blade et jobs asynchrones |
| Docker | Conteneurs déployés sur un VPS OVH |
| MySQL | Groupes, épreuves, positions et validations |
| JavaScript | Géolocalisation et carte en temps réel avec Leaflet |
Fonctionnalités principales
- Carte en temps réel : chaque équipe apparaît avec sa couleur, à côté des lieux de l'événement. La légende et l'heure de dernière actualisation indiquent la fraîcheur de la position affichée.
- Épreuves et défis : six grandes épreuves planifiées par créneau horaire, plus un catalogue de défis libres ouverts jusqu'à 17 h, chacun avec sa preuve à fournir (photo, vidéo ou texte).
- Validation par un administrateur : aucun point n'est attribué automatiquement. Un admin ouvre la preuve, l'accepte ou la refuse, et le système signale les équipes adverses présentes sur le même créneau.
- Traitement des médias en arrière-plan : photos converties en WebP, vidéos confiées à un job asynchrone, pour qu'un envoi depuis le terrain ne bloque jamais l'interface.
- Back-office complet : gestion des lieux, épreuves, groupes et planning, avec détection des conflits de créneaux et export PDF de la feuille de départ avec son QR code.
Défis rencontrés
Points comptés en double
Problème : les points étaient crédités dès la soumission d'une preuve. Un simple retour arrière du navigateur suffisait à les compter deux fois, et un refus de l'admin ne les retirait pas.
Solution : un état explicite sur chaque défi (non validé, en cours de validation, validé), et l'attribution des points déplacée au seul moment où un admin tranche. Le score dépend de ce qui a été validé, plus de ce que fait le joueur.
Envoi de vidéos lourdes en 4G
Problème : l'envoi d'une vidéo de plusieurs dizaines de Mo bloquait l'interface, et la preuve pouvait être ouverte à la validation avant la fin du transfert.
Solution : photos compressées en WebP côté serveur, vidéos traitées par un job asynchrone avec FFmpeg. Le fichier est stocké temporairement et n'apparaît à la validation qu'une fois le traitement terminé.
Géolocalisation instable
Problème : le navigateur redemandait l'autorisation de géolocalisation à chaque changement de page, et les positions sur la carte devenaient incohérentes.
Solution : autorisation demandée une seule fois puis conservée en session. watchPosition prend le relais en continu et n'envoie la position à l'API qu'à intervalle régulier : assez souvent pour suivre la course, assez peu pour épargner la batterie.