Campaigns.wiki
author Wuzzy
Wed, 28 Jun 2023 22:14:36 +0000
changeset 2261 55bd0ae9d187
parent 2101 a0a6ebfa2aab
permissions -rw-r--r--
LuaLibraryUtils: Add formatEngineString

#summary How to create campaigns

= Campaigns =

== Introduction ==
A campaign is a series of missions that tell a story. Campaigns are played in singleplayer mode only.

== Campaign files ==
Campaigns are stored in `Data/Missions/Campaign/<CAMPAIGN NAME>`, with `<CAMPAIGN NAME>` being the campaign name.

In this directory, the following files are used:

 * `campaign.ini`: Campaign mission list
 * `*.lua`: A bunch of Lua scripts for the missions

=== `campaign.ini` ===
This is a file in the INI format. This lists the available missions.

 * No section:
  * `MissionNum`: Number of missions
  * `ResetRetry`: Unused
 * `[Mission X]`: Configuration for mission `X`, where X is the mission number. Mission 1 is the first mission.
  * `Name`: Human-readable mission name in English
  * `Script`: Name of Lua script file to load for this mission

=== The mission's Lua scripts ===
There's one Lua script per mission. Scripting works basically like in singleplayer missons, see [Missions].

Exception: Campaign missions use campaign variables instead of mission variables to track progress.

=== Preview image ===
The preview image is displayed in the menu when you have selected the mission.
It must be a PNG image of size 314px×260px.

The file must be saved in `Data/Graphics/Campaigns/<CAMPAIGN NAME>`. The file name must follow this pattern:

`<mission script name>@2x.png`

Where `<mission script name>` is name of the mission script without the file name suffix.

For example, the preview image for the mission script `mission1.lua` must have the name `mission1@2x.png`.

=== Localization ===
Campaign title, mission titles and mission descriptions menu must be edited in the missions files in `Data/Locale`. The file name is `campaigns_<language code>.txt`. There is one file per language. E.g. `campaigns_en.txt` for English. Note that these files are supposed to contain the titles and descriptions of *all* campaigns on your computer. This makes these files unsuitable for sharing or inclusion into [HWPFormat HWP files], for example.

This is the syntax:

{{{
<campaign dir name>.name="<campaign name>"

<campaign dir name>-<mission 1 script name>.name="<mission 1 name>"
<campaign dir name>-<mission 1 script name>.desc="<mission 1 description>"

<campaign dir name>-<mission 2 script name>.name="<mission 2 name>"
<campaign dir name>-<mission 2 script name>.desc="<mission 2 description>"
}}}

And so on.

 * `<campaign dir name>` is the directory name of the campaign. Replace spaces with underscores here.
 * `<campaign name>` is the human-readable campaign name.
 * `<mission x script name>` is the file name of the script of mission _x_ without file name suffix
 * `<mission x name>` is the human-readable name of mission _x_
 * `<mission x description>` is the description of mission _x_

If something is, the campaign menu will derive the title from the directory/file names instead and shows no description.

For more information about translating Hedgewars, see [Translations].

==== Example ====

Excerpt from `campaigns_en.txt`:

{{{
A_Classic_Fairytale.name="A Classic Fairytale"

A_Classic_Fairytale-first_blood.name="Mission 1: First Blood"
A_Classic_Fairytale-first_blood.desc="Help Leaks a Lot to complete his training and become a proper hedgehog warrior. You will be trained in the art of rope, parachute, shoryuken and desert eagle."
}}}

== Campaign variables / campaign progress ==
Campaigns support campaign variables which allow to store arbitrary values about the campaign in the team file. Most importantly, the campaign progress is stored here. This uses the functions `SaveCampaignVar` and `GetCampaignVar`. Note that `SaveMissionVar` and `GetMissionVar` do *not* work in campaign missions.

Initially, only mission 1 is unlocked. To unlock more missions and to mark missions and the campaign as completed, you must set campaign variables. For linear campaigns, you can use this idiom:

{{{
-- To be called when mission 5 was won:
local progress = tonumber(GetCampaignVar("Progress"))
if progress == nil or progress < 5 then
    SaveCampaignVar("Progress", "5")
end
}}}

For non-linear campaigns, a more sophisticated unlocking is available.

Read [ConfigurationFiles] to learn how campaign variables work in detail.