Score/Progression (Phase 1.1 de la feuille de route produit)
Build and deploy / test-python (push) Successful in 7m27s
Build and deploy / test-js (push) Successful in 1m16s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped

Concept de premier ordre, distinct du système de variables globales —
préalable identifié aux futurs exports SCORM/xAPI (note de cadrage
.claude/Forge_Engine_Cadrage.pdf) : ces standards ont besoin d'un signal
"score"/"terminé" propre, pas d'une convention sur une variable choisie
par le créateur.

- db/scoring/ (même patron que db/global_vars/) : table _scoring, un
  score numérique + un statut (non_commence/en_cours/termine/reussi/
  echoue) par joueur (voir db.PLAYER_SHARED pour l'aperçu créateur).
- Deux nouvelles actions de flux, dans les deux éditeurs (document et
  scène) : "Modifier le score" (réutilise le vocabulaire d'opérations
  déjà là pour "Modifier une variable" — incrémenter/définir/etc., aucune
  nouvelle colonne de nœud) et "Définir le statut de la partie".
- Routes créateur (routes/flow/flow_node_run_score.py,
  flow_node_run_status.py) + miroirs publics par joueur
  (routes/public_play/) — même principe que flow_node_run_variable.py.
- GET /game/<slug>/scoring/<player_id> : lecture interne, pas exposée au
  joueur, préparée pour être consommée par le futur export Web/SCORM.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-02 06:23:37 +02:00
co-authored by Claude Sonnet 5
parent 76a50fa87a
commit 9776fbc057
26 changed files with 486 additions and 1 deletions
+22
View File
@@ -400,6 +400,27 @@
{% endif %}
</div>
<!-- Score/progression (voir db/scoring/) : concept de premier
ordre distinct des variables globales ci-dessus — un seul
score par joueur, pas de nom à choisir. Réutilise le même
vocabulaire d'opérations (DATA_OPERATIONS). -->
<div id="nf-action-score-fields" style="display:none;">
<select id="nf-action-score-operation" onchange="updateDataValuePlaceholder('nf-action-score-operation', 'nf-action-score-value')">
{% for key, label in data_operations %}
<option value="{{ key }}">{{ label }}</option>
{% endfor %}
</select>
<input type="text" id="nf-action-score-value" style="margin-top:6px;" placeholder="Valeur / montant">
</div>
<div id="nf-action-status-fields" style="display:none;">
<select id="nf-action-status-value">
{% for key, label in score_status_choices %}
<option value="{{ key }}">{{ label }}</option>
{% endfor %}
</select>
</div>
<div id="nf-action-event-fields" style="display:none;">
{% if not custom_events %}
<p class="hint">Aucun événement pour l'instant — <a href="javascript:void(0)" onclick="switchBuilderTab('events'); return false;">crées-en un dans l'onglet Événements</a>.</p>
@@ -677,6 +698,7 @@
var ELEMENT_VISIBILITY_LABELS_MAP = {{ element_visibility_labels_json|safe }};
var ELEMENT_ORIENTATION_LABELS_MAP = {{ element_orientation_labels_json|safe }};
var DATA_OPERATION_LABELS_MAP = {{ data_operation_labels_json|safe }};
var SCORE_STATUS_LABELS_MAP = {{ score_status_labels_json|safe }};
var CONDITION_OPERATOR_LABELS_MAP = {{ condition_operator_labels_json|safe }};
var TRIGGER_LABELS_MAP = {};
var CUSTOM_EVENTS_MAP = {{ custom_events_map_json|safe }};
+22
View File
@@ -609,6 +609,27 @@
{% endif %}
</div>
<!-- Score/progression (voir db/scoring/) : concept de premier
ordre distinct des variables globales ci-dessus — un seul
score par joueur, pas de nom à choisir. Réutilise le même
vocabulaire d'opérations (DATA_OPERATIONS). -->
<div id="nf-action-score-fields" style="display:none;">
<select id="nf-action-score-operation" onchange="updateDataValuePlaceholder('nf-action-score-operation', 'nf-action-score-value')">
{% for key, label in data_operations %}
<option value="{{ key }}">{{ label }}</option>
{% endfor %}
</select>
<input type="text" id="nf-action-score-value" style="margin-top:6px;" placeholder="Valeur / montant">
</div>
<div id="nf-action-status-fields" style="display:none;">
<select id="nf-action-status-value">
{% for key, label in score_status_choices %}
<option value="{{ key }}">{{ label }}</option>
{% endfor %}
</select>
</div>
<div id="nf-action-event-fields" style="display:none;">
{% if not custom_events %}
<p class="hint">Aucun événement pour l'instant — <a href="javascript:void(0)" onclick="switchBuilderTab('events'); return false;">crées-en un dans l'onglet Événements</a>.</p>
@@ -1274,6 +1295,7 @@
var SPRITE_LIBRARY = {{ sprite_library_json|safe }};
var ELEMENT_ANIMATIONS_MAP = {{ element_animations_map_json|safe }};
var DATA_OPERATION_LABELS_MAP = {{ data_operation_labels_json|safe }};
var SCORE_STATUS_LABELS_MAP = {{ score_status_labels_json|safe }};
var CONDITION_OPERATOR_LABELS_MAP = {{ condition_operator_labels_json|safe }};
var TRIGGER_LABELS_MAP = {{ trigger_labels_json|safe }};
var CUSTOM_EVENTS_MAP = {{ custom_events_map_json|safe }};