Dev #11

Merged
w-vandal merged 23 commits from dev into main 2026-09-04 19:13:42 +00:00
Owner
No description provided.
w-vandal added 23 commits 2026-09-04 19:03:06 +00:00
Quêtes/collision : personnages nommés, dialogues qui parlent, boîte de dialogue en jeu
Build and deploy / test-python (push) Successful in 11m32s
Build and deploy / test-js (push) Successful in 1m12s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
2347a70c45
- "ℹ️ Informations" (propriétés d'un personnage) : nom éditable, réutilisé
  comme "qui parle" dans l'éditeur de dialogue de quête (menu déroulant,
  plus "Joueur" toujours disponible) — remplace l'ancien choix binaire
  joueur/pnj. db.sanitize_quest_dialogues accepte maintenant un nom libre.

- Nouveau menu "🖥️ Interface" (palette d'objets) avec le premier widget :
  "💬 Boîte de dialogue" (kind="dialogue_box", screens/rendering/
  dialogue_box_style.py) — position/taille comme tout objet de scène,
  panneau "🎨 Style" dédié (police, taille, épaisseur, couleur du texte,
  couleur header/body/footer). Rendu en <div> à 3 zones, jamais soumis à
  la collision ni à l'éditeur de collision (exclu partout : obstacles,
  liste des règles, payload). Rendu côté jeu dans .sceneUI, une couche
  FIXE au viewport (jamais .sceneWorld, qui défile avec la caméra).

- static/js/play/dialogue-box-controller.js : fait le lien moteur entre
  l'action "quete" de l'éditeur de collision et ce widget — affiche la
  réplique en cours du dialogue correspondant au STATUT ACTUEL de la
  quête (gameData.quests, désormais exposé game-wide par
  full_game_payload.py), avance au clic sur "Suivant" (header = qui
  parle, body = texte, footer = bouton), se masque à la dernière réplique.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Dialogues de quête : bulles illimitées, n'importe quel objet, timeline reliée
Build and deploy / test-python (push) Successful in 7m32s
Build and deploy / test-js (push) Successful in 1m2s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
521792fe00
- "qui parle" n'est plus réservé au personnage : N'IMPORTE QUEL objet de
  scène nommé (personnage, décor, fond — voir "ℹ️ Informations",
  screens/rendering/scene_object_names.py, ex-personnage_names.py) peut
  parler dans un dialogue.
- Confirmé/documenté : aucune limite au nombre de répliques par colonne
  (bouton "+ Réplique" reste toujours disponible).
- Bulle = header (menu déroulant du "qui parle") + body (le texte),
  centrée dans sa colonne à 70% de largeur, alignée verticalement et
  reliée à la suivante par un trait — remplace l'ancien alignement
  gauche/droite façon chat.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix "+ Réplique" qui remplaçait la bulle au lieu d'en ajouter une
Build and deploy / test-python (push) Successful in 7m9s
Build and deploy / test-js (push) Successful in 1m2s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
077af2234d
Bug : questSaveDialogues() adoptait la réponse du serveur comme nouvel
état local après chaque enregistrement. Une bulle fraîchement ajoutée a
un texte encore vide (rien tapé) — sanitize_quest_dialogues.py la
rejette légitimement (jamais de réplique sans texte persistée) — donc
la réponse renvoyait un tableau amputé de cette bulle, que le client
adoptait aveuglément, effaçant la bulle en cours d'écriture. Le clic
suivant sur "+ Réplique" repartait donc du même état qu'avant, semblant
"remplacer" la bulle plutôt que d'en ajouter une seconde. Le client ne
resynchronise plus jamais son état depuis la réponse d'enregistrement —
il est déjà la seule source de vérité pendant l'édition.

