Repository navigation
Architecture technique
Spec technique transverse. L'existant d'abord, puis les services à construire pour couvrir Système-de-jeu, Économie, Carte-galactique.
-
Monorepo :
api/(Laravel 12, API JSON/api/v1, port 8000) +front/(Next.js, port 3000, app joueur). Voir ADR 0001 et ADR 0002. -
PostgreSQL (Docker, port 54322). Schéma canonique dans
api/database/migrations/, seeds dansapi/database/seeders/. Tables core en place : profiles, forum (categories/forums/topics/posts), characters, groups/group_members, chat_messages, items/inventory/economy_history, ships, wiki. -
Auth : Fortify + Sanctum (session SPA par cookies, CSRF). Le front consomme exclusivement l'API (
front/src/shared/utils/api.ts). -
Architecture front : Feature-Driven Development (
src/features/<domaine>/), composants partagés danssrc/shared/. - Prod : Docker Compose sur VPS (swor.fr = front, api.swor.fr = Laravel), CI GitHub Actions (tests PHPUnit + typecheck/build front).
- Back-office Filament à venir sur
/admin(#39) ; temps réel via Laravel Reverb (#38).
- Rôles : joueur / animateur (MJ) / modérateur / admin, stockés sur
profiles.role(enumUserRole) (🔶 ou table de rôles multiples — un modérateur peut être MJ). -
Toute la logique métier est côté serveur (controllers + policies/gates Laravel) : les écritures sensibles (jets de dés, transactions, validation de fiche, tick économique) ne passent jamais par le client. Gates
adminetmoderateen place. - Le back-office Filament vérifiera le rôle via les mêmes gates (#39).
-
Génération côté serveur uniquement : endpoint API qui tire le jet (
random_int), l'insère dansdice_rollset le lie au post — le client ne fournit jamais un résultat. - Idempotence : un jet est rattaché à une déclaration d'action unique (pas de reroll en cas de retry réseau).
- Diffusion en temps réel sur le sujet via Reverb/Echo (les autres participants voient le jet arriver).
Appel API Claude par action déclarée : entrée = action + contexte du sujet + fiche mécanique du personnage ; sortie = JSON structuré {compétence, DD, avantage, justification, conséquences_suggérées}.
Patterns d'implémentation :
-
Sorties structurées (
output_config.formatavec JSON schema, ouclient.messages.parse()) : garantit un verdict parsable, pas de post-traitement fragile. -
Prompt caching : le prompt système (règles d'arbitrage, échelle des DD, format de réponse) est volumineux et stable → placé en tête avec
cache_control, le contenu volatile (post, fiche) après. Les relectures de cache coûtent ~0,1× le prix d'entrée. -
Maîtrise des coûts : quota de jets arbitrés par joueur/jour, cache 15 min sur une même action re-soumise, monitoring du champ
usagede chaque réponse. - Streaming inutile ici (réponse courte) ; latence cible < 3 s.
Choix du modèle (prix au 2026-06, par million de tokens) :
| Modèle | Input / Output | Position |
|---|---|---|
Claude Haiku 4.5 (claude-haiku-4-5) |
$1 / $5 | Le moins cher et le plus rapide — à évaluer en premier sur ce cas d'usage (tâche courte et cadrée) |
Claude Sonnet 5 (claude-sonnet-5) |
$3 / $15 (intro $2/$10 jusqu'au 31/08/2026) | Meilleur jugement narratif, si Haiku arbitre mal les cas subtils |
Claude Opus 4.8 (claude-opus-4-8) |
$5 / $25 | Plafond qualité, sans doute surdimensionné pour un DD |
🔶 Décision à prendre sur éval réelle : constituer un jeu de ~50 actions RP annotées (DD attendu par un humain) et comparer les modèles dessus. Ordre de grandeur du coût : un arbitrage ≈ 2–3 k tokens d'entrée (dont l'essentiel caché) + ~200 de sortie → une fraction de centime par action avec Haiku ; le quota par joueur est le vrai garde-fou.
- Job planifié hebdomadaire : Laravel scheduler (
routes/console.php+schedule:run), job en file d'attente, transactionnel. - Chaque tick est journalisé (
econ_ticks,econ_tick_entries) et rejouable en lecture ; en cas d'échec, rollback complet du tick. - Les règles de production (infrastructure → ressources) sont des données, pas du code : table
infra_typesavec les rendements, éditable depuis Filament.
- Données en base (
star_systems,planets,planet_statespar ère), rendu client : SVG interactif (zoom/pan via viewBox) tant que < ~200 systèmes ; passage canvas/WebGL seulement si besoin réel. 🔶 - Pas de tuiles ni de serveur carto : la galaxie est un espace 2D abstrait, pas une carte géographique.
- Table
notifications+ Laravel Reverb (WebSockets) pour la cloche in-app (story #15). - Le chat (#38) et les jets de dés utilisent le même canal Reverb par sujet.
Les tables à ajouter, regroupées par spec (détail dans chaque page) :
| Domaine | Tables nouvelles |
|---|---|
| Système-de-jeu |
dice_rolls, action_checks, gm_requests, damage_events
|
| Personnages-et-compagnons |
companions, character_reviews
|
| Économie |
resources_balances, infrastructures, infra_types, enterprises (+shares/sites), employments, econ_ticks, econ_tick_entries, econ_events
|
| Carte-galactique |
star_systems, planet_states, planet_control_history (extension de planets) |
| Forum |
topic_participants, topic_follows, notifications (+colonnes sur topics/posts) |
| Wiki-Univers |
wiki_article_revisions, wiki_proposals (+colonnes sur wiki_articles) |
Chaque ajout arrive par migration Laravel dans api/database/migrations/, avec ses policies dans le même changement.
| Env | Où | Particularités |
|---|---|---|
| Dev local | Postgres Docker (npm run docker:up) + npm run dev:api / dev:front
|
Seeders Laravel |
| CI | GitHub Actions | Tests PHPUnit (api) + typecheck & build (front) |
| Prod | VPS Docker Compose (docker-compose.prod.yml) |
swor.fr (front) + api.swor.fr (Laravel) via Nginx |
🔶 Un environnement de staging pourra devenir nécessaire quand il y aura plusieurs contributeurs actifs.
Game design
Plateforme
Développement
Liens