Corrige : une animation déjà posée dans la logique ignorait le changement de personnage
Bug réel identifié grâce à la vidéo fournie + inspection directe de la
base de jeu de test : quand un nœud de flow "Jouer une animation"
(ou un clip de Timeline "sprite") était configuré pour un personnage,
ses frames étaient résolues et FIGÉES dans data_value/custom_keyframes
au moment de la configuration — changer ensuite le personnage Forge de
l'élément (galerie des propriétés) n'avait donc aucun effet sur les
animations déjà posées, qui continuaient à jouer indéfiniment les
frames de l'ANCIEN personnage.
Le nœud/clip ne stocke désormais que le NOM de l'animation
({"animation": "walk", "fps": 8, "loop": true}) — ses frames sont
résolues à l'EXÉCUTION, à partir du personnage ACTUELLEMENT assigné à
l'élément cible :
- screens/payload/full_game_payload.py expose un nouveau
gameData.personnage_animations (élément → animations), reconstruit à
chaque chargement de la page de jeu depuis _personnage_data — donc
toujours à jour, y compris après un changement de personnage.
- static/js/play/actions.js (resolveSpriteFrames) et
static/js/play/screens.js (applyAnimationClip) résolvent le nom
d'animation en frames à ce moment précis, plutôt que d'utiliser des
frames figées — repli sur l'ancien format {frames,...} pour les
nœuds/clips déjà créés avant ce correctif.
- Éditeur (flow-editor.js/animation-timeline.js) : simplifié en
conséquence — plus besoin de deviner rétroactivement quelle animation
correspond à une liste de frames stockées (l'ancien hack de
comparaison), le nom est maintenant stocké directement.
Nouveau test de régression (test_swapping_forge_character_updates_
already_configured_flow_action) qui reproduit exactement le scénario
filmé : configure l'action pour "male-adventurer", change le personnage
en "zombie", vérifie que gameData.personnage_animations reflète bien
zombie sans avoir à retoucher le nœud de flow.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5ead091c75
commit
70c2b8df05
@@ -6,6 +6,7 @@ from ..flow.list_flow_nodes import list_flow_nodes
|
||||
from ..flow.list_flow_edges import list_flow_edges
|
||||
from ..animations.list_animation_clips import list_animation_clips
|
||||
from ..element_types.list_element_types import list_element_types
|
||||
from ..rendering.personnage_data import resolve_personnage_animations
|
||||
|
||||
|
||||
def full_game_payload(slug, player_id=db.PLAYER_SHARED):
|
||||
@@ -45,12 +46,29 @@ def full_game_payload(slug, player_id=db.PLAYER_SHARED):
|
||||
# écran-modèle ne doit jamais être rendu comme un vrai <div
|
||||
# class="playScreen"> (il n'est jamais affiché tel quel, seulement
|
||||
# rechargé en direct à l'intérieur d'un élément qui l'utilise).
|
||||
# Animations d'un personnage (Phase 8) — résolues ici, à CHAQUE
|
||||
# affichage de la page de jeu (donc toujours à partir du personnage
|
||||
# Forge ACTUELLEMENT assigné), plutôt que figées dans le nœud de flow/
|
||||
# le clip de Timeline au moment où le créateur les a configurés : sans
|
||||
# ça, changer le personnage Forge d'un élément dans l'éditeur laissait
|
||||
# ses animations déjà posées dans la logique/la Timeline continuer à
|
||||
# jouer les frames de l'ANCIEN personnage indéfiniment (bug signalé —
|
||||
# voir runActionNode()/applyAnimationClip() qui font cette résolution
|
||||
# à l'exécution à partir de gameData.personnage_animations plutôt que
|
||||
# depuis un data_value/custom_keyframes qui contiendrait des frames
|
||||
# déjà résolues). include_templates=True : un personnage peut vivre
|
||||
# dans un écran-modèle d'élément de jeu réutilisable, comme les flows/
|
||||
# animations ci-dessous.
|
||||
personnage_animations = {}
|
||||
for s in list_screens(slug, include_templates=True):
|
||||
flows[str(s["id"])] = {
|
||||
"nodes": list_flow_nodes(slug, s["id"]),
|
||||
"edges": list_flow_edges(slug, s["id"]),
|
||||
}
|
||||
animations[str(s["id"])] = list_animation_clips(slug, s["id"])
|
||||
for el in list_elements(slug, s["id"]):
|
||||
if el.get("widget") == "personnage":
|
||||
personnage_animations[str(el["id"])] = resolve_personnage_animations(el)
|
||||
|
||||
definitions = db.list_definitions(slug)
|
||||
data = {}
|
||||
@@ -88,5 +106,5 @@ def full_game_payload(slug, player_id=db.PLAYER_SHARED):
|
||||
return {
|
||||
"screens": payload_screens, "flows": flows, "animations": animations,
|
||||
"element_types": element_types, "data": data, "fields_meta": fields_meta,
|
||||
"variables": variables,
|
||||
"variables": variables, "personnage_animations": personnage_animations,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user