Colonnes de dialogue : occupent maintenant toute la hauteur disponible
de la modale plein écran et défilent chacune indépendamment (titre et
bouton "+ Réplique" restent fixes), au lieu d'une hauteur minimale fixe.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Test bout en bout : collision -> quête -> boîte de dialogue
Build and deploy / test-python (push) Successful in 6m11s
Build and deploy / test-js (push) Successful in 58s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
5e17e42dfa
Vérifie explicitement le lien moteur demandé : une règle de collision
"quete" retrouve la quête, récupère les répliques de son statut actuel,
les affiche dans l'ordre dans le widget "💬 Boîte de dialogue" posé sur
la scène, avance au clic sur "Suivant", disparaît à la dernière
réplique — déjà implémenté (collision-rules-controller.js +
dialogue-box-controller.js), ce test couvre la CHAÎNE COMPLÈTE plutôt
que chaque brique isolément.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix "à la collision" qui ne se déclenchait jamais
Build and deploy / test-python (push) Successful in 6m27s
Build and deploy / test-js (push) Successful in 54s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
3a67ba622b
Cause réelle : un objet portant une règle de collision est presque
toujours AUSSI un obstacle solide (collision activée par défaut, voir
forgeWouldCollide, personnage-controller.js) — le déplacement du joueur
est donc bloqué PILE au contact, sans jamais laisser les deux boîtes se
chevaucher réellement. Le déclencheur "collision" testait un
chevauchement STRICT (forgeShapesOverlap nu), qui n'était donc jamais
atteint : la règle ne se déclenchait jamais en jeu réel, malgré un
contact visible à l'écran.

Le déclencheur teste maintenant la boîte de l'objet élargie d'une
petite marge (3px) — assez pour détecter un simple contact — SANS
toucher au blocage physique du déplacement (resté strict, inchangé).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix "à la collision" — la marge de 3px restait insuffisante
Build and deploy / test-python (push) Successful in 5m56s
Build and deploy / test-js (push) Successful in 48s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
726775fe4e
forgeWouldCollide (personnage-controller.js) bloque le déplacement par
PAS ENTIER (cmd.vitesse px/tick, 4 par défaut mais réglable) : le
joueur peut donc rester bloqué jusqu'à PRESQUE un pas entier de
distance de l'obstacle, pas seulement 1-3px — la marge de tolérance du
correctif précédent (3px) restait insuffisante même pour la vitesse par
défaut dans les cas les moins favorables. Portée à 24px, confortable
pour toute vitesse raisonnablement configurée sans jamais déclencher
"à la collision" alors que les objets sont encore visiblement séparés.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix bulle "Appuie sur X" invisible + retire Attaque/Événement du picker
Build and deploy / test-python (push) Successful in 6m12s
Build and deploy / test-js (push) Successful in 52s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
00f9cf33e9
Bug corrigé : la bulle "Appuie sur X" était ajoutée comme ENFANT de
l'objet de scène (un <img> pour "personnage"/"decor"/"fond") — un
élément REMPLACÉ dont les enfants DOM ajoutés en JS ne sont JAMAIS
affichés par un navigateur, quel que soit son CSS. La bulle existait
donc bien dans le DOM (aucune erreur) mais restait invisible à l'écran.
Elle est maintenant ajoutée comme SŒUR de l'objet dans son parent
(.sceneWorld/.sceneUI), positionnée en JS aux mêmes coordonnées.

Assistant "+ Action" de l'éditeur de collision : "⚔️ Attaquer la cible"
et "📣 Déclencher un événement" retirés des choix proposés (pas besoin
pour le moment) — le serveur continue d'accepter/d'exécuter une règle
déjà enregistrée avec l'un des deux, rien ne casse pour l'existant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix bulle "Appuie sur X" trop haute au-dessus du personnage
Build and deploy / test-python (push) Successful in 6m7s
Build and deploy / test-js (push) Successful in 52s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
aa17614c7b
La bulle s'ancrait sur le cadre BRUT du sprite (<img> style.left/top/
width/height) — beaucoup de sprites (animaux CraftPix notamment, voir
screens/labels/animal_sprite_library.py) ont un très grand canevas
padé autour d'une silhouette bien plus petite, faisant flotter la
bulle loin au-dessus du personnage visible.

Elle s'ancre maintenant sur la BOÎTE DE COLLISION (objRect, déjà
résolue via forgeElementBoxRect — largeur/hauteur/décalage réglables
dans "🧱 Collision"), que l'auteur ajuste déjà pour épouser la
silhouette réelle : ancre bien plus fidèle, sans configuration
supplémentaire à faire.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Collision : une carte par objet occupe toute la largeur
Build and deploy / test-python (push) Successful in 6m24s
Build and deploy / test-js (push) Successful in 54s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
df34106752
L'ancienne grille (auto-fill, colonnes de 300px minimum) réservait des
colonnes vides même avec une seule carte, la laissant étroite avec un
grand vide à droite. Empilées en pleine largeur à la place — laisse
aussi la place à une longue chaîne de règles de s'étendre sans se
faire couper.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Quête "nouvelle" : écran Accepter/Refuser à la fin du dialogue
Build and deploy / test-python (push) Successful in 7m13s
Build and deploy / test-js (push) Successful in 1m5s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
e90d941527
Une fois le dialogue épuisé, si la quête est encore "nouvelle", la
boîte de dialogue bascule sur un écran d'offre au lieu de se masquer :
header "Quête : <titre>", body l'objectif, pied deux boutons.

- Accepter -> la quête passe "en_cours" (en MÉMOIRE seulement,
  gameData.quests — jamais persisté en base : le statut en base est
  celui de DÉPART pour toute nouvelle partie, pas un état de partie en
  cours, voir PLAYER_SHARED/full_game_payload.py).
- Refuser -> la boîte se referme SANS toucher au statut, qui reste
  "nouvelle" : la prochaine interaction rejoue exactement le même
  dialogue depuis le début — impossible d'avancer la quête sans
  l'accepter un jour.

