feat: Implement task store reset functionality and update documentation for server launch prerequisites
This commit is contained in:
parent
b7f7ae3a01
commit
96718996b2
@ -1,5 +1,6 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
if !(isNil QGVAR(TaskStore)) then { GVAR(TaskStore) call ["resetMissionState", []]; };
|
||||
if (isNil QEGVAR(common,EventBus)) then { call EFUNC(common,eventBus); };
|
||||
if (isNil QGVAR(TaskLifecycleEventLogTokens)) then {
|
||||
private _logTaskLifecycleEvent = {
|
||||
|
||||
@ -37,6 +37,21 @@ GVAR(TaskStore) = createHashMapObject [[
|
||||
["targets", createHashMap]
|
||||
]];
|
||||
|
||||
_self call ["resetMissionState", []];
|
||||
}],
|
||||
["resetMissionState", compileFinal {
|
||||
_self set ["participantRegistry", createHashMap];
|
||||
_self set ["taskLifecycleRegistry", createHashMap];
|
||||
_self set ["taskEntityRegistries", createHashMapFromArray [
|
||||
["cargo", createHashMap],
|
||||
["hostages", createHashMap],
|
||||
["hvts", createHashMap],
|
||||
["ieds", createHashMap],
|
||||
["entities", createHashMap],
|
||||
["shooters", createHashMap],
|
||||
["targets", createHashMap]
|
||||
]];
|
||||
|
||||
// Task extension state is mission-scoped and intentionally reset on
|
||||
// startup rather than being treated as durable account data.
|
||||
["task:reset", []] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
|
||||
@ -44,9 +59,12 @@ GVAR(TaskStore) = createHashMapObject [[
|
||||
!_isSuccess
|
||||
|| { !(_result isEqualType "") }
|
||||
|| { (_result find "Error:") == 0 }
|
||||
) then {
|
||||
) exitWith {
|
||||
["WARNING", "Failed to reset task backend state during task store initialization."] call EFUNC(common,log);
|
||||
false
|
||||
};
|
||||
|
||||
true
|
||||
}],
|
||||
["callTaskStateEnvelope", compileFinal {
|
||||
params [["_function", "", [""]], ["_arguments", [], [[]]]];
|
||||
|
||||
@ -89,6 +89,18 @@ GVAR(AttackTaskBaseClass) = createHashMapFromArray [
|
||||
private _targets = _self getOrDefault ["targets", []];
|
||||
{ !alive _x } count _targets
|
||||
}],
|
||||
["waitForAssignment", compileFinal {
|
||||
private _taskID = _self getOrDefault ["taskID", ""];
|
||||
|
||||
if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
GVAR(TaskStore) call ["isTaskAccepted", [_taskID]]
|
||||
};
|
||||
|
||||
true
|
||||
}],
|
||||
["tick", compileFinal {
|
||||
private _startedAt = _self getOrDefault ["startedAt", -1];
|
||||
private _timeLimit = _self getOrDefault ["timeLimit", 0];
|
||||
@ -136,26 +148,7 @@ GVAR(AttackTaskBaseClass) = createHashMapFromArray [
|
||||
};
|
||||
};
|
||||
|
||||
if (_timeLimit isNotEqualTo 0 && { _useTaskStore }) then {
|
||||
private _catalogEntry = GVAR(TaskStore) call ["getTaskCatalogEntry", [_taskID]];
|
||||
["INFO", format [
|
||||
"Attack task %1 initial state before acceptance wait. Accepted=%2, RequesterUid='%3', Source='%4', TimeLimit=%5s",
|
||||
_taskID,
|
||||
_catalogEntry getOrDefault ["accepted", false],
|
||||
_catalogEntry getOrDefault ["requesterUid", ""],
|
||||
_catalogEntry getOrDefault ["source", ""],
|
||||
_timeLimit
|
||||
]] call EFUNC(common,log);
|
||||
|
||||
["INFO", format ["Attack task %1 waiting for acceptance before starting %2s time limit.", _taskID, _timeLimit]] call EFUNC(common,log);
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
GVAR(TaskStore) call ["isTaskAccepted", [_taskID]]
|
||||
};
|
||||
|
||||
["INFO", format ["Attack task %1 accepted. Starting %2s time limit.", _taskID, _timeLimit]] call EFUNC(common,log);
|
||||
};
|
||||
|
||||
_self call ["waitForAssignment", []];
|
||||
_self call ["markActive", []];
|
||||
|
||||
while { (_self call ["getStatus", []]) isEqualTo "active" } do {
|
||||
|
||||
@ -114,6 +114,18 @@ GVAR(DefuseTaskBaseClass) = createHashMapFromArray [
|
||||
|
||||
true
|
||||
}],
|
||||
["waitForAssignment", compileFinal {
|
||||
private _taskID = _self getOrDefault ["taskID", ""];
|
||||
|
||||
if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
GVAR(TaskStore) call ["isTaskAccepted", [_taskID]]
|
||||
};
|
||||
|
||||
true
|
||||
}],
|
||||
["startIedControllers", compileFinal {
|
||||
if ((_self getOrDefault ["iedControllers", []]) isNotEqualTo []) exitWith { true };
|
||||
|
||||
@ -234,6 +246,7 @@ GVAR(DefuseTaskBaseClass) = createHashMapFromArray [
|
||||
}],
|
||||
["runLoop", compileFinal {
|
||||
_self call ["waitForRequiredEntities", []];
|
||||
_self call ["waitForAssignment", []];
|
||||
_self call ["startIedControllers", []];
|
||||
_self call ["markActive", []];
|
||||
|
||||
|
||||
@ -78,11 +78,10 @@ GVAR(DeliveryTaskBaseClass) = createHashMapFromArray [
|
||||
_self set ["maxDamaged", _maxDamaged];
|
||||
true
|
||||
}],
|
||||
["waitForAssignmentIfTimed", compileFinal {
|
||||
private _timeLimit = _self getOrDefault ["timeLimit", 0];
|
||||
["waitForAssignment", compileFinal {
|
||||
private _taskID = _self getOrDefault ["taskID", ""];
|
||||
|
||||
if (_timeLimit <= 0 || { _taskID isEqualTo "" } || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
@ -175,7 +174,7 @@ GVAR(DeliveryTaskBaseClass) = createHashMapFromArray [
|
||||
}],
|
||||
["runLoop", compileFinal {
|
||||
_self call ["waitForRequiredEntities", []];
|
||||
_self call ["waitForAssignmentIfTimed", []];
|
||||
_self call ["waitForAssignment", []];
|
||||
_self call ["markActive", []];
|
||||
|
||||
while { (_self call ["getStatus", []]) isEqualTo "active" } do {
|
||||
|
||||
@ -69,11 +69,10 @@ GVAR(DestroyTaskBaseClass) = createHashMapFromArray [
|
||||
_self set ["requiredDestroyed", _requiredDestroyed];
|
||||
true
|
||||
}],
|
||||
["waitForAssignmentIfTimed", compileFinal {
|
||||
private _timeLimit = _self getOrDefault ["timeLimit", 0];
|
||||
["waitForAssignment", compileFinal {
|
||||
private _taskID = _self getOrDefault ["taskID", ""];
|
||||
|
||||
if (_timeLimit <= 0 || { _taskID isEqualTo "" } || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
@ -155,7 +154,7 @@ GVAR(DestroyTaskBaseClass) = createHashMapFromArray [
|
||||
}],
|
||||
["runLoop", compileFinal {
|
||||
_self call ["waitForRequiredEntities", []];
|
||||
_self call ["waitForAssignmentIfTimed", []];
|
||||
_self call ["waitForAssignment", []];
|
||||
_self call ["markActive", []];
|
||||
|
||||
while { (_self call ["getStatus", []]) isEqualTo "active" } do {
|
||||
|
||||
@ -37,7 +37,7 @@ GVAR(HVTEntityController) = createHashMapFromArray [
|
||||
if (isNull _entity || { !alive _entity }) exitWith { false };
|
||||
|
||||
_entity setCaptive true;
|
||||
doStop _entity;
|
||||
_entity enableAIFeature ["MOVE", true];
|
||||
true
|
||||
}],
|
||||
["runLoop", compileFinal {
|
||||
|
||||
@ -115,11 +115,10 @@ GVAR(HVTTaskBaseClass) = createHashMapFromArray [
|
||||
_self set ["hvtControllers", _controllers];
|
||||
true
|
||||
}],
|
||||
["waitForAssignmentIfTimed", compileFinal {
|
||||
private _timeLimit = _self getOrDefault ["timeLimit", 0];
|
||||
["waitForAssignment", compileFinal {
|
||||
private _taskID = _self getOrDefault ["taskID", ""];
|
||||
|
||||
if (_timeLimit <= 0 || { _taskID isEqualTo "" } || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
@ -210,8 +209,8 @@ GVAR(HVTTaskBaseClass) = createHashMapFromArray [
|
||||
}],
|
||||
["runLoop", compileFinal {
|
||||
_self call ["waitForRequiredEntities", []];
|
||||
_self call ["waitForAssignment", []];
|
||||
_self call ["startHvtControllers", []];
|
||||
_self call ["waitForAssignmentIfTimed", []];
|
||||
_self call ["markActive", []];
|
||||
|
||||
while { (_self call ["getStatus", []]) isEqualTo "active" } do {
|
||||
|
||||
@ -183,11 +183,10 @@ GVAR(HostageTaskBaseClass) = createHashMapFromArray [
|
||||
_self set ["maxHostageLosses", _maxHostageLosses];
|
||||
true
|
||||
}],
|
||||
["waitForAssignmentIfTimed", compileFinal {
|
||||
private _timeLimit = _self getOrDefault ["timeLimit", 0];
|
||||
["waitForAssignment", compileFinal {
|
||||
private _taskID = _self getOrDefault ["taskID", ""];
|
||||
|
||||
if (_timeLimit <= 0 || { _taskID isEqualTo "" } || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
if (_taskID isEqualTo "" || { !(_self getOrDefault ["useTaskStore", false]) }) exitWith { true };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
@ -337,8 +336,8 @@ GVAR(HostageTaskBaseClass) = createHashMapFromArray [
|
||||
}],
|
||||
["runLoop", compileFinal {
|
||||
_self call ["waitForRequiredEntities", []];
|
||||
_self call ["waitForAssignment", []];
|
||||
_self call ["startHostageControllers", []];
|
||||
_self call ["waitForAssignmentIfTimed", []];
|
||||
_self call ["markActive", []];
|
||||
|
||||
while { (_self call ["getStatus", []]) isEqualTo "active" } do {
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
# Forge Server Configuration
|
||||
# Copy this file to config.toml and place it beside forge_server_x64.dll.
|
||||
# Start SurrealDB before launching the Arma server, and keep these values
|
||||
# aligned with the running database.
|
||||
|
||||
[surreal]
|
||||
endpoint = "127.0.0.1:8000"
|
||||
|
||||
@ -21,7 +21,9 @@ SQF module
|
||||
|
||||
## Configuration
|
||||
|
||||
Copy `config.example.toml` to `config.toml` next to the extension DLL.
|
||||
Copy `config.example.toml` to `config.toml` next to the extension DLL before
|
||||
launching a Forge-enabled server. SurrealDB must also be running before the
|
||||
server starts, and the values in `config.toml` must match that database.
|
||||
|
||||
```toml
|
||||
[surreal]
|
||||
@ -33,6 +35,9 @@ password = "root"
|
||||
connect_timeout_ms = 5000
|
||||
```
|
||||
|
||||
Players and mission designers do not need this file unless they are hosting
|
||||
locally. Server owners and developers do.
|
||||
|
||||
For install links and Forge-specific setup steps, see
|
||||
[SurrealDB Setup](../../../docs/surrealdb-setup.md).
|
||||
|
||||
|
||||
@ -6,6 +6,19 @@ persists durable state through SurrealDB.
|
||||
|
||||
This extension build targets SurrealDB `3.x`.
|
||||
|
||||
## Launch Prerequisites
|
||||
|
||||
Before starting the Arma server with Forge enabled:
|
||||
|
||||
1. Start SurrealDB.
|
||||
2. Copy `config.example.toml` to `config.toml` beside `forge_server_x64.dll`.
|
||||
3. Match the `config.toml` endpoint, namespace, database, username, and password
|
||||
to the running SurrealDB instance.
|
||||
|
||||
The extension reads configuration during startup. If SurrealDB is offline or
|
||||
the config values do not match, persistence-backed commands are not ready for
|
||||
normal gameplay.
|
||||
|
||||
## Responsibilities
|
||||
|
||||
- Register extension command groups for actor, bank, garage, locker, org,
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
# Forge Server Configuration
|
||||
# Copy this file to config.toml and place it beside forge_server_x64.dll.
|
||||
# Start SurrealDB before launching the Arma server, and keep these values
|
||||
# aligned with the running database.
|
||||
|
||||
[surreal]
|
||||
# SurrealDB HTTP endpoint. Use "127.0.0.1:8000" for a local server.
|
||||
|
||||
@ -5,7 +5,9 @@ This guide covers the usual path for adding or changing a Forge module.
|
||||
## Local Checks
|
||||
|
||||
Before running storage-backed workflows locally, complete
|
||||
[SurrealDB Setup](./surrealdb-setup.md).
|
||||
[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:
|
||||
|
||||
|
||||
@ -127,6 +127,13 @@ password = "root"
|
||||
connect_timeout_ms = 5000
|
||||
```
|
||||
|
||||
`config.toml` is a launch prerequisite for server owners and developers. The
|
||||
file must exist beside `forge_server_x64.dll`, and SurrealDB must already be
|
||||
running at the configured endpoint before starting a Forge-enabled dedicated
|
||||
server or local multiplayer test. Clients and mission designers do not run this
|
||||
configuration unless they are hosting locally, but the server they connect to
|
||||
must have it in place.
|
||||
|
||||
For install links and role-based setup guidance, see
|
||||
[SurrealDB Setup](./surrealdb-setup.md).
|
||||
|
||||
|
||||
@ -4,6 +4,20 @@ Forge is split into Arma client addons, Arma server addons, a Rust server
|
||||
extension, shared Rust domain crates, and web UI build tooling. This directory
|
||||
collects framework-level documentation for those pieces.
|
||||
|
||||
## Launch Prerequisites
|
||||
|
||||
Before starting a Forge-enabled dedicated server or local multiplayer test,
|
||||
server owners and developers must:
|
||||
|
||||
1. Start SurrealDB.
|
||||
2. Place `config.toml` beside `forge_server_x64.dll`.
|
||||
3. Keep the `config.toml` SurrealDB endpoint, namespace, database, username,
|
||||
and password aligned with the running database.
|
||||
|
||||
Mission designers and players do not need to run SurrealDB unless they are
|
||||
hosting locally, but the server they join must have these prerequisites ready.
|
||||
See [SurrealDB Setup](./surrealdb-setup.md) for the full setup path.
|
||||
|
||||
## Start Here
|
||||
|
||||
- [Framework Architecture](./FRAMEWORK_ARCHITECTURE.md): how SQF, web UIs,
|
||||
|
||||
@ -4,6 +4,26 @@ 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.
|
||||
|
||||
## Launch Requirement
|
||||
|
||||
Before launching an Arma server or local multiplayer test with Forge enabled:
|
||||
|
||||
1. Start SurrealDB and confirm it is listening on the endpoint Forge will use.
|
||||
2. Copy `arma/server/extension/config.example.toml` to `config.toml` beside
|
||||
`forge_server_x64.dll`.
|
||||
3. Make sure `config.toml` matches the running SurrealDB endpoint, namespace,
|
||||
database, username, and password.
|
||||
|
||||
Server owners and developers must do this before starting the dedicated server
|
||||
or hosting a test session. Mission designers and players do not need their own
|
||||
SurrealDB instance unless they are running the server locally, but the server
|
||||
they connect to must have SurrealDB running and configured.
|
||||
|
||||
If SurrealDB is not running, or if `config.toml` points at the wrong endpoint
|
||||
or credentials, persistence-backed systems such as actors, bank accounts,
|
||||
garages, lockers, organizations, phone data, stores, and tasks will not be
|
||||
ready for normal gameplay.
|
||||
|
||||
## Choose the Right Path
|
||||
|
||||
### Developer or Server Operator
|
||||
@ -73,11 +93,11 @@ password = "root"
|
||||
connect_timeout_ms = 5000
|
||||
```
|
||||
|
||||
After that:
|
||||
Before starting the game server, confirm SurrealDB is still running. After
|
||||
launching the Arma server:
|
||||
|
||||
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:
|
||||
1. Let the extension connect and apply the Forge schema modules.
|
||||
2. Verify the connection state:
|
||||
|
||||
```sqf
|
||||
"forge_server" callExtension ["status", []];
|
||||
|
||||
@ -4,6 +4,26 @@ 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.
|
||||
|
||||
## Launch Requirement
|
||||
|
||||
Before launching an Arma server or local multiplayer test with Forge enabled:
|
||||
|
||||
1. Start SurrealDB and confirm it is listening on the endpoint Forge will use.
|
||||
2. Copy `arma/server/extension/config.example.toml` to `config.toml` beside
|
||||
`forge_server_x64.dll`.
|
||||
3. Make sure `config.toml` matches the running SurrealDB endpoint, namespace,
|
||||
database, username, and password.
|
||||
|
||||
Server owners and developers must do this before starting the dedicated server
|
||||
or hosting a test session. Mission designers and players do not need their own
|
||||
SurrealDB instance unless they are running the server locally, but the server
|
||||
they connect to must have SurrealDB running and configured.
|
||||
|
||||
If SurrealDB is not running, or if `config.toml` points at the wrong endpoint
|
||||
or credentials, persistence-backed systems such as actors, bank accounts,
|
||||
garages, lockers, organizations, phone data, stores, and tasks will not be
|
||||
ready for normal gameplay.
|
||||
|
||||
## Choose the Right Path
|
||||
|
||||
### Developer or Server Operator
|
||||
@ -73,11 +93,11 @@ password = "root"
|
||||
connect_timeout_ms = 5000
|
||||
```
|
||||
|
||||
After that:
|
||||
Before starting the game server, confirm SurrealDB is still running. After
|
||||
launching the Arma server:
|
||||
|
||||
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:
|
||||
1. Let the extension connect and apply the Forge schema modules.
|
||||
2. Verify the connection state:
|
||||
|
||||
```sqf
|
||||
"forge_server" callExtension ["status", []];
|
||||
|
||||
@ -11,6 +11,17 @@ Forge combines:
|
||||
- shared Rust crates for models, repositories, and services
|
||||
- SurrealDB for durable storage
|
||||
|
||||
## Launch Prerequisites
|
||||
|
||||
Before starting a Forge-enabled dedicated server or local multiplayer test,
|
||||
server owners and developers must start SurrealDB and make sure
|
||||
`config.toml` is beside `forge_server_x64.dll`. The config values must match
|
||||
the running SurrealDB endpoint, namespace, database, username, and password.
|
||||
|
||||
Mission designers and players do not need their own SurrealDB instance unless
|
||||
they are hosting locally, but the server they join must have these prerequisites
|
||||
ready.
|
||||
|
||||
## Common Commands
|
||||
|
||||
```powershell
|
||||
|
||||
@ -126,6 +126,13 @@ password = "root"
|
||||
connect_timeout_ms = 5000
|
||||
```
|
||||
|
||||
`config.toml` is a launch prerequisite for server owners and developers. The
|
||||
file must exist beside `forge_server_x64.dll`, and SurrealDB must already be
|
||||
running at the configured endpoint before starting a Forge-enabled dedicated
|
||||
server or local multiplayer test. Clients and mission designers do not run this
|
||||
configuration unless they are hosting locally, but the server they connect to
|
||||
must have it in place.
|
||||
|
||||
For install links and role-based setup guidance, see
|
||||
[SurrealDB Setup](/getting-started/surrealdb-setup).
|
||||
|
||||
|
||||
@ -6,7 +6,9 @@ description: "This guide covers the usual path for adding or changing a Forge mo
|
||||
## Local Checks
|
||||
|
||||
Before running storage-backed workflows locally, complete
|
||||
[SurrealDB Setup](/getting-started/surrealdb-setup).
|
||||
[SurrealDB Setup](/getting-started/surrealdb-setup). 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:
|
||||
|
||||
|
||||
@ -3,6 +3,26 @@ title: "SurrealDB Setup"
|
||||
description: "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."
|
||||
---
|
||||
|
||||
## Launch Requirement
|
||||
|
||||
Before launching an Arma server or local multiplayer test with Forge enabled:
|
||||
|
||||
1. Start SurrealDB and confirm it is listening on the endpoint Forge will use.
|
||||
2. Copy `arma/server/extension/config.example.toml` to `config.toml` beside
|
||||
`forge_server_x64.dll`.
|
||||
3. Make sure `config.toml` matches the running SurrealDB endpoint, namespace,
|
||||
database, username, and password.
|
||||
|
||||
Server owners and developers must do this before starting the dedicated server
|
||||
or hosting a test session. Mission designers and players do not need their own
|
||||
SurrealDB instance unless they are running the server locally, but the server
|
||||
they connect to must have SurrealDB running and configured.
|
||||
|
||||
If SurrealDB is not running, or if `config.toml` points at the wrong endpoint
|
||||
or credentials, persistence-backed systems such as actors, bank accounts,
|
||||
garages, lockers, organizations, phone data, stores, and tasks will not be
|
||||
ready for normal gameplay.
|
||||
|
||||
## Choose the Right Path
|
||||
|
||||
### Developer or Server Operator
|
||||
@ -72,11 +92,11 @@ password = "root"
|
||||
connect_timeout_ms = 5000
|
||||
```
|
||||
|
||||
After that:
|
||||
Before starting the game server, confirm SurrealDB is still running. After
|
||||
launching the Arma server:
|
||||
|
||||
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:
|
||||
1. Let the extension connect and apply the Forge schema modules.
|
||||
2. Verify the connection state:
|
||||
|
||||
```sqf
|
||||
"forge_server" callExtension ["status", []];
|
||||
|
||||
@ -20,7 +20,9 @@ SQF module
|
||||
|
||||
## Configuration
|
||||
|
||||
Copy `config.example.toml` to `config.toml` next to the extension DLL.
|
||||
Copy `config.example.toml` to `config.toml` next to the extension DLL before
|
||||
launching a Forge-enabled server. SurrealDB must also be running before the
|
||||
server starts, and the values in `config.toml` must match that database.
|
||||
|
||||
```toml
|
||||
[surreal]
|
||||
@ -32,6 +34,9 @@ password = "root"
|
||||
connect_timeout_ms = 5000
|
||||
```
|
||||
|
||||
Players and mission designers do not need this file unless they are hosting
|
||||
locally. Server owners and developers do.
|
||||
|
||||
For install links and Forge-specific setup steps, see
|
||||
[SurrealDB Setup](/getting-started/surrealdb-setup).
|
||||
|
||||
|
||||
@ -16,6 +16,10 @@ browser-backed player interfaces.
|
||||
Use these docs to understand the runtime architecture, extension API surface,
|
||||
server gameplay modules, and client addon integration patterns.
|
||||
|
||||
Server owners and developers must start SurrealDB and place a matching
|
||||
`config.toml` beside `forge_server_x64.dll` before launching a
|
||||
Forge-enabled server or local multiplayer test.
|
||||
|
||||
#links
|
||||
:::u-button
|
||||
---
|
||||
|
||||
@ -80,9 +80,10 @@ impl<R: TaskRepository> TaskStateService<R> {
|
||||
|
||||
self.repository
|
||||
.save_ownership(entry_id.clone(), ownership.clone())?;
|
||||
let accepted = !ownership.requester_uid.trim().is_empty();
|
||||
let entry = self.patch_catalog_ownership(
|
||||
&entry_id,
|
||||
true,
|
||||
accepted,
|
||||
&ownership.requester_uid,
|
||||
&ownership.org_id,
|
||||
)?;
|
||||
@ -326,6 +327,39 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bind_ownership_without_requester_does_not_accept_task() {
|
||||
let repository = InMemoryTaskRepository::new();
|
||||
let service = TaskStateService::new(repository.clone());
|
||||
|
||||
service
|
||||
.upsert_catalog_entry("task-1".to_string(), r#"{"title":"Hostage"}"#.to_string())
|
||||
.expect("catalog upsert should succeed");
|
||||
|
||||
let result = service
|
||||
.bind_ownership(
|
||||
"task-1".to_string(),
|
||||
r#"{"requesterUid":"","orgId":"default"}"#.to_string(),
|
||||
)
|
||||
.expect("bind should succeed");
|
||||
|
||||
assert_eq!(result.requester_uid, "");
|
||||
assert_eq!(result.org_id, "default");
|
||||
assert_eq!(
|
||||
result.entry.get("accepted").and_then(Value::as_bool),
|
||||
Some(false)
|
||||
);
|
||||
|
||||
let stored = repository
|
||||
.get_catalog_entry("task-1")
|
||||
.expect("catalog lookup should succeed")
|
||||
.expect("catalog entry should exist");
|
||||
assert_eq!(
|
||||
stored.fields.get("requesterUid").and_then(Value::as_str),
|
||||
Some("")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_status_falls_back_to_completed_status() {
|
||||
let repository = InMemoryTaskRepository::new();
|
||||
|
||||
@ -171,6 +171,10 @@ browser-backed player interfaces.
|
||||
Use these docs to understand the runtime architecture, extension API surface,
|
||||
server gameplay modules, and client addon integration patterns.
|
||||
|
||||
Server owners and developers must start SurrealDB and place a matching
|
||||
\`config.toml\` beside \`forge_server_x64.dll\` before launching a
|
||||
Forge-enabled server or local multiplayer test.
|
||||
|
||||
#links
|
||||
:::u-button
|
||||
---
|
||||
@ -372,6 +376,17 @@ Forge combines:
|
||||
- shared Rust crates for models, repositories, and services
|
||||
- SurrealDB for durable storage
|
||||
|
||||
## Launch Prerequisites
|
||||
|
||||
Before starting a Forge-enabled dedicated server or local multiplayer test,
|
||||
server owners and developers must start SurrealDB and make sure
|
||||
\`config.toml\` is beside \`forge_server_x64.dll\`. The config values must match
|
||||
the running SurrealDB endpoint, namespace, database, username, and password.
|
||||
|
||||
Mission designers and players do not need their own SurrealDB instance unless
|
||||
they are hosting locally, but the server they join must have these prerequisites
|
||||
ready.
|
||||
|
||||
## Common Commands
|
||||
|
||||
\`\`\`powershell
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user