Jacob Schmidt 07d5422091 Refactor task management system with object prototypes and enhanced logging
- Updated fnc_extCall.sqf to suppress logging for specific functions.
- Added object model prototypes for task instances in prototypes/taskObjectPrototypes.sqf.
- Enhanced README.md to document the new object model and its purpose.
- Modified XEH_postInit.sqf to improve event handling for defuse tasks.
- Updated various task functions (fnc_attack, fnc_defend, fnc_defuse, fnc_delivery, fnc_destroy, fnc_heartBeat, fnc_hostage, fnc_hvt) to include task acceptance checks.
- Improved fnc_makeHostage and fnc_makeIED to ensure proper task registration and state management.
- Introduced new methods in task object prototypes for better state management and task flow control.
2026-04-28 23:04:22 -05:00

223 lines
8.7 KiB
Markdown

# Forge Task Module
## Overview
The task addon is a server-owned mission/task system for Forge. It manages task execution, task-owned state, participant tracking, contribution-based player earnings, and org-owned rewards.
Task operational state is mission-scoped. The extension-backed task catalog,
ownership, status, and defuse state are reset on task store startup, so the
system intentionally starts clean after each server or mission restart.
## Responsibilities
- spawn and monitor task flows on the server
- track per-task entities through `TaskStore`
- track task participants and engine-rating contribution
- award player earnings through the bank module
- award org funds, reputation, assets, and fleet rewards
- notify task participants and sync org updates to online members
## Dependencies
- `forge_server_extension`
- `forge_server_common`
- `forge_server_actor`
- `forge_server_bank`
- `forge_server_org`
- `forge_client_notifications`
## Main Components
### Task Flows
- `fnc_attack.sqf`
- `fnc_defend.sqf`
- `fnc_defuse.sqf`
- `fnc_delivery.sqf`
- `fnc_destroy.sqf`
- `fnc_hostage.sqf`
- `fnc_hvt.sqf`
### TaskStore
`fnc_initTaskStore.sqf` initializes `TaskStore`, which owns:
- task ownership bindings
- participant snapshots
- defuse progress
- per-task entity registries for cargo, hostages, HVTs, IEDs, protected entities, shooters, and targets
### Object Model Prototype
A review-only prototype for object-based task instances lives under
`prototypes/`. It is not wired into runtime.
- `prototypes/taskObjectPrototypes.sqf`
- `prototypes/README.md`
The prototype sketches `TaskInstanceBaseClass`, `HostageTaskBaseClass`, and
`DefuseTaskBaseClass` using `createHashMapObject` so the team can review a
stateful per-task design without replacing the current procedural task flows.
### Reward Handling
`fnc_handleTaskRewards.sqf` applies org-owned rewards:
- `funds` -> org funds
- `equipment`, `supplies`, `weapons`, `special` -> org assets
- `vehicles` -> org fleet
Player `earnings` and org `reputation` from task outcomes are distributed separately through `TaskStore.applyRatingOutcome` using Arma engine `rating` deltas.
## Task Ownership
Tasks are bound to an owner org when they are started through `fnc_handler.sqf`.
- if a requester UID is provided, the task is owned by that requester's org
- if no requester UID is available, the task is bound to the `default` org
Org rewards always go to the bound owner org. Player earnings still use per-player contribution.
## Usage
Task time limits use `0` for no limit on attack, destroy, delivery, hostage,
and HVT tasks. Defuse IED timers are different: each IED must have a positive
countdown value.
Mission designers can create tasks in four ways:
- Eden modules for editor-authored tasks.
- `fnc_startTask.sqf` for script-authored tasks.
- `fnc_handler.sqf` for pre-registered entities with reputation gating and
ownership binding. This path expects the BIS task and catalog entry to
already exist if map-task and CAD visibility are required.
- Direct task function calls for server-owned or mission-authored flows that
intentionally fall back to the `default` org. This path expects the BIS task
to already exist if map-task visibility is required.
The dynamic mission manager can also generate attack tasks from config. That is
system-generated content rather than a hand-authored task creation path.
### CAD Compatibility
CAD hydrates assignable tasks from `TaskStore.getActiveTaskCatalog`. A task must
have a catalog entry and active task status before CAD can show and assign it.
CAD-compatible creation paths:
- Eden modules: compatible because they delegate to `fnc_startTask.sqf`
- `fnc_startTask.sqf`: compatible because it registers the catalog entry,
creates the BIS task, and dispatches through `fnc_handler.sqf`
- dynamic mission manager attack tasks: compatible because the mission manager
uses `fnc_startTask.sqf`
Limited or incompatible paths:
- `fnc_handler.sqf`: only compatible if a catalog entry was already registered
elsewhere. The handler sets active status and ownership, but it does not
create the BIS task shown in the map task tab or upsert the catalog entry
- direct task function calls: not CAD-compatible by default. They bypass
`fnc_startTask.sqf` and usually do not register the task catalog entry or
active status that CAD hydrates from. They also only call
`BIS_fnc_taskSetState` at completion/failure; they do not create the BIS task
first
### BIS Map Task Prerequisite
Only the Eden task modules and `fnc_startTask.sqf` create the BIS task
automatically through `BIS_fnc_taskCreate`.
If a mission uses `fnc_handler.sqf` directly or calls a task flow function such
as `forge_server_task_fnc_attack`, the mission must create a BIS task with the
same task ID before the Forge task completes. Otherwise the success/failure
`BIS_fnc_taskSetState` call has no visible map task to update.
That prerequisite can be satisfied with a vanilla Eden task creation module or
a scripted `BIS_fnc_taskCreate` call. `fnc_startTask.sqf` is the preferred Forge
path because it handles BIS task creation, Forge catalog registration, entity
registration, and handler dispatch together.
### Create With Eden Modules
Eden task modules are the normal designer-facing path. Place the module,
configure its attributes, and sync it to the relevant entities or grouping
modules.
Available task modules:
- `FORGE_Module_Attack`: sync directly to target units or vehicles
- `FORGE_Module_Destroy`: sync directly to objects, vehicles, or units
- `FORGE_Module_Defuse`: sync to `FORGE_Module_Explosives` and optionally
`FORGE_Module_Protected`
- `FORGE_Module_Delivery`: sync to `FORGE_Module_Cargo`; the cargo module syncs
to cargo objects
- `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
These modules delegate to `fnc_startTask.sqf`.
### Start Through `fnc_startTask.sqf`
Use `fnc_startTask.sqf` for script-authored tasks. It registers task entities,
creates the BIS task, stores the catalog entry, and dispatches through
`fnc_handler.sqf`.
```sqf
[
"attack",
"compound_attack_01",
getPosATL leader1,
"Attack: East Compound",
"Eliminate all hostile forces.",
createHashMapFromArray [["targets", [unit1, unit2, unit3]]],
createHashMapFromArray [
["limitFail", 0],
["limitSuccess", 3],
["funds", 50000],
["ratingFail", -10],
["ratingSuccess", 20],
["timeLimit", 900]
],
0,
getPlayerUID player,
"script"
] call forge_server_task_fnc_startTask;
```
### Start Through The Handler
Use the handler when you want reputation gating and task ownership binding.
Create the BIS task and catalog entry separately if this task should appear in
the map task tab or CAD.
```sqf
["attack", ["task_attack_1", 1, 2, 1500000, -75, 375, false, false], 250, getPlayerUID player] call forge_server_task_fnc_handler;
["delivery", ["task_delivery_1", 1, 3, "delivery_zone", 250000, -75, 300, false, false, 900], 0, getPlayerUID player] call forge_server_task_fnc_handler;
```
Arguments:
- `0`: task type
- `1`: task-specific argument array
- `2`: minimum org reputation required to start the task
- `3`: requester UID used for ownership binding
### Start Task Functions Directly
Direct task calls still work, but they do not provide a requester UID. That means task ownership falls back to the `default` org.
Create the BIS task separately if this task should appear in the map task tab.
Use direct starts only when that behavior is intended, such as:
- mission-authored tasks
- editor-placed tasks
- server-owned/random tasks
If you want the accepting player's org to own the task rewards, use `fnc_handler.sqf` instead.
```sqf
["task_attack_1", 1, 2, 1500000, -75, 375, false, false] spawn forge_server_task_fnc_attack;
["task_hostage_1", 1, 2, "extract_marker", 1500000, -75, 500, [false, true], false, false] spawn forge_server_task_fnc_hostage;
```
## Event Hooks
- `XEH_preInit.sqf`
- compiles functions
- initializes `TaskStore`
- `XEH_postInit.sqf`
- registers the ACE defuse event hook
## Notes
- the dynamic mission manager in `fnc_missionManager.sqf` is currently not started by default
- it starts server-owned tasks through `fnc_handler.sqf` and binds them to the `default` org
- task lifecycle for the mission manager is tracked through `TaskStore` status entries
- task backend state is intentionally transient and resets with the active server/mission lifecycle
- task rewards are org-owned, not player-owned
- participant notifications are sent through the notifications module, not through local server UI
## Authors
- J. Schmidt
- Creedcoder
- IDSolutions