Pour tout autre statut (déjà "en_cours"/"terminee"), la boîte se
masque normalement à la fin du dialogue, comme avant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix boutons Accepter/Refuser absents de l'écran d'offre de quête
Build and deploy / test-python (push) Successful in 6m47s
Build and deploy / test-js (push) Successful in 53s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
f2ed602459
Le footer de la boîte de dialogue n'avait pas data-dialogue-role="footer"
(seul son bouton interne "Suivant" l'avait, sous "next-btn") — le JS
(forgeShowQuestOffer, dialogue-box-controller.js) le cherche par ce
sélecteur pour y injecter les boutons Accepter/Refuser en fin de
dialogue d'une quête "nouvelle". querySelector ne trouvait donc jamais
le footer, et l'écran d'offre gardait silencieusement le bouton
"Suivant" au lieu des deux nouveaux boutons — exactement le bug signalé.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Quêtes : bulle "❓ Question" à choix multiples, à côté de "+ Réplique"
Build and deploy / test-python (push) Successful in 6m25s
Build and deploy / test-js (push) Successful in 58s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
e972acf9e6
Nouveau type de ligne dans un dialogue de quête (voir
db/quests/sanitize_quest_dialogues.py) : une bulle JAUNE, dans la même
chaîne verticale que les répliques (même alignement, reliée par un
trait) — header : nombre de choix (2 à 8) + récompense (score, montant
en points) ; body : la question, ses choix et un bouton radio pour
désigner la bonne réponse. Aucune limite au nombre de questions par
colonne, comme pour une réplique.

Les lignes de dialogue portent maintenant explicitement
{"type": "dialogue", ...} (au lieu d'un objet sans type) pour
distinguer les deux formes — migration de forme, tests mis à jour.

Portée de ce commit : l'ÉDITEUR (créer/modifier une question). Le jeu
lui-même (afficher la question au joueur, vérifier la réponse,
attribuer la récompense) reste à construire — le widget "💬 Boîte de
dialogue" ne sait aujourd'hui afficher qu'une réplique.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Quiz jouable : budget de récompense, boîte à quiz, widget score
Build and deploy / test-python (push) Failing after 1m34s
Build and deploy / test-js (push) Successful in 1m1s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
b5546df044
- Récompense d'une quête = budget MAXIMUM pour ses questions : la somme
  des points des "❓ Question" ne peut plus dépasser recompense_score
  (routes/quests/quest_dialogues.py à l'enregistrement des dialogues,
  quest_update.py si on abaisse la récompense sous ce qui est déjà
  réparti) — message d'erreur explicite (400) dans les deux sens,
  affiché via alert() côté éditeur (quest-editor.js), jamais enregistré
  silencieusement dans un état incohérent.
- Nombre de choix par question plafonné à 4 (au lieu de 8).

- Deux nouveaux widgets "🖥️ Interface" (mêmes fondations que "💬 Boîte
  de dialogue" — screens/rendering/dialogue_box_style.py, même panneau
  "🎨 Style") :
  - "❓ Boîte à quiz" : affiche la question et ses choix, sans pied (une
    question se résout au clic sur un choix, pas de "Suivant").
  - "🏆 Score" : affiche en continu les points gagnés, TOUJOURS visible
    une fois posé (contrairement aux boîtes de dialogue/quiz, masquées
    par défaut).

- Moteur d'exécution (static/js/play/dialogue-box-controller.js,
  refonte) : une conversation de quête alterne maintenant répliques
  (boîte de dialogue) et questions (boîte à quiz) selon le type de
  chaque ligne. Bonne réponse -> crédite le score (compteur runtime
  dédié, jamais lié au score du moteur document) et avance ; mauvaise
  réponse -> rien, la question reste affichée pour réessayer ; aucune
  boîte à quiz posée -> la question est ignorée plutôt que de bloquer
  la conversation. Le dialogue "en_cours" épuisé (donc, s'il contenait
  des questions, toutes répondues) fait passer la quête "terminee" (en
  mémoire seulement, comme le reste de ce système — voir accepter/
  refuser une offre de quête) : le joueur peut alors quitter la scène
  normalement, ces widgets n'étant jamais des obstacles.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix accès au canevas masqué + quiz : header quête, réponse fausse n'avance jamais bloquée, animé
Build and deploy / test-python (push) Failing after 1m36s
Build and deploy / test-js (push) Successful in 55s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
d705f58c4a
- Bug corrigé : les panneaux flottants "🧩 Objets"/"⚙️ Propriétés" sont en
  position:fixed (hors du flux flex de .builder3) — ils flottaient
  PAR-DESSUS le canevas sans jamais réduire sa largeur, rendant sa
  partie droite/gauche inaccessible au clic/glisser tant qu'un panneau
  restait ouvert. .builderCanvasArea réserve maintenant leur largeur
  (marge) dès qu'un panneau est ouvert (:has()).

- Boîte à quiz : header = "Quête : <titre>" (au lieu du texte de la
  question), corps = la question ET ses choix ensemble.

- Mauvaise réponse : ne bloque plus JAMAIS la progression (bug signalé :
  "je suis obligé de bien répondre sinon j'avance pas") — surligne la
  bonne réponse en vert (le choix cliqué en rouge s'il était faux) puis
  avance automatiquement après un court délai, sans jamais octroyer de
  points. Un second clic pendant la révélation est ignoré.

- Animations : la boîte à quiz rejoue une entrée (pop-in) à CHAQUE
  nouvelle question, la bonne réponse pulse en vert, une mauvaise
  réponse "secoue" en rouge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Annule la réservation d'espace des panneaux, corrige le vrai bug (drag invisible sous eux)
Build and deploy / test-python (push) Failing after 1m22s
Build and deploy / test-js (push) Successful in 53s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
046c38b4dc
Retour en arrière sur le commit précédent : les panneaux flottants
doivent RESTER en position:fixed par-dessus le canevas pour maximiser
l'espace utile (remarque explicite) — leur réserver une marge
permanente allait à l'encontre de ce principe et ne réglait rien.

Vrai bug identifié : un objet glissé (déplacé ou redimensionné) sous
l'un de ces panneaux (z-index:60) disparaissait littéralement à
l'écran PENDANT le geste — toujours déplacé/enregistré correctement en
dessous, juste invisible, donnant l'impression qu'on ne pouvait pas y
déposer d'objet. Élevé au-dessus des panneaux (z-index très haut) le
temps du glisser/redimensionnement SEULEMENT, restauré ensuite.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix "impossible d'aller plus loin vers la droite" — défilement automatique du canevas
Build and deploy / test-python (push) Failing after 1m13s
Build and deploy / test-js (push) Successful in 55s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
7c9b2c9b25
Cause confirmée (tous les objets bloquaient au même endroit, pas
spécifique à un widget) : une scène à taille fixe (960×540 par ex.)
peut être plus LARGE que la zone visible de .canvasFrame (overflow:auto)
selon la largeur de fenêtre — sa partie droite/basse défile alors HORS
de vue, et le curseur atteignait le bord de cette zone VISIBLE bien
avant celui de la scène elle-même : la souris ne pouvait tout simplement
plus bouger physiquement plus loin, sans aucun rapport avec la limite
réelle (960px) de la scène.

onSceneObjectMouseDown/onSceneObjectResizeMouseDown font maintenant
défiler .canvasFrame automatiquement quand le curseur approche un bord
pendant un glisser/redimensionnement — et continuent de déplacer
l'objet même si la souris reste immobile près du bord (mirror du
comportement standard d'un glisser-déposer dans une zone scrollable),
grâce à une position ACCUMULÉE plutôt que recalculée depuis le point de
départ fixe.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix vrai bug : un objet plus grand que la scène (fond/caméra) restait figé à (0,0)
Build and deploy / test-python (push) Failing after 1m22s
Build and deploy / test-js (push) Successful in 56s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
6b4846a646
Confirmé par l'utilisateur : lié à l'introduction du fond/caméra (voir
add_scene_object.py — un "fond" est posé à sa taille RÉELLE, souvent
bien plus grande que la scène, exprès, pour que la caméra le suive en
défilant sur un monde plus grand que le viewport).

Le glisser en position utilisait Math.max(0, Math.min(SCENE_WIDTH -
width, ...)) — cette formule suppose SCENE_WIDTH - width POSITIF (objet
plus petit que la scène). Pour un objet plus GRAND (ex. un fond de
1920px sur une scène de 960px), cette différence est NÉGATIVE, et
Math.max(0, négatif) ramenait TOUJOURS la position à 0 quel que soit le
glisser — l'objet restait donc figé, impossible à repositionner.

Le redimensionnement plafonnait aussi la largeur/hauteur à "ce qui
reste dans la scène depuis son coin" (SCENE_WIDTH - left) — empêchant
justement de rendre un objet plus grand que la scène par glisser (un
fond ne pouvait être agrandi qu'en le recréant via la galerie).

Les deux bornes sont corrigées pour fonctionner quel que soit lequel
(scène ou objet) est le plus grand.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Éditeur : le canevas affiche tout le monde (fond agrandi), pas que la scène
Build and deploy / test-python (push) Failing after 1m20s
Build and deploy / test-js (push) Successful in 53s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
14ec76dddd
Suite au fix du glisser figé à (0,0) : le canevas de l'éditeur restait
malgré tout limité à la scène nominale (960×540 par ex.) — la partie
d'un "fond" plus grand qui dépasse restait invisible/injoignable à la
souris. Le canevas affiche désormais tout le "monde" (max de la scène
et de l'étendue de chaque "fond", voir routes/scenes/scene_edit_view.py),
comme la caméra en jeu le fait déjà (personnage-controller.js).

Nouveau repère visuel "🎥 Champ de la caméra" : un cadre en pointillés
marquant où s'arrête la scène nominale à l'intérieur de ce monde agrandi
(le reste est assombri), pour que l'auteur voie clairement ce que le
joueur verra réellement à l'écran une fois le monde plus grand que le
viewport.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bouton "📐 Agrandir la caméra à la zone visible"
Build and deploy / test-python (push) Failing after 1m23s
Build and deploy / test-js (push) Successful in 54s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
b9d3c46087
Fait de tout le "monde" affiché par l'éditeur (la taille réelle d'un
"fond" plus grand que la scène nominale, voir routes/scenes/
scene_edit_view.py::world_width/world_height) la scène/caméra ELLE-MÊME
— jusqu'ici scene_width/scene_height n'étaient fixées qu'à la création
de l'écran, jamais modifiables ensuite. Le bouton n'apparaît que quand
un fond dépasse encore la scène nominale (même condition que le repère
"🎥 Champ de la caméra"), affiche la taille cible, recharge la page une
fois appliqué. La caméra ne recadre alors plus rien en jeu (monde ==
scène == viewport, voir personnage-controller.js::forgeUpdateSceneCamera).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contrôle direct de la taille de la caméra (Largeur × Hauteur, toujours modifiable)
Build and deploy / test-python (push) Failing after 1m13s
Build and deploy / test-js (push) Successful in 53s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
55c6bb330b
Remplace le bouton conditionnel "Agrandir la caméra à la zone visible"
(n'apparaissait que si un fond dépassait déjà la scène) par deux champs
"Caméra (px)" TOUJOURS visibles, pré-remplis avec scene_width/
scene_height actuels — demande explicite : "l'écran de l'éditeur a une
taille fixe, la caméra a la même taille, c'est tout", un réglage direct
plutôt qu'une suggestion automatique liée à la taille d'un fond.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Relie le score/statut des quêtes aux indicateurs SCORM
Build and deploy / test-python (push) Failing after 1m15s
Build and deploy / test-js (push) Successful in 51s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
413685e871
Les quêtes/quiz mettaient à jour l'état local (statut, score) sans
jamais toucher gameData.scoring, que scorm-api.js interroge déjà pour
reporter Completion/Success/Score au LMS. Ajoute forgeSyncQuizScoreToScorm,
forgeSyncQuestStartedToScorm et forgeSyncAllQuestsCompletionToScorm,
appelées lors d'un bon score, de l'acceptation d'une quête et de la
complétion de toutes les quêtes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Corrige les animations figées et le reporting SCORM dans le paquet exporté
Build and deploy / test-python (push) Failing after 1m15s
Build and deploy / test-js (push) Successful in 51s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
00f7191a8b
Deux bugs distincts détectés dans le paquet Web/SCORM :
- L'animation de marche du personnage dépend entièrement des touches
  clavier maintenues (heldKeys), qui ne sont alimentées que par des
  écouteurs keydown/keyup sur window. Un LMS comme SCORM Cloud charge
  index.html dans une iframe qui ne reçoit pas le focus clavier par
  défaut : aucune touche n'atteignait jamais window, donc le personnage
  ne bougeait/animait jamais. On force désormais le focus au chargement
  et on le reprend au premier clic dans le jeu.
- scorm-api.js (qui pousse score/statut au LMS) était bien copié dans
  le zip mais jamais référencé par un <script> dans index.html, car
  build_scorm_package.py ne passait pas scorm_api_wrapper_url au
  template — le reporting SCORM (Completion/Success/Score) ne
  fonctionnait donc jamais depuis un export.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Supprime le type d'écran "document" et recentre le produit sur le jeu 2D
Build and deploy / test-python (push) Successful in 9m41s
Build and deploy / test-js (push) Successful in 1m0s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
50835a18e2
Le document de cadrage produit cible des formateurs non techniques créant
des serious games/quiz gamifiés — l'éditeur générique "document" (blocs de
logique en nœuds, timeline d'animation, définitions d'objets/relations,
templates réutilisables) est une complexité hors cible que l'effort
d'ingénierie récent avait déjà abandonnée au profit du jeu_2d.

- Onboarding : ne garde que le parcours "RPG" (jeu_2d), retire
  Quiz/Embranchement/Créer mon jeu de A à Z (tous document-only)
- Suppression en bloc des modules exclusifs au document : routes/elements,
  routes/element_types, routes/objects, routes/legacy_actions,
  screens/elements, screens/element_types, screens/widgets,
  screens/legacy_actions, le rendu render_element_html.py et son cluster,
  templates/screen_edit.html, templates/game_dashboard.html,
  flow-editor.js/tabs-and-blocks.js/animation-timeline.js
- Dashboard toujours simplifié (un seul mode possible désormais)
- Tests document-only supprimés, tests de logique partagée (flow,
  événements personnalisés, animations) retargetés sur des écrans jeu_2d
- Aucune régression jeu_2d : 299 tests passent

Carte d'onboarding retravaillée : argumentaire RH non technique (liste à
coche, badge "Compatible LMS"), taille et interaction de retournement
ajustées.
w-vandal merged commit b1c995ab46 into main 2026-09-04 19:13:42 +00:00
Sign in to join this conversation.