Jacob Schmidt 827f3303a2 feat: add initial Docus setup and sync tool for documentation generation
- Created package.json for Docus with necessary scripts and dependencies.
- Implemented sync-docus-docs.mjs to automate the generation of documentation files from source markdown.
- Defined mappings for generated pages and virtual routes to ensure proper linking in documentation.
- Added static content files for the documentation structure, including navigation and index pages.
2026-04-21 16:07:27 -05:00

5.6 KiB

Development Guide

This guide covers the usual path for adding or changing a Forge module.

Local Checks

Before running storage-backed workflows locally, complete SurrealDB Setup.

Run these before pushing Rust or extension changes:

cargo fmt --check
cargo check
cargo test
cargo build
cargo clippy --all-targets --all-features -- -D warnings

Run this after changing browser UI sources:

npm run build:webui

Build Arma packages with:

.\build-arma.ps1

Module Boundaries

Keep each layer responsible for one kind of work:

<th>
  Owns
</th>

<th>
  Avoid
</th>
<td>
  Data structures, serde defaults, validation helpers.
</td>

<td>
  Database calls, SQF-specific context.
</td>
<td>
  Repository traits and in-memory stores.
</td>

<td>
  SurrealDB-specific code.
</td>
<td>
  Business rules, workflow orchestration, structured results.
</td>

<td>
  Arma engine calls, extension transport details.
</td>
<td>
  Command parsing, context resolution, SurrealDB implementations, serialization to SQF.
</td>

<td>
  Business rules that belong in services.
</td>
<td>
  Server SQF lifecycle, game-object integration, calls into <code>
    forge_server
  </code>
  
  .
</td>

<td>
  Direct database logic.
</td>
<td>
  Client UI, keybinds, local UI events.
</td>

<td>
  Authoritative persistence.
</td>
Layer
lib/models
lib/repositories
lib/services
arma/server/extension
arma/server/addons
arma/client/addons

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:

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.