|
Ground of Aces Modding
|
A quest is a list of goals the player sees in the quest panel: build an airstrip, order an aircraft, fly five missions. Each goal is a counter that fills up as the player does the thing, and when every required goal is full the quest is complete and the next one in the chain can start.
Quests are not missions. A mission is a flight with dice rolls and a script; a quest is a checklist that watches the game and ticks boxes. There is no Python in a quest and nothing to "run" - a quest is a single .json file, and everything it can watch for is built into the game.
| Page | Contents |
|---|---|
| Missions | missions, and the events a quest can wait for when a mission returns |
| Mission locations | the location flags a mission quest can filter on (sea, enemyterritory, …) |
| Changing game data with a CSV mod | the data tables that hold the ids you will use in quests - buildings, aircraft, resources, plants |
| Example quests | complete quest files to open or save - three written for this page, four shipped with the game |
The game reads quests from two places, and the later one wins when both carry the same id:
Mods/<your mod>/Quests/, holding .json files. Only files directly inside Quests/ are read; subfolders are ignored. Only enabled mods are read - a mod switched off in the Mods window contributes no quests.Unlike missions there is no personal quests folder that the game reads outside of a mod. To try a quest, put it in a mod folder - How mods work explains where that folder is, what config.json may contain and how the Mods window works. The quests go into a Quests subfolder next to the other content types:
Two rules follow from how the files are read:
mycampaign_first_steps.json is the quest mycampaign_first_steps, whatever the _questId field inside says. Keep the two identical: the game checks whether a quest already exists in the save by its file name but stores the field in the save, so if they differ the quest is handed out again every time the game loads, and chains (requirement type 1) reference the field.quest3.json silently replaces the shipped quest3. Between two mods with the same file name the one loaded later wins: local mods (your Mods/ folder) load after Steam Workshop mods, and within a source by load order, then by id.Quests/ folder that was still empty when the game started, needs Refresh in the Mods window (main menu → Mods) first, or a restart. (Developers: reload_mods in development builds does not reload quests either - use a level load.)This is a complete, working quest. Save it as Mods/my_campaign/Quests/mycampaign_first_steps.json, start the game, and load or start any map: it appears in the quest panel right away.
Reading it top to bottom: the quest has two steps. The first waits until a sickbed has been finished building - once. The second counts beds standing on the base and is full at four, but it is optional, so the quest completes as soon as the sickbed is done. _requirements is empty, which means the quest starts on every map the moment the game loads.
The titles are localisation keys, not text - until you register them the player sees no title at all. The section Text explains how to give them words.
| Field | Meaning |
|---|---|
_questId | The quest's id. Keep it equal to the file name. |
_questTitle | Localisation key of the title shown in the quest panel. |
_questDescription | Localisation key of a longer text under the title. Leave "" for none - shipped quests do. |
_subQuests | The steps, in the order they are listed in the panel. At least one. |
_requirements | When the quest is handed out - see How a quest starts. Not progress. |
_isHiddenInUI | true hides the quest from the panel while it still runs. Used by the shipped skin-unlock quests. |
_questType | 0 a normal quest. 2 a tutorial quest. 1 an aircraft-skin quest. See Quest types; use 0. |
_highlightedUIElements | Tutorial quests only: buttons the tutorial points at. Ignored for type 0. |
_cheatsOnStart, _completionCheats | Tutorial quests only, and stripped from every mod quest - see Quest types. |
Fields you leave out take their default: false, 0, or empty. Extra fields (the shipped files carry a "Name" the game no longer reads) are ignored.
Each entry of _subQuests is one step:
| Field | Meaning |
|---|---|
_subQuestTitle | Localisation key of the step's title. Also the name the game uses internally for the step. |
_subQuestDescription | Localisation key of the step's tooltip. "" for none. |
_isOptional | true - the quest can complete without this step. |
_subQuestRequirement | What is counted: a _type, a _parameter and an _amount. Exactly one per step. |
_genericIconKey | Which icon the step shows. See Icons. |
And the requirement inside it:
| Field | Meaning |
|---|---|
_type | A number picking the kind of condition - the full table is under What a step can wait for. |
_parameter | A comma-separated list whose meaning depends on the type. No spaces around the commas. |
_amount | The count at which the step is complete. At least 1. |
_amount must be at least 1. A step with _amount: 0 behaves inconsistently: depending on whether the quest was created while a save loaded or later in the running game, it either completes instantly or never completes - and in the second case, unless it is optional, it blocks its quest forever. Always use at least 1. If you want a step the map already satisfies (a "you are here" step), give it a real, already-true condition instead: _type: 1, _parameter: "0", _amount: 1 is complete as soon as the base has any parking spot.Every text field of a quest is a localisation key - the same kind of key missions use - and the game looks it up in its translation table when the panel is drawn. A key that is registered in no language is not shown at all: the quest card keeps the text it had before (a placeholder, or the text of the quest that last used that card) and the tooltip stays empty. Register every key.
Missions can carry their text directly in the JSON. Quests cannot - there are no raw-text fields, and a quest has no script of its own. You have two options:
Reuse a shipped key. The tutorial and main-line quests already have translated titles for things like "Build an airstrip" or "Order an aircraft". Open the matching shipped quest and copy its key. This costs nothing and is translated into every language the game ships, but you are limited to sentences that already exist.
Register your own keys from a script. A .py file in your mod's Missions/ folder runs when a level loads, for every enabled mod, and its top level can register terms:
The file needs no mission handlers; it exists only to run this block. Put it in Missions/, not in Quests/ - Quests/ is read for .json only, and Missions/ is the one folder the game loads scripts from. Call SetTerm once per language you want to support ("de", "fr", …). A language you leave out shows the text of a language you did register, so always register en. A key that is registered in no language is not shown at all: the quest card keeps the text it had before and the tooltip stays empty. The try/except matters: a syntax error skips only your script, but any other error at the top level of a script can abort the loading of every script after it - yours and other mods'.
Registering a key the game already ships - a building name, a shipped quest title - replaces the game's own text for that language. Prefix your keys with your mod name so this can never happen by accident.
Shipped quests name their keys quest/<questId>/title, quest/<questId>/subQuest0_title and quest/<questId>/subQuest0_description. Nothing enforces that shape for your quests - use your mod name as the first segment so your keys can never collide with the game's.
_genericIconKey picks the step's icon from a fixed set built into the game. A key the game does not know simply shows no icon; nothing is logged. There is no way to add your own icons from a mod.
Every key the game knows, grouped by what it shows:
| Kind | Keys |
|---|---|
| Base | ui_path_runway, ui_runway, ui_path_cars, ui_functionarea_runway, ui_functionarea_parking, ui_functionarea_parking_1, ui_functionarea_parking_2, ui_functionarea_resources, ui_functionarea_safety, ui_functionarea_gardening, ui_hangar_roof, roof, wall, floor, door, house, ui_decoration_wall, ui_decoration_poster, ui_props_kitchen, ui_props_social |
| Aircraft | ui_plane, ui_plane_GlosterGladiator_MKI, ui_scramble, ui_aagun, ui_alarm, ui_radio |
| Resources | ui_resource_wood, ui_resource_planks, ui_resource_metal, ui_resource_bricks, ui_resource_cement, ui_resource_fuel, ui_resource_gunAmmo, ui_resource_repairParts, ui_resource_trash, ui_resource_rubble, ui_resource_victoryPoints, ui_seeds_beans, ui_harvesting, ui_tool_gathering, ui_fire |
| Crew | ui_crew_person_single, ui_crew_people_multiple, ui_crewjob_cook, ui_crewjob_medic, ui_health, ui_morale, ui_bed, ui_prop_bed, ui_prestige_full, Endurance |
| Interface | ui_camera, ui_move_tool, ui_pause, ui_speed_1, ui_speed_2, ui_speed_3, ui_timer_clock, ui_clock, ui_schedule, ui_eventlog, ui_notifications_all, ui_attention, ui_search_looking_glass, ui_lock_open, ui_headquarters, ui_stamp_headquarters_approved, ui_repairandcrafting, ui_cogwheel, ui_crown, ui_mark_exclamation, ui_assigned, ui_trash, plus |
| Workbenches | SawStation, FieldKitchen, IndoorKitchen, ElectronicsWorkbench, BrickStation, CementMixer |
| Prop thumbnails | PP0151_SickBed_thumbnail, PP1101_Bofors40mm_thumbnail, PP1002_SirenOnAPole_thumbnail, PP1006_LargeFuelTankWithConnector_thumbnail, PP1020_Flagpole5m_thumbnail, PP1030_Water_Pump_thumbnail, PP1000_RadioTower_thumbnail, PP0101_WoodenChair_thumbnail, PP0102_BarStool_thumbnail, PP0911_BarCounter_thumbnail, PP0956_DividerCurtains_thumbnail, BB0900_Sandbag1mStraightVarA_thumbnail, BB1300_Table1x2_thumbnail, Simple-Rack_thumbnail, GraveStoneWhite_thumbnail |
"" is fine and means no icon. When in doubt, copy the key from a shipped step that shows the picture you want.
Each step has one requirement, and its _type decides what the game counts. There are two kinds:
Progress is capped at _amount, and a completed step stays complete.
_type | Counts | _parameter |
|---|---|---|
| 0 | Finished, unobstructed airstrips of at least this tier | The tier as a number: "1" … "5". Required. |
| 21 | Airstrips at any stage - planned, under construction or finished - whose planned length, width and material all reach this tier | The tier as a number. Required. |
| 1 | Usable parking spots of at least this size | The size as a number; "0" is any parking spot. Required. |
| 4 | Finished props with one of these ids | Prop ids, e.g. "Bed" or "Flagpole5,Flagpole10". Planned or unbuilt props do not count. |
| 6 | Usable workbenches with one of these ids | Workbench ids, e.g. "SawStation", "FieldKitchen". |
| 9 | Zones of a type, optionally of a size | "<Zone>", or "<Zone>,<min tiles>", or "<Zone>,<min>,<max>". Zones: Airstrip, Parking, SafetyZone, Storage, GardeningZone. Example "Storage,20" - a storage zone of at least 20 tiles. |
| 20 | Zones whose every tile is covered by a given building | "<Zone>,<building id>", optionally ,<min>,<max> tiles. Example "Storage,roof_tent" - a storage zone entirely under tent roof. |
| 10 | 1 if at least one storage zone has floor and roof over every tile, else 0 | Leave empty. A size in here does not restrict which storage counts - it only decides whether the check runs at all. Use _amount: 1. |
| 11 | Storage zones that accept trash and rubble | Empty - any storage that lets trash and rubble in. "true" - only storages set up for nothing but trash and rubble. |
| 25 | Completes when every listed resource is allowed in at least one storage zone | Resource names, e.g. "GunAmmo,AntiAirAmmo,PlaneBombs". Re-checked whenever the player changes a storage's settings or places a zone. Use _amount: 1. |
| 24 | Gardening zones growing a plant for a purpose | "<plant>,<Seeds or Food>", optionally ,<min tiles>,<max tiles>. Example "beans,Food,10". Plant ids are those of the gardening data table. |
Types 0, 1 and 21 must have a number in _parameter, and types 20 and 24 must have their second token (the building id, the Seeds/Food purpose). Anything else - including an empty string - is an error inside the game every time the step is checked, and it stalls every other counted-state step that is checked in the same batch until the save is reloaded. This is the one mistake that hurts beyond your own quest.
_type | Counts | _parameter |
|---|---|---|
| 2 | Aircraft the player owns | One or more aircraft ids, comma-separated - "spitfire" or "spitfire,hurricane" - or empty for any aircraft. |
| 12 | Aircraft that returned from a successful mission | See below. |
| 13 | Aircraft that returned from any mission, won or lost | See below. |
| 17 | Aircraft that returned from a failed mission | See below. |
| 16 | Aircraft that took part in a scramble | Aircraft ids, or empty for any. |
| 18 | Enemy aircraft shot down during a scramble | Aircraft ids of the defending aircraft that scored, or empty for any. |
| 19 | Aircraft that scrambled to safety | Aircraft ids, or empty for any. |
Types 12, 13, 16, 17, 18 and 19 add one per aircraft, not per mission. A three-aircraft mission that succeeds adds three to a type-12 step. For "fly one mission", keep _amount: 1 and accept that the step completes when the first aircraft is home.
Filters for 12, 13 and 17. An empty _parameter accepts every returning aircraft. Otherwise the list is read as a bag of tokens, and the aircraft must satisfy all of them:
| Token | Types | Meaning |
|---|---|---|
an aircraft id - spitfire, blenheim, … | all three | the returning aircraft must be one of the listed ids. Required whenever the list is not empty - a filter with no aircraft id in it matches nothing. |
a skill - fight, bomb, recon, transport, maneuverability, stealthiness - or any_skill_type | 12, 17 | the mission was rolled on that skill. One of these is required for types 12 and 17. |
gone_wrong | 12, 17 | only missions that did not go as planned |
location followed by land, sea, ownterritory or enemyterritory | 12, 13 | the mission's location must carry every listed flag |
low_hp | 13 | the aircraft came back with a quarter of its health or less |
high_success_rate | 17 | the mission failed although the forecast was above 90 % |
Aircraft ids are the first column of the vehicle data table: gladiator, hurricane, spitfire, meteor, mustangmk1, vampire, beaufighter, typhoon, tempest, kittyhawk, blenheim, hampden, stirling, lancaster, b17raf, mosquito, defiant, flamingo, lysander.
Examples that work in a normal quest:
fighter, bomber, multirole or special - where the aircraft id goes. That works only for _questType: 1, where the game makes one copy of the quest per matching aircraft and fills the real id in. In a _questType: 0 quest a role name matches nothing - list the aircraft ids.Waiting for one particular mission. Types 12, 13 and 17 cannot name a mission. Use type 7 with the mission's return event instead - see Events:
This is how a quest follows a chain of your own missions, one step per mission.
_type | Counts | _parameter |
|---|---|---|
| 22 | Living, not heavily injured crew members with a job | One job: RAFAircrew, AAFCook, FieldMechanic, FieldEngineer, RAFMedic, AAFLabour. |
Three types watch the stream of things that happen on the base. Each adds one per matching event - with one exception: resource_gained carries the number of units gained and adds that number, so "resource_gained,Metal" with _amount: 20 means twenty metal, not twenty deliveries.
_type | Adds one when… | _parameter |
|---|---|---|
| 5 | the named event fires, whatever its details | "<event>" |
| 7 | the named event fires and any of its details is one of the listed values | "<event>,<value>,<value>,…". With no values listed, every occurrence counts. |
| 8 | the named event fires and every listed value is among its details | "<event>,<value>,<value>,…" |
Type 7 is the workhorse - "a specific building was finished", "a specific resource arrived":
Type 8 narrows to combinations, and is rarely needed:
Type 8 has two limits type 7 does not have. It compares the listed values against the event's details as text only: details that are names (crew ids, building ids, project ids, mission ids) match, but details the game carries as numbers or as types - the resource of harvesting_finished and resource_gained, the category of building_type_finished, the zone of function_area_placed - never do. Use type 7 for those. And a type-8 step with listed values on an event that carries no details at all (victory_points_added, quest_dismissed) is an error every time that event fires. When one value is enough, use type 7.
Events available in normal play, with the details each one carries:
| Event | Details |
|---|---|
building_started, building_finished, deconstruction_finished | worker, building id (e.g. Sickbed, roof_concrete, wall_tent) |
building_type_finished | worker, building category (e.g. PropSocial, PropPosters) |
project_started, project_finished | worker, workbench id, project id (as SawStation.Planks) |
harvesting_started, harvesting_finished | worker, harvested object (e.g. tree, tree_big, berry_bush), resource |
resource_gained | resource name |
resource_picked_up, resouce_consumed | crew member, resource name (the second is spelt that way in the game) |
shipment_received | the ids in the delivery |
victory_points_added | - |
assigned_to_equipment | crew member, equipment id |
training_started, training_finished | crew member, training object |
task_started, task_completed | crew member, task name (e.g. Harvest, Build, Repair, RepairAirplane, Refuel, Recover) |
chat_started, chat_finished | the two crew members |
mission_started, mission_success, mission_failed | the mission's location name |
airplane_on_mission_succeed, airplane_on_mission_failed | aircraft id, aircraft, mission id, skill, went-as-planned, location name, forecast |
airplane_took_part_in_scramble, airplane_scramble_fly_to_safety, airplane_scramble_airplane_destroyed | aircraft id |
plane_takeoff, plane_landing | the aircraft's internal number (not its id - you cannot filter for spitfire here), pilot |
storage_resource_enabled, function_area_placed | resource name / zone type |
day_phase_change | previous phase, current phase |
midnight, midday | year, month, day |
sub_quest_completed | the completed step's _subQuestTitle key - a quest can wait for a step of another quest |
quest_dismissed | - |
dog_sleep, dog_walk_started, dog_walk_finished, dog_sniff_wait | the dog |
camera_moved, camera_zoomed, camera_rotated, character_selected, task_created, tooltip_shown, preview_created, building_placed, state_entered, time_scale_changed, window_opened, character_job_assigned, day_phase_ended, plane_ordered, plane_selected, plane_assigned_to_mission, shipment_item_added, scramble_started, attack_finished, storage_resource_disabled, button_clicked, plane_back_from_mission, hour_changed, workbench_selected, project_planned. building_finished over building_placed, and airplane_on_mission_succeed over plane_back_from_mission._type | Completes when… | _parameter |
|---|---|---|
| 23 | the player clicks the button this step puts on the quest card | The localisation key of the button label, e.g. "basic_ui/ok" or "basic_ui/start". |
The button is drawn on the quest card of the quest that owns the step. Note that any such button on any quest advances every type-23 step that is currently open, so keep to one at a time. With an empty _parameter no button is drawn, but the step still completes when a button on another quest is clicked.
_type: 3 and _type: 15 exist in old files but have no logic behind them; a step using either never progresses and nothing is logged. The same goes for any number outside the table. If a step sits at zero forever, check its _type first.
_requirements decides when the quest is handed to the player. It has nothing to do with progress. All entries must pass (they are combined with AND), and the check runs when a game is loaded or started, and again every time any quest completes - at that point only quests with a type-1 entry are re-checked.
_requirementType | Meaning | _value |
|---|---|---|
| 1 | Start once the named quest is complete | the other quest's id |
| 3 | Start only when the loaded map names this quest - see Quests and maps | "" |
| 2 | Minimum date - not implemented. The entry is skipped, so the quest starts as if it were not there. Do not use it. | |
| 0 | None. |
With an empty list, the quest starts on every map as soon as the game loads. That is right for a side quest or an achievement-like quest, and wrong for anything that belongs to a story or a map.
A chain is a series of quests each requiring the one before it:
A quest is handed out at most once per playthrough - once it exists in the save, complete or not, it is not created again, and a completed quest stays completed. Requiring a quest that never starts on this map (because that quest carries requirement type 3 and the map does not list it) is a convenient way to keep a whole chain off a map: only the first link needs the map, the rest follow through requirement type 1.
Every map names the quests it starts, in the Metadata.json inside its .goamap file:
Those quests are handed out when the map is loaded, whatever their _requirements say. A map that names none - every older map, and a map whose field was left empty - starts the game's default quest line, quest0, so no map is ever without quests.
The shipped quest0 carries requirement type 3, and every later questN requires the one before it. So the moment a map lists your quest instead of quest0, the whole shipped main line stays away from that map - which is usually what a campaign wants. If you want both, list both: ["quest0", "mycampaign_first_steps"].
To make a quest belong to a map, and only to that map, do both halves:
StartingQuestIds.{ "_requirementType": 3, "_value": "" } so no other path - not an empty requirement list, not another quest completing - can start it elsewhere.A quest with an empty requirement list still starts everywhere, listed or not. A quest with only type 1 still starts wherever its predecessor completes. Type 3 is the only thing that says "here and nowhere else".
StartingQuestIds list is the whole story. The two mechanisms are independent - a campaign map typically uses both, tags for its missions and StartingQuestIds for its quests.In the game. Open the map in the map editor and find the Starting quest field in the map settings, next to the tags. Type the quest ids separated by commas - quest0, mycampaign_first_steps - and save the map. Maps you save this way land in your Maps folder (next to the Mods folder above); copy the .goamap into your mod's Maps/ folder to ship it. A map that already lives inside a mod folder cannot be saved over from the editor - edit the copy in Maps, then replace the one in the mod.
In a text editor. A .goamap is an ordinary zip archive with a different extension. Open it with any archive tool, edit Metadata.json, and put it back with the same name. Everything else in the archive stays as it is. StartingQuestIds sits at the end of the file, next to _tags; add the key if it is missing.
An id in the list that no quest file provides is skipped without a message in the shipped game (the Unity editor logs a warning); the map still loads.
To change a quest the game ships with, drop a file with the same name into your mod's Quests/. Your copy replaces the shipped one entirely, so start from a full copy of the original and change what you need: an _amount, a _parameter, a step made optional, a step added or removed.
The shipped files are plain JSON inside the game's installation folder, under <game>_Data/StreamingAssets/Scripts/Quest/ (inside the app bundle on macOS) - quest0 to quest14, the tutorial_* quests and the *_skin_unlock quests. Copy from there; never edit them in place, because a game update overwrites that folder. The shipped maps sit next to them in StreamingAssets/Maps/, which is also the place to look at a real Metadata.json.
Changes reach existing saves too. When a save is loaded, every quest already in it is compared with the current file: step titles, step descriptions, requirement types, parameters and amounts are updated in place, steps you added are appended, steps you removed are deleted, and a step whose progress already meets the new amount completes right away. Steps are matched by position, so inserting a step in the middle re-labels everything after it in a running save - append new steps at the end when a quest is already out in the wild. Not updated in a running save: the quest's own _questTitle, _questDescription and _isHiddenInUI, and a step's _isOptional and _genericIconKey - those are fixed when the quest is first handed out.
_questType: 0 is a normal quest and the one you want. The other two exist for the game's own content, and both come with strings attached.
Tutorial quests (2) additionally point the tutorial highlight at the buttons listed in _highlightedUIElements, one after the other, and can run cheat commands from _cheatsOnStart and _completionCheats. In a mod:
SawStation, Sickbed, ParkingSmall, CrewRoleDropdown, …) are the vocabulary. An unknown id does nothing.Aircraft-skin quests (1) are created once per aircraft whose role or id appears in the first step's _parameter, and the aircraft's id is appended to every step's parameter. On completion they unlock a skin - but which skin is a table inside the game keyed by the shipped quest ids, so a new quest of this type unlocks nothing.
The same table is what makes completing quest2 unlock new buildings: rewards are not part of the quest file. A mod quest cannot unlock a building, an aircraft or a skin. What it can do is gate: requirement type 1 chains quests behind each other, and a quest step can wait for a mission chain. The reverse is not available - a mission can be gated by map tags, runway tier, a day window or a completed mission, but not by a quest (see Missions).
Three complete quest files to open, copy and change. Each one goes into Mods/<your mod>/Quests/ under the file name shown; the titles are localisation keys you give words to as described in Text.
| File | What it shows |
|---|---|
| example_first_steps.json | The quest from A first quest: one required step waiting for a finished sickbed, one optional step counting beds. Starts on every map. |
| example_patrol_chain.json | A follow-up quest. It starts once example_first_steps is complete, waits for a Spitfire to be owned, then for the shipped mission calm_supply_drop (see Example missions) to come back a success, and optionally counts three winning fighter sorties. Note that calm_supply_drop itself only appears from day 20 with a tier-3 runway, so the mission step cannot progress before that. |
| example_map_campaign.json | A quest that belongs to one map. Requirement type 3 keeps it off every other map; the map lists it in StartingQuestIds (see Quests and maps). Its steps use the counted-state types: an airstrip of tier 1, two parking spots, a storage zone of twenty tiles. |
Install all three together and you have a two-quest chain plus a map-bound quest to compare against. Rename the ids before you build on them - example_ is only a placeholder prefix.
The game's own quest files, exactly as they ship. They show what the real thing looks like; remember that a mod file with the same name replaces the shipped quest, so rename a copy before you change it.
| File | What it shows |
|---|---|
| quest0.json | The first quest of the main line: requirement type 3, so it only starts on maps that list it in StartingQuestIds. Its steps are the counted-state types - an airstrip of tier 1, a parking spot, a Gladiator, beds. |
| quest1.json | The second quest, chained on quest0 with requirement type 1. It mixes event steps (harvesting_finished, project_finished) with a workbench count, and has an optional step. |
| fighter_day_skin_unlock.json | An aircraft skin achievement: _questType: 1, hidden from the quest panel, and the only place where a role name (fighter) is allowed where an aircraft id normally goes - see Quest types. |
| tutorial_building.json | A tutorial quest: _questType: 2 with _highlightedUIElements that point the player at the interface while the steps are open. |
Load a level again after every edit (a new folder needs Refresh in the Mods window first), then use the developer console (Options → Cheats, then type into the console and press Enter):
| Command | Effect |
|---|---|
quest <id> | Hands out the quest right now, whatever its requirements or map say. The console suggests loaded quest ids as you type - if yours is never suggested, the file was not read. Running it twice creates a second copy of the quest. |
complete_current_quests | Completes every open normal quest, so the next links in a chain start. |
go_to_quest <id> | Completes every quest the named one requires (through requirement type 1, following the chain back), so the named quest is handed out. It does not complete the named quest itself, and it works for mod quests too. |
start_shipment <Resource> <amount> … | Puts resources on the base - start_shipment Wood 12. |
create_mission <mission id> | Puts a mission on the map to test a mission-return step. |
When a quest does not show up, or a step does not move, read the game's log file:
| Platform | Log |
|---|---|
| Windows | USERPROFILE%\AppData\LocalLow\Blindflug Studios\Ground Of Aces\Player.log |
| macOS | ~/Library/Logs/Blindflug Studios/Ground Of Aces/Player.log |
| Linux | ~/.config/unity3d/Blindflug Studios/Ground Of Aces/Player.log |
A quest file that is not valid JSON is not skipped - it breaks the loading of the level, so validate your JSON in an editor before you test. A map that lists an unknown quest id, and a step that never progresses because of a wrong _type or a misspelt id, get no line in the shipped game's log - check the tables above.
{ and [ closed, a comma between entries and none after the last one._questId, and both carry your mod's prefix._amount is at least 1._parameter; types 20 and 24 have their second token.any_skill_type; any of 12, 13, 17 that is not empty includes at least one aircraft id._requirementType: 2._requirementType: 3 and the map lists them; side quests that should start everywhere have an empty list on purpose._parameter.A quest that has been handed out lives in the savegame - name, progress and requirement - independently of your file. Saving and loading with the mod installed is uneventful. A quest you add in an update appears in existing saves the next time they are loaded, as long as its requirements pass.
Remove the mod and the quest stays in the save, still visible, frozen where it was. Nothing removes a quest because its file is gone, and the game's own translation of your keys goes with your script, so the card shows the bare keys. Steps that wait for your missions can never move, because those missions no longer exist. Putting the mod back restores everything - text, progress, no duplicates.
For the player this means: a quest that can be finished leaves a tidy save behind; one that strands them halfway through a chain does not, and there is nothing they can do about it from inside the game. Prefer quests that reach an end, and treat removing a quest from a published mod as a breaking change for anyone mid-playthrough.
For anything that has to decide, use a mission or an event script (see Missions) and let the quest report where the player has got to.