Mission Start Trigger
Reference for `gameplay_missions_startTrigger`, which parses mission start triggers into location data and clusters nearby missions for the POI/marker system.
Reference for gameplay_missions_startTrigger, which parses mission start triggers into location data and clusters nearby missions for the POI/marker system.
Module Exports (M)
| Function | Signature | Description |
|---|---|---|
parseMission | (mission) → locations, err | Parses a mission's startTrigger into a list of location objects |
getMissionClusters | (mergeRadius) → table | Returns clustered mission locations, cached by merge radius |
defaultLocationCheck | (location, level, playerPosition, mission) → bool | Proximity check: same level + within radius |
defaultLocationDisplayMarker | (location, playerPosition) | Debug: draws cylinder marker at location |
onAnyMissionChanged | hook | Clears cluster cache when missions change |
Start Trigger Types
| Type | Required Fields | Description |
|---|---|---|
level | level | Mission available anywhere on specified level(s) |
coordinates | level, pos, radius | Mission available at specific world position |
league | level | League-based trigger (no location generated) |
M.defaultLocationCheck | (location, level, playerPosition, mission) | - |
M.defaultLocationDisplayMarker | (location, playerPosition) | - |
M.getMissionClusters | (mergeRadius) | - |
M.onAnyMissionChanged | () | - |
M.parseMission | (mission) | - |
Mission Clustering
Uses a quadtree for spatial clustering of coordinate-based mission triggers:
local function getMissionClusters(mergeRadius)
-- 1. Collect all coordinate locations, grouped by level
-- 2. Build quadtree per level
-- 3. For each location, find overlapping neighbors
-- 4. Merge overlapping locations into clusters
-- 5. Cache result by mergeRadius
endMerge Algorithm
local function merge(allClusters, cluster, mergeRadius)
if #cluster == 1 then
-- Single mission: use its position/radius directly
else
-- Multiple missions: compute weighted center
-- 1. First pass: radius-weighted center
-- 2. Second pass: distance-weighted center refinement
-- 3. New radius = max(distance to any member + its radius) - 1
-- All mission IDs collected into cluster
end
endLocation Object Structure
{
type = 'coordinates',
level = "west_coast_usa",
pos = vec3(...),
rot = quat(...),
radius = 3,
check = defaultLocationCheck,
displayMarker = defaultLocationDisplayMarker,
missionIds = {"mission1", "mission2"}, -- for clusters
clusterId = "mission1mission2"
}How It Works
-- Parsing validates required fields before generating locations:
local function parseMission(mission)
local trigger = mission.startTrigger
-- Check required fields for the trigger type
-- Call the appropriate trigger handler (level/coordinates/league)
-- Return locations array or error string
end
-- Level triggers support string or array of level names:
local function levelTriggerList(trigger, locations)
if type(trigger.level) == 'string' then
-- Single level
elseif type(trigger.level) == 'table' then
-- Multiple levels
end
endKey Behaviors
- Cluster cache is invalidated whenever
onAnyMissionChangedfires - Quadtree uses
quadtree.pointBBox()for spatial indexing - Locations are sorted by ID for deterministic clustering
mergeRadiusof-1(nil) means no clustering - each location uses its own radius- The
leaguetrigger type is a no-op - produces no locations (handled elsewhere) - Debug markers draw colored cylinders: red = out of range, green = in range and startable, gray = in range but not startable
See Also
- missions/locationsDetector - Nearby Mission Location Detection - Related reference
- missions/missionManager - Mission Lifecycle Manager - Related reference
- missions/missionScreen - Mission UI Screen & Starting Options - Related reference
- Gameplay Systems Guide - Guide
Progress
Reference for `gameplay_missions_progress`, the system that tracks mission attempts, aggregates progress, manages leaderboards, computes star rewards, and formats progress data for the UI.
Unlocks
Reference for `gameplay_missions_unlocks`, which evaluates start/visible conditions, manages unlock dependencies between missions, and computes mission ordering depth.