forge/docs/DEVELOPMENT_GUIDE.md
2026-04-17 17:39:20 -05:00

130 lines
4.6 KiB
Markdown

# Development Guide
This guide covers the usual path for adding or changing a Forge module.
## Local Checks
Run these before pushing Rust or extension changes:
```powershell
cargo fmt --check
cargo check
cargo test
cargo build
cargo clippy --all-targets --all-features -- -D warnings
```
Run this after changing browser UI sources:
```powershell
npm run build:webui
```
Build Arma packages with:
```powershell
.\build-arma.ps1
```
## Module Boundaries
Keep each layer responsible for one kind of work:
| Layer | Owns | Avoid |
| --- | --- | --- |
| `lib/models` | Data structures, serde defaults, validation helpers. | Database calls, SQF-specific context. |
| `lib/repositories` | Repository traits and in-memory stores. | SurrealDB-specific code. |
| `lib/services` | Business rules, workflow orchestration, structured results. | Arma engine calls, extension transport details. |
| `arma/server/extension` | Command parsing, context resolution, SurrealDB implementations, serialization to SQF. | Business rules that belong in services. |
| `arma/server/addons` | Server SQF lifecycle, game-object integration, calls into `forge_server`. | Direct database logic. |
| `arma/client/addons` | Client UI, keybinds, local UI events. | Authoritative persistence. |
## Adding a Domain Module
1. Add the model in `lib/models/src/<module>.rs`.
2. Export the model from `lib/models/src/lib.rs`.
3. Add repository traits in `lib/repositories/src/<module>.rs`.
4. Add in-memory repository support if the service needs tests or hot state.
5. Export the traits from `lib/repositories/src/lib.rs`.
6. Add service logic in `lib/services/src/<module>.rs`.
7. Add focused unit tests for service behavior.
8. Export the service from `lib/services/src/lib.rs`.
9. Add a SurrealDB schema module under `arma/server/extension/src/schema`.
10. Add the concrete storage adapter under `arma/server/extension/src/storage`.
11. Register the storage adapter in `arma/server/extension/src/storage.rs`.
12. Add an extension command group under `arma/server/extension/src/<module>.rs`.
13. Register the command group in `arma/server/extension/src/lib.rs`.
14. Add server addon functions under `arma/server/addons/<module>` if SQF needs a module-level API.
15. Add client addon or browser UI files under `arma/client/addons/<module>` if the module has player-facing UI.
16. Add documentation in `docs/` and module-level READMEs.
## Extension Command Rules
Commands should return one of these forms:
- JSON string for structured results.
- `"true"` or `"false"` for simple existence and boolean operations.
- `"OK"` for successful destructive operations with no response body.
- `"Error: <message>"` for failures.
Prefer stable JSON shapes over ad hoc strings. SQF callers should always check
for the `"Error:"` prefix before parsing JSON.
Example:
```sqf
private _result = "forge_server" callExtension ["actor:get", [getPlayerUID player]];
private _payload = _result select 0;
if (_payload find "Error:" == 0) exitWith {
systemChat format ["Actor request failed: %1", _payload];
};
private _actor = fromJSON _payload;
```
## Persistence Rules
SurrealDB is the durable store. Keep database-specific mapping in the extension
storage adapters, not in services or repository traits.
When changing persisted data:
- Update or add the matching `.surql` schema module.
- Update the concrete storage adapter.
- Preserve existing records when possible through serde defaults or migration
logic.
- Add tests at the service level for behavior, and add storage tests only when
database mapping is the risk.
## Hot-State Rules
Use hot state for data that is read or mutated frequently during a player
session. Hot-state modules usually provide:
- `init` to load durable state into memory.
- `get` to read the runtime copy.
- `override` or focused mutation commands to update the runtime copy.
- `save` to write the runtime copy back to SurrealDB.
- `remove` to evict the runtime copy.
Do not assume hot state is durable until `save` succeeds.
## Web UI Rules
Browser UI source files live under each client addon. Built assets usually land
under that addon's `ui/_site` directory.
Use the existing common bridge in `arma/client/addons/common` when a UI needs
to send events back to SQF. Keep UI state and rendering in JavaScript, and keep
server-authoritative decisions in server SQF or Rust services.
## Documentation Checklist
When adding or changing a module, update:
- `docs/MODULE_REFERENCE.md` for framework-level inventory.
- A module-specific README in the addon directory when SQF or UI usage changes.
- `arma/server/docs/api-reference.md` when extension commands change.
- Existing usage guides when payload shapes or workflows change.