Index
# Creating a library A `mmo.*` library is a package of its own: its own git repository, its own namespace under `MMO\`, its own manifest, tests and documentation. It is mounted in the hub (the MMOFramework clone) as a git submodule under `libs/`. It is not a composer package, and its classes are not found by a PSR-4 autoloader. ## The one command From the hub: ```sh php tools/mmo.php new mmo.weather --description="Forecasts and weather stations." php tools/mmo.php new mmo.weather --dry-run # say what it would write, write nothing ``` It scaffolds the library from the hub's `templates/library`, and adds it to the repository as a submodule. **The name rule** is `mmo.` followed by lowercase letters and digits (`^mmo\.[a-z][a-z0-9]*$`); anything else is refused. `mmo.weather` gives the slug `weather`, the folder `libs/weather`, the namespace `MMO\weather` and the title `Weather`. ## What it writes ``` libs/weather/ mmo.json the manifest src/ bootstrap.php requires every class file, and registers the namespace as a path Weather.php a first class docs/ what the documentation site and the MCP server serve tests/ bootstrap.php unit/TestWeather.php demo/www/ a demo served at http://localhost/MMO/master/libs/weather phpunit.xml README.md AGENTS.md icon.svg ``` ## The manifest ```json { "name": "mmo.weather", "version": "1.0.0", "namespace": "MMO\\weather", "title": "Weather", "description": "Forecasts and weather stations.", "status": "alpha", "documentations": ["docs"], "demo": "demo/www", "tests": "phpunit.xml", "sources": ["src"], "dependencies": {"mmo.core": "20.*"}, "bootstrap": "src/bootstrap.php", "build": "build/{name}.{version}.phar" } ``` `status` is `alpha`, `beta` or `stable`, and is what `list_packages` and the documentation site show. @see <@\MMO\core\PackageManager> for every key and for the build hooks. ## `src/bootstrap.php` **Nothing autoloads on its own.** Every class file is required here, after whatever it extends or uses — the framework only autoloads a class it was not given, and warns when it has to. The returned configuration registers the namespace as a path, so `{MMO\weather}/...` resolves both to `src/` in a checkout and to the same folder inside `packages/mmo.weather.phar` in a release. ```php fragment namespace MMO\weather; require(__DIR__ . '/Weather.php'); require(__DIR__ . '/stations/Station.php'); //after whatever it extends return [ \MMO\core\Application::class => ['paths' => [__NAMESPACE__ => __DIR__]], ]; ``` ## Adding a class Generate it rather than writing it from scratch — the generator writes the file, its `require` in `src/bootstrap.php` and a first test: ```sh php tools/mmo.php make entity entities/Station --lib=weather --prop=name,lat:float,lon:float --unique=name php tools/mmo.php make controller controllers/StationsController --lib=weather --route="GET|stations.json" ``` Without a checkout, this MCP server's `generate_entity_stub`, `generate_controller_stub` and `generate_test_stub` tools return the same code. ## Checking it ```sh cd libs/weather && phpunit # its own suite php tools/mmo.php verify --lib=weather # lint + phpstan + tests on what changed php tools/mmo.php check --lib=weather # what the library is still missing ``` @see Testing.md for the test setup, and NewProject.md for an application rather than a library.