Aller au contenu

tilttek/game-engine-bundle

✅ publié

Des tables en ligne pour Symfony sur tilttek/game-engine : des journaux sur Doctrine DBAL, des états dans un cache partagé, un verrou par table, chaque changement poussé par Mercure, et la vue de chaque siège lue depuis le serveur.

tilttek/game-engine-bundle fait tourner les tables de tilttek/game-engine dans une application Symfony. Chaque service qui implémente le contrat Game de la bibliothèque est un jeu. Le journal de chaque table — la vérité de la table, avec son germe — est conservé par Doctrine DBAL sur MySQL, PostgreSQL ou SQLite, ajouté en une seule instruction qui refuse un coup concurrent ; l'état courant est mis en cache dans un pool PSR-6 partagé par tous les processus, sous forme de texte JSON plutôt que d'objet PHP ; chaque coup est joué sous le verrou de sa table quand une fabrique de verrous est nommée. Une lecture coûte la ligne de la table et les coups faits depuis son état en cache, lus fenêtre par fenêtre et au plus une fois par requête ; un état construit avant qu'un coup soit repris n'est jamais servi.

Le serveur vérifie chaque coup et Mercure pousse : chaque changement est publié en privé sur le sujet de sa table, avec des identifiants et des compteurs seulement, et la page de chaque joueur lit la vue de son siège depuis un point de terminaison qui demande à l'application qui est le lecteur. Le journal d'une table, germe compris, n'est donné qu'une fois sa partie terminée, pour que chacun vérifie chaque tirage contre l'engagement montré à l'ouverture, et aucun coup n'est repris après cela. Les sièges sont des identifiants opaques de la table : un identifiant qui ressemble à une adresse courriel ou à une référence à un membre est refusé. Un gabarit construit avec les recettes du kit PHIL UX et un contrôleur Stimulus affichent la table et relisent la vue à chaque mise à jour.

La bibliothèque seule convient à une application sans Symfony.

État

PartieÉtat
TilttekGameEngineBundle et sa configuration tilttek_game_engineImplémenté et testé
Les jeux rassemblés depuis le conteneur, la scène de jeu de rôle de la bibliothèque sur demandeImplémenté et testé
DbalLogStore sur MySQL, PostgreSQL et SQLite, ses tables dans le schéma généréImplémenté et testé
CacheStateCache, les états dans un pool PSR-6 partagé sous forme de texte JSON, écrits sous le verrou de leur cléImplémenté et testé
SymfonyTableLock et GameTables, les coups sous le verrou de leur tableImplémenté et testé
SeatIdentifiers, identifiants de siège opaques seulementImplémenté et testé
MercureTablePublisher, chaque changement sur le sujet de sa tableImplémenté et testé
TableController, la vue d'un siège et le journal d'une table terminée, par le ViewerResolver de l'applicationImplémenté et testé
tilttek:game-engine:setup et tilttek:game-engine:verifyImplémenté et testé
Le gabarit d'une table, ses fonctions Twig et le contrôleur Stimulus game-tableImplémenté et testé
La recette Flex, dans recipe/Écrite

Documentation

DocumentContenu
InstallationLes prérequis, la recette, les tables des journaux, les jeux, les routes, le contrôleur et le kit.
ConfigurationChaque option, avec un exemple.
StockageLes journaux sur Doctrine DBAL, le cache d'états, une lecture par requête, le verrou, et les identifiants de siège opaques.
Tables en directMercure, le lecteur, les points de terminaison, le gabarit et le contrôleur Stimulus.
CommandesCréer les tables des journaux et vérifier un journal.
Points d'extensionLes services à remplacer, les étiquettes à compléter, et quand ils sont stables.
TestsLes tests du bundle, les serveurs que lisent ses tests d'intégration, et comment tester un jeu.
RéférenceChaque classe et chaque fichier du bundle.

Démarrage rapide

# config/packages/tilttek_game_engine.yaml
tilttek_game_engine:
    lock: { factory: lock.factory }
    mercure: { enabled: true }
    view: { resolver: App\Game\SeatOfTheMember }
public function move(GameTables $tables, string $table, Request $request): Response
{
    $seat = $this->seating->seatOf($table, $this->getUser());
    $tables->play($table, new Move('chess.move', $seat, ['from' => 'e2', 'to' => 'e4']), $request->getPayload()->getInt('seen'));

    return new Response(null, Response::HTTP_NO_CONTENT);
}

Prérequis

PHP 8.5 ou une version plus récente, et Symfony 8.2 ou une version plus récente.

Contribuer

Les contributions sont les bienvenues sur le monodépôt de PHIL : lisez le guide de contribution et le code de conduite, en anglais. Signalez une vulnérabilité en privé, comme l'explique la politique de sécurité, jamais dans un ticket public.

Licence

MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Tilttek project. Voir LICENSE.