velkuns / game-text-engine
This is a PHP Game Text Engine to create games based on texts, with choices, items, and more.
Installs: 5
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/velkuns/game-text-engine
Requires
- php: 8.3.*||8.4.*||8.5.*
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.89.1
- phpstan/phpstan: ^2.1.31
- phpstan/phpstan-deprecation-rules: ^2.0.3
- phpstan/phpstan-phpunit: ^2.0.7
- phpstan/phpstan-strict-rules: ^2.0.7
- phpunit/phpcov: ^11.0.2
- phpunit/phpunit: ^12.4.1
- shipmonk/composer-dependency-analyser: ^1.8.3
This package is auto-updated.
Last update: 2025-10-30 17:40:19 UTC
README
Why?
This is a PHP Game Text Engine to create games based on texts, with choices, items, and more.
Installation
If you wish to install it in your project, require it via composer:
composer require velkuns/game-text-engine
API Documentation
Game Object
declare(strict_types=1); namespace Application; use Velkuns\GameTextEngine\Api\ItemsApi;use Velkuns\GameTextEngine\Api\PlayerApi;use Velkuns\GameTextEngine\Element\Factory\AbilityFactory;use Velkuns\GameTextEngine\Util\Loader\JsonLoader;use Velunns\GameTextEngine\Api\GameApi; //~ Factories $modifierFactory = new ModifierFactory(); $itemFactory = new ItemFactory($modifierFactory); $conditionFactory = new ConditionsFactory(new ConditionParser(), new ConditionElementResolver(), new ConditionValidator()); $graphFactory = new GraphFactory($conditionFactory); $abilityFactory = new AbilityFactory(); $entityFactory = new EntityFactory( $abilityFactory, new StatusFactory($modifierFactory, $conditionFactory), $itemFactory ); $items = new ItemsApi($itemFactory); $gameApi = new GameApi( new JsonLoader(), new StoryApi($graphFactory), $items, new BestiaryApi($entityFactory, $items), new AbilitiesApi($abilityFactory), new PlayerApi($entityFactory, $items), new CombatApi(new Randomizer(new Mt19937())), ); //~ Load json data (can be from files or strings if came from database) $storyData = $game->loader->fromFile($dataDir . '/stories/test.json'); $itemsData = $game->loader->fromFile($dataDir . '/items.json'); $bestiaryData = $game->loader->fromFile($dataDir . '/bestiary.json'); $abilitiesRulesData = $game->loader->fromFile($dataDir . '/rules/rules_abilities.json'); $statusesRulesData = $game->loader->fromFile($dataDir . '/rules/rules_statuses.json'); $playerData = $game->loader->fromFile($dataDir . '/templates/player.json'); //~ Load data into the game api $gameApi->load($storyData, $itemsData, $bestiaryData, $playerData); //~ Access to the other apis $gameApi->storyApi->[...]; $gameApi->bestiaryApi->[...]; $gameApi->itemsApi->[...]; $gameApi->abilitiesApi->[...]; $gameApi->statusesApi->[...]; $gameApi->playerApi->[...]; //~ Dumping apis into json data /** * @param array{ * story: string, * items: string, * bestiary: string, * abilities: string, * statuses: string, * player: string * } $data Array of json data, to save in files or database */ $data = $gameApi->dump(/* true */); // true to pretty json output //~ Exporting story graph into DOT data $gameApi->exporter->toFile($gameApi->storyApi->graph, [...]); // export story graph to file $string = $gameApi->exporter->toString($gameApi->storyApi->graph); // export story graph to string //~ Game API read $source = 'text_1'; $target = 'text_2'; $gameApi->read($source, $target);
Loader (to load data from files / strings):
<?php declare(strict_types=1); namespace Application; use Velkuns\GameTextEngine\Util\Loader\JsonLoader; $loader = new JsonLoader(); //~ To load data from a file $data = $loader->fromFile('/path/to/data.json'); //~ To load data from a string (JSON format, can be stored in database) $data = $loader->fromString('{"key": "value"}');
Items API
<?php declare(strict_types=1); namespace Application; // [... game api init code here ... ] //~ Get an item by its name $item = $game->items->get('Rusty Sword'); $staff = $itemFactory->from(['name' => 'Staff', ...]); $gameApi->items->set($staff); // Adds or replaces the item in the items dictionary $gameApi->items->remove($staff->getName()); // Removes the item from the items dictionary
Bestiary API
<?php declare(strict_types=1); namespace Application; // [... game api init code here ... ] //~ Get a creature by its name $entity = $gameApi->bestiary->get('Goblin'); $goblinWarrior = $entityFactory->from(['name' => 'Goblin Warrior', ...]); $gameApi->bestiary->set($goblinWarrior); // Adds or replaces the creature in the bestiary $gameApi->bestiary->remove('Goblin'); // Removes the creature from the bestiary
Abilities API
<?php declare(strict_types=1); namespace Application; // [... game api init code here ... ] //~ Return all abilities: array{bases: array<string, AbilityInterface>, compounds: array<string, AbilityInterface>} $abilities = $gameApi->abilities->getAll(); $ability = $gameApi->abilities->get('strength'); // Get one ability (cloned) $gameApi->abilities->set($ability); // Set an ability $gameApi->abilities->remove('strength');
Statuses API
<?php declare(strict_types=1); namespace Application; // [... game api init code here ... ] //~ Return all statuses: array<string, array<string, StatusInterface>> $statuses = $gameApi->statuses->getAll(); $status = $gameApi->statuses->get('skill', 'Goblin Hunter'); // Get one status (cloned) $gameApi->statuses->set($status); // Set an ability $gameApi->statuses->remove('skill', 'Goblin Hunter');
Story API
<?php declare(strict_types=1); namespace Application; // [... game api init code here ... ] //~ Start the story - retrieve the first node of the story $text = $gameApi->story->start(); // define $player before //~ Get possible choices $choices = $gameApi->story->getPossibleChoices($node->id, $player); //~ Then display choices to the player, get his choice and advance the story $playerChoice = $choices[0]; $nextText = $gameApi->story->goto($playerChoice->source, $playerChoice->target, $player/*[, $enemy]*/); // A validation is made to be sure the choice is valid
Player API
<?php declare(strict_types=1); namespace Application; // [... game api init code here ... ] //~ Create a new player based on the given data $data = [ 'name' => 'New Hero', 'age' => 25, // optional, default 20 'race' => 'elf', // optional, default 'human' 'description' => 'A brave adventurer.', // optional, default '' 'background' => 'Born in a small village.', // optional, default '' 'abilities' => [, 'strength' => 10, 'endurance' => 12, 'agility' => 14, 'intuition' => 13, ], 'inventory' => ['Rusty Sword'], // optional, default [] ]; $gameApi->player->new($data); //~ Get player object $player = $gameApi->player->player;
Combat API
<?php declare(strict_types=1); namespace Application; // [... game api init code here ... ] $enemies = [ $gameApi->bestiary->get('Rat'), // get clone $gameApi->bestiary->get('Rat'), // get clone ]; $logs = $gameApi->combat->start($gameApi->player->player, $enemies); //~ Display combat results // ... your code to display combat turns ...
Access to the Story's graph
<?php declare(strict_types=1); namespace Application; // [... game api init code here ... ] $graph = $gameApi->story->graph; //~ Manipulate graph nodes $graph->addNode(new Node(...)); $graph->removeNode('node_id'); //~ Manipulate graph edges (between nodes). $graph->addEdge(new Edge(...)); $graph->removeEdgeBetweenNodes('node_id_source', 'node_id_target');
Important
When add edges, source node and target node must have already been added to the graph.
Contributing
See the CONTRIBUTING file.
Install / update project
You can install project with the following command:
make install
And update with the following command:
make update
NB: For the components, the composer.lock file is not committed.
Testing & CI (Continuous Integration)
Tests
You can run unit tests (with coverage) on your side with following command:
make php/tests
You can run integration tests (without coverage) on your side with following command:
make php/integration
For prettier output (but without coverage), you can use the following command:
make php/testdox # run tests without coverage reports but with prettified output
Code Style
You also can run code style check with following commands:
make php/cs-check
You also can run code style fixes with following commands:
make php/cs-fix
Check for missing explicit dependencies
You can check if any explicit dependency is missing with the following command:
make php/deps
Static Analysis
To perform a static analyze of your code (with phpstan, lvl 9 at default), you can use the following command:
make php/analyse
CI Simulation
And the last "helper" commands, you can run before commit and push, is:
make ci
License
This project is currently under The MIT License (MIT). See LICENCE file for more information.