Fondations multi-éditeurs (1/3) : game_type + schéma/CRUD des objets de scène
Build and deploy / test-python (push) Successful in 1m41s
Build and deploy / test-js (push) Successful in 7s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped

Première brique du plan "Fondations d'une plateforme multi-éditeurs" —
l'utilisateur veut un éditeur dédié aux jeux 2D/serious games (scène à
coordonnées pixel fixes, objets en couches, collision, personnages
animés), distinct de l'éditeur générique actuel, sans dupliquer ce qui
peut être partagé (comptes, objets de données, moteur de logique de
flow, hébergement/publication).

- db/games/get_game_type.py (nouveau) : "document" (défaut, éditeur
  actuel) ou "jeu_2d" (nouveau), stocké dans _meta comme
  is_public_played — aucune migration pour les jeux déjà créés
  (retombent sur "document"). Choisi obligatoirement à la création
  (templates/index.html), jamais modifiable ensuite.
- screens/scenes/ (nouveau sous-module) : table _scene_objects (une
  scène = des objets en pixels fixes, pas les % fluides de
  _screen_elements — indispensable pour la collision/l'animation),
  CRUD complet, rendu HTML. kind="personnage" réutilise TELLE QUELLE la
  structure _personnage_data et les fonctions resolve_personnage_* déjà
  écrites pour le widget "personnage" de l'éditeur document (Phase 8) —
  même bibliothèque Forge, même moteur d'animation, juste une autre
  table de stockage.
- screens/flow/ensure_flow_schema.py : += trigger_object_id/
  target_object_id (ALTER TABLE sans contrainte FK, même patron que
  cond_element_a) — le moteur de logique de flow (_flow_nodes/_flow_edges,
  flow-engine.js) reste EXACTEMENT le même pour les deux éditeurs, seule
  la palette de nœuds change (screens/scenes/flow_palette.py, nouveau :
  sous-ensemble direct des triggers/actions existants, déjà génériques).
- screens/screens_repo/ensure_schema.py : += scene_width/scene_height
  sur _screens (taille de scène fixe en pixels, sans effet sur un écran
  "document").

Reste à faire (prochains commits) : route + template de l'éditeur de
scène, puis le rendu en mode jouable.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-08-31 09:42:38 +02:00
co-authored by Claude Sonnet 5
parent 70c2b8df05
commit efa7d1d9b0
22 changed files with 454 additions and 4 deletions
+2 -1
View File
@@ -31,6 +31,7 @@ from .games.list_games import list_games
from .games.game_meta import game_meta
from .games.is_public_played import is_public_played
from .games.set_public_played import set_public_played
from .games.get_game_type import get_game_type, DEFAULT_GAME_TYPE
from .games.create_game import create_game
from .games.update_game_name import update_game_name
from .games.delete_game import delete_game
@@ -74,7 +75,7 @@ __all__ = [
"PROJECTS_DIR", "FIELD_TYPES", "GLOBAL_VARIABLE_TYPES", "PLAYER_SHARED",
"slugify", "table_name_for", "game_dir", "db_path", "connect",
"list_games", "game_meta", "create_game", "update_game_name", "delete_game", "move_game",
"is_public_played", "set_public_played",
"is_public_played", "set_public_played", "get_game_type", "DEFAULT_GAME_TYPE",
"list_definitions", "get_definition", "create_definition", "rename_definition",
"definitions_referencing", "add_field_to_definition", "update_field", "delete_field",
"delete_definition",
+9 -2
View File
@@ -3,9 +3,10 @@ import os
from ..connection import connect
from ..game_dir import game_dir
from ..slugify import slugify
from .get_game_type import DEFAULT_GAME_TYPE
def create_game(name, slug_override=None):
def create_game(name, slug_override=None, game_type=DEFAULT_GAME_TYPE):
"""Feature 1 : crée le dossier du jeu, ses fichiers index.html/css/js
reliés entre eux, et sa base de données dédiée (nom du jeu en méta).
@@ -13,7 +14,12 @@ def create_game(name, slug_override=None):
`name` — utilisé par l'inscription (auth/) pour que le dossier d'un
compte porte son adresse email (slugifiée), indépendamment du nom
donné à son jeu. Toujours rendu unique de la même façon (suffixe
-2/-3...) si, par un hasard extrême, le dossier existe déjà."""
-2/-3...) si, par un hasard extrême, le dossier existe déjà.
game_type : "document" (défaut, éditeur générique actuel) ou "jeu_2d"
(éditeur de scène — voir get_game_type.py) — choisi une fois pour
toutes à la création, gate quel éditeur/quel rendu jouable ce jeu
utilise (voir routes/screens/screen_edit.py)."""
slug = slugify(slug_override) if slug_override else slugify(name)
base = slug
n = 2
@@ -78,6 +84,7 @@ console.log("Jeu chargé.");
"""
)
conn.execute("INSERT INTO _meta (key, value) VALUES ('name', ?)", (name,))
conn.execute("INSERT INTO _meta (key, value) VALUES ('game_type', ?)", (game_type,))
conn.commit()
conn.close()
return slug
+5
View File
@@ -1,5 +1,6 @@
from ..connection import connect
from .is_public_played import is_public_played
from .get_game_type import get_game_type
def game_meta(slug):
@@ -13,4 +14,8 @@ def game_meta(slug):
# ligne" en a besoin pour afficher son état actuel), sans avoir à
# appeler is_public_played(slug) séparément dans chaque route.
"is_public_played": is_public_played(slug),
# Type de jeu (fondations multi-éditeurs) : "document" (éditeur
# générique) ou "jeu_2d" (éditeur de scène) — voir
# get_game_type.py et routes/screens/screen_edit.py.
"game_type": get_game_type(slug),
}
+17
View File
@@ -0,0 +1,17 @@
from ..connection import connect
DEFAULT_GAME_TYPE = "document"
def get_game_type(slug):
"""Type de jeu choisi à la création (voir create_game.py) : "document"
(éditeur générique actuel — quiz/formulaires/contenus, écrans =
éléments HTML positionnés en %) ou "jeu_2d" (éditeur de scène dédié —
voir screens/scenes/, écrans = objets pixel-positionnés en couches).
Réutilise _meta comme is_public_played — aucune nouvelle table. Un jeu
créé avant l'existence de cette clé (absente de _meta) retombe sur
"document", son comportement d'avant, inchangé."""
conn = connect(slug)
row = conn.execute("SELECT value FROM _meta WHERE key = 'game_type'").fetchone()
conn.close()
return row["value"] if row and row["value"] else DEFAULT_GAME_TYPE