Add architecture flow diagram in SVG format
This commit is contained in:
parent
c176837a2c
commit
df325e2114
@ -6,6 +6,8 @@ handlers, and optional browser UI.
|
||||
|
||||
## Runtime Flow
|
||||
|
||||

|
||||
|
||||
```text
|
||||
Arma client UI or SQF action
|
||||
-> client addon bridge
|
||||
@ -27,7 +29,7 @@ request and response chunks through the extension transport module.
|
||||
### Client Addons
|
||||
|
||||
Client addons live under `arma/client/addons`. They own local player UX,
|
||||
keybinds, browser UI dialogs, and UI-to-SQF event handling. When a client needs
|
||||
keybinds, browser UI dialogs, and UI-to-SQF event handling. When a client needs`
|
||||
durable or authoritative state, it routes work to the matching server addon
|
||||
instead of touching persistence directly.
|
||||
|
||||
|
||||
101
docs/SURREALDB_SETUP.md
Normal file
101
docs/SURREALDB_SETUP.md
Normal file
@ -0,0 +1,101 @@
|
||||
# SurrealDB Setup
|
||||
|
||||
Forge uses SurrealDB for durable storage. The Rust server extension connects to
|
||||
SurrealDB on startup and applies Forge schema modules automatically, so setup
|
||||
comes down to running a reachable database and matching the Forge config.
|
||||
|
||||
## Choose the Right Path
|
||||
|
||||
### Developer or Server Operator
|
||||
|
||||
Use this path if you are building Forge, running a local test server, or
|
||||
hosting the live Arma server.
|
||||
|
||||
Official SurrealDB resources:
|
||||
|
||||
- [SurrealDB install page](https://surrealdb.com/install)
|
||||
- [SurrealDB CLI `start` reference](https://surrealdb.com/docs/reference/cli/surrealdb-cli/commands/start)
|
||||
|
||||
Install SurrealDB with the official method for your platform:
|
||||
|
||||
```powershell
|
||||
# Windows
|
||||
iwr https://windows.surrealdb.com -useb | iex
|
||||
```
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
brew install surrealdb/tap/surreal
|
||||
```
|
||||
|
||||
```bash
|
||||
# Linux
|
||||
curl -sSf https://install.surrealdb.com | sh
|
||||
```
|
||||
|
||||
For Forge, start a persistent local database instead of the default in-memory
|
||||
mode:
|
||||
|
||||
```powershell
|
||||
surreal start surrealkv://forge.db --bind 127.0.0.1:8000 --user root --pass root
|
||||
```
|
||||
|
||||
Then copy `arma/server/extension/config.example.toml` to `config.toml` next to
|
||||
`forge_server_x64.dll` and keep the values aligned with the database you
|
||||
started:
|
||||
|
||||
```toml
|
||||
[surreal]
|
||||
endpoint = "127.0.0.1:8000"
|
||||
namespace = "forge"
|
||||
database = "main"
|
||||
username = "root"
|
||||
password = "root"
|
||||
connect_timeout_ms = 5000
|
||||
```
|
||||
|
||||
After that:
|
||||
|
||||
1. Start the Arma server with the Forge extension enabled.
|
||||
2. Let the extension connect and apply the Forge schema modules.
|
||||
3. Verify the connection state:
|
||||
|
||||
```sqf
|
||||
"forge_server" callExtension ["status", []];
|
||||
"forge_server" callExtension ["surreal:status", []];
|
||||
```
|
||||
|
||||
If you change the endpoint, namespace, database, username, or password in
|
||||
SurrealDB, change the same values in Forge's `config.toml`.
|
||||
|
||||
### Mission Designer or Community Manager/Leader
|
||||
|
||||
Use this path if you mostly need to inspect, query, or adjust data for a test
|
||||
or live server and you are not changing Forge source code.
|
||||
|
||||
Official SurrealDB resources:
|
||||
|
||||
- [Surrealist installation](https://surrealdb.com/docs/explore/surrealist/installation)
|
||||
- [Surrealist web app](https://app.surrealdb.com)
|
||||
- [Surrealist local database serving](https://surrealdb.com/docs/explore/surrealist/concepts/local-database-serving)
|
||||
|
||||
Recommended approach:
|
||||
|
||||
1. Install **Surrealist Desktop**. It is the better fit for Forge because the
|
||||
official docs note that the web app can be limited when connecting to
|
||||
`localhost` or non-HTTPS endpoints.
|
||||
2. Connect Surrealist to the same database Forge uses.
|
||||
3. Use the values from the server's `config.toml`:
|
||||
|
||||
```text
|
||||
Endpoint: http://127.0.0.1:8000
|
||||
Namespace: forge
|
||||
Database: main
|
||||
Username: root
|
||||
Password: root
|
||||
```
|
||||
|
||||
If you need your own local sandbox instead of connecting to an existing Forge
|
||||
server, install SurrealDB first and follow the developer/server-operator path
|
||||
above. Surrealist Desktop can also launch a local database for you after the
|
||||
`surreal` executable is installed and available on your `PATH`.
|
||||
@ -6,6 +6,8 @@ handlers, and optional browser UI.
|
||||
|
||||
## Runtime Flow
|
||||
|
||||

|
||||
|
||||
```text
|
||||
Arma client UI or SQF action
|
||||
-> client addon bridge
|
||||
@ -27,7 +29,7 @@ request and response chunks through the extension transport module.
|
||||
### Client Addons
|
||||
|
||||
Client addons live under `arma/client/addons`. They own local player UX,
|
||||
keybinds, browser UI dialogs, and UI-to-SQF event handling. When a client needs
|
||||
keybinds, browser UI dialogs, and UI-to-SQF event handling. When a client needs`
|
||||
durable or authoritative state, it routes work to the matching server addon
|
||||
instead of touching persistence directly.
|
||||
|
||||
|
||||
@ -4,9 +4,6 @@ Forge uses SurrealDB for durable storage. The Rust server extension connects to
|
||||
SurrealDB on startup and applies Forge schema modules automatically, so setup
|
||||
comes down to running a reachable database and matching the Forge config.
|
||||
|
||||
Forge currently targets the SurrealDB `3.x` server line. Do not pair this
|
||||
build of the extension with a `2.x` SurrealDB server.
|
||||
|
||||
## Choose the Right Path
|
||||
|
||||
### Developer or Server Operator
|
||||
@ -17,7 +14,23 @@ hosting the live Arma server.
|
||||
Official SurrealDB resources:
|
||||
|
||||
- [SurrealDB install page](https://surrealdb.com/install)
|
||||
- [SurrealDB CLI `start` reference](https://surrealdb.com/docs/reference/cli/surrealdb-cli/commands/start)
|
||||
- [SurrealDB CLI `start` reference](https://surrealdb.com/docs/surrealdb/cli/start)
|
||||
|
||||
Forge also includes helper scripts under `arma/server/surrealdb`:
|
||||
|
||||
```powershell
|
||||
cd arma/server/surrealdb
|
||||
.\UpdateMe.bat
|
||||
.\RunMe.bat
|
||||
```
|
||||
|
||||
On Linux or macOS:
|
||||
|
||||
```bash
|
||||
cd arma/server/surrealdb
|
||||
./setup.sh
|
||||
./run.sh
|
||||
```
|
||||
|
||||
Install SurrealDB with the official method for your platform:
|
||||
|
||||
@ -40,9 +53,12 @@ For Forge, start a persistent local database instead of the default in-memory
|
||||
mode:
|
||||
|
||||
```powershell
|
||||
surreal start surrealkv://forge.db --bind 127.0.0.1:8000 --user root --pass root
|
||||
surreal start --user root --pass root --bind 127.0.0.1:8000 rocksdb://forge.db
|
||||
```
|
||||
|
||||
`root`/`root` is only the local development default. For a public or shared
|
||||
server, set a real password and keep `config.toml` aligned.
|
||||
|
||||
Then copy `arma/server/extension/config.example.toml` to `config.toml` next to
|
||||
`forge_server_x64.dll` and keep the values aligned with the database you
|
||||
started:
|
||||
|
||||
98
docus/content/2.server-extension/3.common.md
Normal file
98
docus/content/2.server-extension/3.common.md
Normal file
@ -0,0 +1,98 @@
|
||||
# Forge Server Common
|
||||
|
||||
## Overview
|
||||
The common addon provides shared SQF utilities used by server-side Forge
|
||||
addons. It contains lightweight helpers only; gameplay domain state belongs in
|
||||
the specific domain addons or the Rust extension.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
|
||||
## Main Components
|
||||
- `fnc_baseStore.sqf` provides shared hash-map object behavior such as JSON
|
||||
conversion.
|
||||
- `fnc_eventBus.sqf` provides a framework-wide in-process event bus for
|
||||
cross-addon notifications.
|
||||
- `fnc_log.sqf` standardizes server log messages.
|
||||
- `fnc_getPlayer.sqf` resolves online players by UID.
|
||||
- `fnc_formatNumber.sqf` formats numeric values for notifications and UI text.
|
||||
- `fnc_generateHash.sqf` and `fnc_generateSecureData.sqf` provide hashing and
|
||||
random data helpers.
|
||||
- `fnc_timeToSeconds.sqf` converts time values into seconds.
|
||||
|
||||
## Notes
|
||||
Keep this addon free of domain-specific behavior. If a helper needs actor,
|
||||
bank, org, task, store, or CAD state, it belongs in that addon instead.
|
||||
|
||||
## Event Bus
|
||||
The event bus is initialized as `forge_server_common_EventBus` during store
|
||||
bootstrap. It is synchronous and in-process: listeners run immediately when an
|
||||
event is emitted.
|
||||
|
||||
### Event Naming
|
||||
Use lower-case dot-separated names:
|
||||
|
||||
- `<domain>.<entity>.<action>` for domain events, such as `cad.assignment.assigned`
|
||||
- `<domain>.<action>` for simple lifecycle events, such as `task.started`
|
||||
|
||||
Prefer past-tense action names for events that report completed state changes:
|
||||
`created`, `started`, `assigned`, `acknowledged`, `declined`, `completed`,
|
||||
`failed`, `cleared`, `updated`, `closed`.
|
||||
|
||||
Payloads should be hash maps and should include stable identifiers first:
|
||||
`taskID`, `requestID`, `groupID`, `uid`, `orgID`, or `accountID` as appropriate.
|
||||
The event bus adds `event`, `source`, and `timestamp` when the event is emitted.
|
||||
|
||||
### Current Events
|
||||
Task lifecycle:
|
||||
- `task.created`
|
||||
- `task.started`
|
||||
- `task.completed`
|
||||
- `task.failed`
|
||||
- `task.cleared`
|
||||
|
||||
Task rewards and notifications:
|
||||
- `task.reward.requested`
|
||||
- `task.reward.applied`
|
||||
- `task.reward.failed`
|
||||
- `task.rating.applied`
|
||||
- `task.rating.failed`
|
||||
- `task.notification.requested`
|
||||
- `task.reward.notification.requested`
|
||||
|
||||
CAD state:
|
||||
- `cad.assignment.assigned`
|
||||
- `cad.assignment.created`
|
||||
- `cad.assignment.acknowledged`
|
||||
- `cad.assignment.declined`
|
||||
- `cad.assignment.closed`
|
||||
- `cad.request.submitted`
|
||||
- `cad.request.closed`
|
||||
- `cad.group.updated`
|
||||
|
||||
Client sync and notification requests:
|
||||
- `notification.requested`
|
||||
- `bank.account.sync.requested`
|
||||
- `org.sync.requested`
|
||||
- `locker.sync.requested`
|
||||
- `locker.va.sync.requested`
|
||||
- `garage.vgarage.sync.requested`
|
||||
|
||||
```sqf
|
||||
private _token = EGVAR(common,EventBus) call ["on", [
|
||||
"task.completed",
|
||||
{
|
||||
params ["_event"];
|
||||
["INFO", format ["Task completed: %1", _event getOrDefault ["taskID", ""]]] call EFUNC(common,log);
|
||||
},
|
||||
"example"
|
||||
]];
|
||||
|
||||
EGVAR(common,EventBus) call ["emit", [
|
||||
"task.completed",
|
||||
createHashMapFromArray [["taskID", "task_001"]],
|
||||
createHashMapFromArray [["source", "task"]]
|
||||
]];
|
||||
|
||||
EGVAR(common,EventBus) call ["off", [_token]];
|
||||
```
|
||||
@ -199,10 +199,254 @@ Available task modules:
|
||||
- `FORGE_Module_Hostage`: sync to `FORGE_Module_Hostages` and
|
||||
`FORGE_Module_Shooters`.
|
||||
- `FORGE_Module_HVT`: sync directly to HVT units.
|
||||
- `FORGE_Module_Defend`: configure the defense marker and wave settings.
|
||||
- `FORGE_Module_Defend`: configure the defense marker and wave settings; sync
|
||||
enemy units to use their groups as wave templates.
|
||||
|
||||
These modules delegate to `forge_server_task_fnc_startTask`.
|
||||
|
||||
## Mission Designer Guide
|
||||
|
||||
This section is the practical Eden setup guide for mission designers.
|
||||
|
||||
### General Rules
|
||||
|
||||
Use these rules for every Forge task:
|
||||
|
||||
1. Give every task a unique `TaskID`.
|
||||
2. Use area markers for zone-style fields such as:
|
||||
- `DefenseZone`
|
||||
- `DeliveryZone`
|
||||
- `ExtZone`
|
||||
- `CBRNZone`
|
||||
3. Prefer `RECTANGLE` or `ELLIPSE` markers with real size.
|
||||
4. Set success and fail limits explicitly instead of relying on defaults.
|
||||
5. If a task uses a timer, the countdown now waits until the task is assigned.
|
||||
6. Grouping modules such as `Explosive Entities`, `Protected Entities`,
|
||||
`Cargo`, `Hostages`, and `Shooters` should be synced to real world objects,
|
||||
not other logic modules.
|
||||
|
||||
### Attack Task
|
||||
|
||||
Use `FORGE_Module_Attack` when players need to eliminate hostile units or
|
||||
vehicles.
|
||||
|
||||
Setup:
|
||||
|
||||
1. Place the enemy units or vehicles.
|
||||
2. Place `FORGE_Module_Attack`.
|
||||
3. Set `TaskID`.
|
||||
4. Set `LimitSuccess` to the number of targets that must be killed.
|
||||
5. Set `LimitFail` if you want a fail threshold.
|
||||
6. Set rewards, rating, and optional `TimeLimit`.
|
||||
7. Sync the attack module directly to the target units or vehicles.
|
||||
|
||||
Notes:
|
||||
|
||||
- This module reads its synced entities directly.
|
||||
- `TimeLimit` uses seconds. `0` means no limit.
|
||||
|
||||
### Destroy Task
|
||||
|
||||
Use `FORGE_Module_Destroy` when players must destroy objects, vehicles, or
|
||||
units.
|
||||
|
||||
Setup:
|
||||
|
||||
1. Place the objects, vehicles, or units that must be destroyed.
|
||||
2. Place `FORGE_Module_Destroy`.
|
||||
3. Set `TaskID`.
|
||||
4. Set `LimitSuccess` to the number of targets that must be destroyed.
|
||||
5. Set `LimitFail` if the mission should fail after too many losses.
|
||||
6. Set rewards, rating, and optional `TimeLimit`.
|
||||
7. Sync the destroy module directly to the targets.
|
||||
|
||||
Notes:
|
||||
|
||||
- This module reads its synced entities directly.
|
||||
- `TimeLimit` uses seconds. `0` means no limit.
|
||||
|
||||
### Defuse Task
|
||||
|
||||
Use `FORGE_Module_Defuse` when players must defuse one or more explosives while
|
||||
protecting other entities.
|
||||
|
||||
Required module layout:
|
||||
|
||||
```text
|
||||
[Defuse Task] --> [Explosive Entities] --> explosive objects
|
||||
[Defuse Task] --> [Protected Entities] --> protected objects/vehicles/units
|
||||
```
|
||||
|
||||
Setup:
|
||||
|
||||
1. Place the explosive objects that players must defuse.
|
||||
2. Place `FORGE_Module_Explosives`.
|
||||
3. Sync each explosive object to `FORGE_Module_Explosives`.
|
||||
4. Place the objects, vehicles, or units that must survive.
|
||||
5. Place `FORGE_Module_Protected`.
|
||||
6. Sync each protected entity to `FORGE_Module_Protected`.
|
||||
7. Place `FORGE_Module_Defuse`.
|
||||
8. Set `TaskID`.
|
||||
9. Set `LimitSuccess` to the number of explosives that must be defused.
|
||||
10. Set `LimitFail` to the number of protected entities that can be lost before failure.
|
||||
11. Set `TimeLimit` to the IED countdown in seconds. This is per-IED countdown behavior, not a global mission timer.
|
||||
12. Set rewards, rating, and end-state options.
|
||||
13. Sync `FORGE_Module_Defuse` to `FORGE_Module_Explosives`.
|
||||
14. Sync `FORGE_Module_Defuse` to `FORGE_Module_Protected`.
|
||||
|
||||
Notes:
|
||||
|
||||
- The module reads grouped objects from the `Explosive Entities` and
|
||||
`Protected Entities` modules, not from direct object syncs.
|
||||
- Logic objects are filtered out already, so only real explosives and protected
|
||||
entities are counted.
|
||||
- The ACE defuse event is wired to the task system and resolves IEDs back to
|
||||
the correct task.
|
||||
|
||||
### Delivery Task
|
||||
|
||||
Use `FORGE_Module_Delivery` when players must move cargo into a delivery zone.
|
||||
|
||||
Required module layout:
|
||||
|
||||
```text
|
||||
[Delivery Task] --> [Cargo] --> cargo objects
|
||||
```
|
||||
|
||||
Setup:
|
||||
|
||||
1. Place the cargo objects.
|
||||
2. Create an area marker for the delivery zone.
|
||||
3. Place `FORGE_Module_Cargo`.
|
||||
4. Sync each cargo object to `FORGE_Module_Cargo`.
|
||||
5. Place `FORGE_Module_Delivery`.
|
||||
6. Set `TaskID`.
|
||||
7. Set `DeliveryZone` to the marker name.
|
||||
8. Set `LimitSuccess` to the number of cargo objects that must arrive.
|
||||
9. Set `LimitFail` to the number of cargo objects that can be damaged past the fail threshold.
|
||||
10. Set rewards, rating, and optional `TimeLimit`.
|
||||
11. Sync `FORGE_Module_Delivery` to `FORGE_Module_Cargo`.
|
||||
|
||||
Notes:
|
||||
|
||||
- The runtime checks `inArea DeliveryZone`, so the zone must be an area marker.
|
||||
|
||||
### Hostage Task
|
||||
|
||||
Use `FORGE_Module_Hostage` when players must rescue hostages and move them to
|
||||
an extraction zone.
|
||||
|
||||
Required module layout:
|
||||
|
||||
```text
|
||||
[Hostage Task] --> [Hostage Entities] --> hostage units
|
||||
[Hostage Task] --> [Shooter Entities] --> hostile shooter units
|
||||
```
|
||||
|
||||
Setup:
|
||||
|
||||
1. Place the hostage AI units.
|
||||
2. Place the hostile shooter AI units.
|
||||
3. Create an area marker for the extraction zone.
|
||||
4. If using the CBRN variant, create an area marker for the `CBRNZone`.
|
||||
5. Place `FORGE_Module_Hostages`.
|
||||
6. Sync the hostage units to `FORGE_Module_Hostages`.
|
||||
7. Place `FORGE_Module_Shooters`.
|
||||
8. Sync the shooter units to `FORGE_Module_Shooters`.
|
||||
9. Place `FORGE_Module_Hostage`.
|
||||
10. Set `TaskID`.
|
||||
11. Set `ExtZone` to the extraction marker name.
|
||||
12. Set `LimitSuccess` to the number of hostages that must be rescued.
|
||||
13. Set `LimitFail` to the number of hostages that can be lost before failure.
|
||||
14. Set `Execution` or `CBRN` as needed for the mission variant.
|
||||
15. If `CBRN` is enabled, set `CBRNZone`.
|
||||
16. Set rewards, rating, and optional `TimeLimit`.
|
||||
17. Sync `FORGE_Module_Hostage` to `FORGE_Module_Hostages`.
|
||||
18. Sync `FORGE_Module_Hostage` to `FORGE_Module_Shooters`.
|
||||
|
||||
Notes:
|
||||
|
||||
- Hostages and shooters are filtered to real units only.
|
||||
- Hostages are protected immediately on task registration to avoid startup race conditions.
|
||||
- The hostage timer now waits until the task is assigned before counting down.
|
||||
- `ExtZone` is checked with `inArea`, so it must be an area marker.
|
||||
|
||||
### HVT Task
|
||||
|
||||
Use `FORGE_Module_HVT` when players must capture or eliminate a high-value
|
||||
target.
|
||||
|
||||
Setup:
|
||||
|
||||
1. Place the HVT unit or units.
|
||||
2. If using capture mode, create an area marker for the extraction zone.
|
||||
3. Place `FORGE_Module_HVT`.
|
||||
4. Set `TaskID`.
|
||||
5. Set `CaptureHVT` as needed:
|
||||
- enabled for capture/extract
|
||||
- disabled for kill/eliminate
|
||||
6. If using capture mode, set `ExtZone` to the extraction marker name.
|
||||
7. Set `LimitSuccess` to the number of HVTs that must be captured or eliminated.
|
||||
8. Set `LimitFail` if the mission should fail after too many HVT deaths in capture mode.
|
||||
9. Set rewards, rating, and optional `TimeLimit`.
|
||||
10. Sync the HVT module directly to the HVT unit or units.
|
||||
|
||||
Notes:
|
||||
|
||||
- Capture mode uses `ExtZone` with `inArea`, so use an area marker.
|
||||
- Elimination mode does not require an extraction zone.
|
||||
- The HVT timer now waits until the task is assigned before counting down.
|
||||
|
||||
### Defend Task
|
||||
|
||||
Use `FORGE_Module_Defend` when players must hold an area against spawned enemy
|
||||
waves.
|
||||
|
||||
Setup:
|
||||
|
||||
1. Create an area marker for the defense zone.
|
||||
2. Place `FORGE_Module_Defend`.
|
||||
3. Set `TaskID`.
|
||||
4. Set `DefenseZone` to the defense marker name.
|
||||
5. Set `DefendTime` to how long the area must be held.
|
||||
6. Set `WaveCount`.
|
||||
7. Set `WaveCooldown`.
|
||||
8. Set `MinBlufor` to the minimum number of friendlies required in the zone.
|
||||
9. Place one or more enemy groups or units to use as wave templates.
|
||||
10. Sync any unit from each enemy group to the defend module.
|
||||
11. Set rewards, rating, and end-state options.
|
||||
|
||||
Notes:
|
||||
|
||||
- Synced enemy units are treated as templates. Syncing one unit from a group
|
||||
makes the whole group available as a wave composition.
|
||||
- If no enemy units are synced, the defend task falls back to default CSAT
|
||||
infantry waves.
|
||||
- The defend task waits for the required number of BLUFOR to enter the zone
|
||||
before the timer, waves, and empty-zone failure checks begin.
|
||||
- `DefenseZone` must be an area marker.
|
||||
|
||||
### Quick Reference
|
||||
|
||||
Use direct syncs:
|
||||
|
||||
- `Attack Task` -> target units/vehicles
|
||||
- `Destroy Task` -> target objects/vehicles/units
|
||||
- `HVT Task` -> HVT units
|
||||
|
||||
Use grouping modules:
|
||||
|
||||
- `Defuse Task` -> `Explosive Entities`, `Protected Entities`
|
||||
- `Delivery Task` -> `Cargo`
|
||||
- `Hostage Task` -> `Hostage Entities`, `Shooter Entities`
|
||||
|
||||
Use area markers:
|
||||
|
||||
- `DefenseZone`
|
||||
- `DeliveryZone`
|
||||
- `ExtZone`
|
||||
- `CBRNZone`
|
||||
|
||||
## Scripted Start Task
|
||||
|
||||
Use `forge_server_task_fnc_startTask` when creating tasks from modules,
|
||||
|
||||
16801
docus/package-lock.json
generated
16801
docus/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
BIN
docus/public/architecture-flow.png
Normal file
BIN
docus/public/architecture-flow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
1
docus/public/architecture-flow.svg
Normal file
1
docus/public/architecture-flow.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 21 KiB |
Loading…
x
Reference in New Issue
Block a user