# Development Guide This guide covers the usual path for adding or changing a Forge module. ## Repository Workflow Use [Git Workflow](./GIT_WORKFLOW.md) as the source of truth for branch roles, release tags, and mission branch handling. The short version is: - Use `pre-v0.2` for framework development after the `v0.1.0` baseline. - Keep `master` as the clean release baseline branch. - Keep mission folders off `master`; mission work belongs on `missions/local-mission-copies`. - Keep `archive/pre-v0.1-history` read-only unless recovering old work. - Bring reusable mission logic back to framework branches by copying only the needed framework files or code, not by merging the mission branch. Use the workflow helper for the routine checks: ```powershell npm run workflow -- status npm run workflow -- doctor npm run workflow -- switch dev npm run workflow -- switch missions ``` Example framework workflow: ```powershell git switch pre-v0.2 git pull git switch -c feature/cad-task-request # make framework changes git status --short --branch git add arma/client/addons/cad arma/server/addons/cad git commit -m "Add CAD task request workflow" ``` Example mission workflow: ```powershell git switch missions/local-mission-copies # make mission changes git status --short --branch git add arma/forge_pmc_simulator.Tanoa git commit -m "Update PMC simulator mission setup" ``` ## Local Checks Before running storage-backed workflows locally, complete [SurrealDB Setup](./surrealdb-setup.md). A local or dedicated server launch must have SurrealDB running and a `config.toml` beside `forge_server_x64.dll` that matches the running database. 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/.rs`. 2. Export the model from `lib/models/src/lib.rs`. 3. Add repository traits in `lib/repositories/src/.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/.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/.rs`. 13. Register the command group in `arma/server/extension/src/lib.rs`. 14. Add server addon functions under `arma/server/addons/` if SQF needs a module-level API. 15. Add client addon or browser UI files under `arma/client/addons/` 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: "` 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.