tilttek / game-engine-bundle
Online tables for Symfony on tilttek/game-engine: logs kept by Doctrine DBAL, states cached in a PSR-6 pool, a lock per table, changes published on Mercure with identifiers only, the view of a seat and the log of a finished table, commands to create tables and verify logs, and a Stimulus controller
Package info
github.com/TiltTek/game-engine-bundle
Type:symfony-bundle
pkg:composer/tilttek/game-engine-bundle
Requires
- php: >=8.5
- doctrine/dbal: ^4.5
- symfony/config: ^8.2
- symfony/dependency-injection: ^8.2
- tilttek/game-engine: ^0.1@dev
Requires (Dev)
- doctrine/doctrine-bundle: ^3.3
- doctrine/orm: ^3.7
- phpunit/phpunit: ^13.4
- psr/cache: ^3.0
- psr/log: ^3.0
- symfony/asset-mapper: ^8.2
- symfony/cache: ^8.2
- symfony/clock: ^8.2
- symfony/console: ^8.2
- symfony/event-dispatcher: ^8.2
- symfony/framework-bundle: ^8.2
- symfony/http-foundation: ^8.2
- symfony/http-kernel: ^8.2
- symfony/lock: ^8.2
- symfony/mercure: ^0.10
- symfony/routing: ^8.2
- symfony/translation: ^8.2
- symfony/twig-bundle: ^8.2
- symfony/ux-twig-component: ^3.7
- symfony/yaml: ^8.2
- twig/twig: ^3.21
Suggests
- doctrine/orm: To add the tables of the logs to the schema the ORM generates, and so to the migrations
- phil/ux-kit: For the recipes Card and Badge the template of a table is built of, through the Symfony UX Toolkit
- symfony/asset-mapper: For the Stimulus controller that reads the view again at each update
- symfony/cache: To cache the states of the tables in a pool shared by every process
- symfony/console: For the commands that create the tables of the logs and verify a log
- symfony/framework-bundle: For the endpoints of the views and of the logs, and their routes
- symfony/lock: For the lock that keeps two moves at one table apart
- symfony/mercure-bundle: To publish every change of a table on its Mercure topic
- symfony/twig-bundle: For the Twig functions and the template of a table
- symfony/ux-twig-component: For the template of a table, built of the recipes of a kit of the Symfony UX Toolkit
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-13 22:47:26 UTC
README
Online tables for Symfony on tilttek/game-engine: logs on Doctrine DBAL, states in a shared cache, a lock per table, every change pushed by Mercure, and the view of each seat read from the server.
tilttek/game-engine-bundle runs the tables of tilttek/game-engine in a Symfony application. Every service that
implements the library's Game contract is a game. The log of each table — the truth of the table, with its seed —
is kept by Doctrine DBAL on MySQL, PostgreSQL or SQLite, appended in one statement that refuses a concurrent move; the
current state is cached in a PSR-6 pool shared by every process, as JSON text rather than a PHP object; each move is
made under the lock of its table when a lock factory is named. A read costs the row of the table and the moves made
since its cached state, read window by window and at most once per request; a state built before a move was taken back
is never served.
The server checks every move and Mercure pushes: each change is published privately on the topic of its table with identifiers and counters only, and each player's page reads the view of its seat from an endpoint that asks the application who the reader is. The log of a table, seed included, is given only once its game is over, for anyone to verify every draw against the commitment shown at the opening, and no move is taken back after that. Seats are opaque identifiers of the table: one that looks like an email address or a reference to a member is refused. A template built of the recipes of the PHIL UX kit and a Stimulus controller show the table and read the view again at each update.
The library alone suits an application without Symfony.
Status
| Part | State |
|---|---|
TilttekGameEngineBundle and its configuration tilttek_game_engine |
Implemented and tested |
| The games gathered from the container, the library's role-playing scene on demand | Implemented and tested |
DbalLogStore on MySQL, PostgreSQL and SQLite, its tables in the generated schema |
Implemented and tested |
CacheStateCache, the states in a shared PSR-6 pool as JSON text, written under the lock of their key |
Implemented and tested |
SymfonyTableLock and GameTables, the moves under the lock of their table |
Implemented and tested |
SeatIdentifiers, opaque seat identifiers only |
Implemented and tested |
MercureTablePublisher, every change on the topic of its table |
Implemented and tested |
TableController, the view of a seat and the log of a finished table, through the application's ViewerResolver |
Implemented and tested |
tilttek:game-engine:setup and tilttek:game-engine:verify |
Implemented and tested |
The template of a table, its Twig functions and the Stimulus controller game-table |
Implemented and tested |
The Flex recipe, in recipe/ |
Written |
Documentation
| Document | What it covers |
|---|---|
| Installation | Requirements, the recipe, the tables of the logs, the games, the routes, the controller and the kit. |
| Configuration | Every option, with an example. |
| Storage | The logs on Doctrine DBAL, the state cache, one read per request, the lock, and opaque seat identifiers. |
| Live tables | Mercure, the viewer, the endpoints, the template and the Stimulus controller. |
| Commands | Creating the tables of the logs and verifying a log. |
| Extension points | The services to replace, the tags to add to, and when they are stable. |
| Testing | The bundle's tests, the servers its integration tests read, and testing a game. |
| Reference | Every class and file of the bundle. |
Quick start
# 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); }
Requirements
PHP 8.5 or later and Symfony 8.2 or later.
Contributing
Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.
License
MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Tilttek project. See LICENSE.