diff --git a/dashboard/app.py b/dashboard/app.py
index c37147c..10e3bcf 100644
--- a/dashboard/app.py
+++ b/dashboard/app.py
@@ -47,13 +47,21 @@ def execute(sql, params=None):
finally:
conn.close()
-def load_sim_config(session_id: int) -> dict:
+_REFERENCE_CONFIG_ID = 1 # sim_001.json = référence pour la liste des modes
+
+def load_sim_config(session_id: int) -> dict | None:
+ """Retourne le cfg JSON ou None si introuvable (None est falsy ET distinguable de {})."""
path = os.path.join(SIM_CONFIGS_DIR, f"sim_{session_id:03d}.json")
try:
with open(path) as f:
return json.load(f)
- except Exception:
- return {}
+ except Exception as e:
+ return None
+
+def load_all_modes() -> dict:
+ """Charge les modes depuis sim_001.json (référence complète des 5 modes)."""
+ cfg = load_sim_config(_REFERENCE_CONFIG_ID) or {}
+ return cfg.get("modes", {})
def save_sim_config(session_id: int, cfg: dict):
path = os.path.join(SIM_CONFIGS_DIR, f"sim_{session_id:03d}.json")
@@ -407,7 +415,7 @@ if (el) {
⚙ CONFIG SIM_{{ '%03d' % current_sid }}.JSON
@@ -673,7 +690,7 @@ def params():
sid = int(request.args.get("sid", all_sessions[-1]["id"] if all_sessions else 1))
session = query_one("SELECT * FROM sessions WHERE id = %s", (sid,))
cfg = load_sim_config(sid)
- modes = cfg.get("modes", {})
+ modes = load_all_modes() # toujours les 5 modes depuis sim_001 (référence)
flash_msg = request.args.get("msg")
flash_ok = request.args.get("ok", "1") == "1"
return render_template_string(TEMPLATE,
@@ -697,8 +714,8 @@ def params():
def params_save():
sid = int(request.args.get("sid", 1))
cfg = load_sim_config(sid)
- if not cfg:
- return redirect(url_for("params", sid=sid, msg="Fichier config introuvable", ok=0))
+ if cfg is None:
+ return redirect(url_for("params", sid=sid, msg=f"Fichier sim_{sid:03d}.json introuvable dans {SIM_CONFIGS_DIR}", ok=0))
f = request.form
diff --git a/src/engine/run.py b/src/engine/run.py
index c27b6fe..947bff2 100644
--- a/src/engine/run.py
+++ b/src/engine/run.py
@@ -77,8 +77,12 @@ def run(config_path: str | None = None):
day, current_tick = tick_engine.next_tick(day, current_tick)
- # Réinit world_state au début de chaque nouveau jour
+ # Début d'un nouveau jour : hot-reload config depuis le JSON (permet les changements dashboard)
if current_tick == 0:
+ cfg.load(config_path, session_id=SESSION_ID)
+ effective_mode = cfg.mode() or db_mode
+ tick_sleep = float(os.getenv("TICK_SLEEP_SEC",
+ cfg.get("tick", {}).get("tick_sleep_sec", tick_sleep)))
_init_world_state(SESSION_ID, day)
except KeyboardInterrupt: