# 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.