# Campaign editor The campaign editor is part of the game: *Campaign editor* in the title menu. It works with the game's own graphics and needs a mouse and a keyboard (desktop). It has three levels: 1. the **campaign graph** – all missions as cards, linked by arrows, 2. the **mission** – settings, goals and branches, map, scripts, 3. the **map editor** and the **block editor** for one mission. Code: `src/editor/` (`mod.rs` graph and mission pages, `map.rs` map editor, `blocks_ui.rs` block editor, `widgets.rs` the small interface toolkit, `templates.rs` demo campaign and templates), the file format in `src/campaign_doc.rs`, the scripts in `src/blocks.rs` and `src/mscript.rs` (see [MISSION_SCRIPTING.md](MISSION_SCRIPTING.md)). ## Campaign graph - Top bar: campaign name, author, the campaign's language (one language per campaign), and the buttons *Play*, *New*, *Open*, *Save file*, *Save online*, *Close*; *+ Mission* adds a card. *Published* (after saving online) puts the campaign into the public list. - A card shows the title, random or painted map and its size, the goals, the number of triggers and, in red, the number of problems in its scripts. - Click a card to open the mission. Drag a card to move it; drag with the right (or middle) mouse button to move the view. - Links: drag from the **gold dot** of a card onto another card – that is the *next mission*. The **blue dots** are branches; the empty blue ring makes a new branch. Dropping a link on empty space removes it. The `x` on a card deletes the mission (click twice). - *Play* plays the whole campaign from the first mission, following next missions and branches; at the end (or via the pause menu) the editor comes back. ## Opening *Open* offers: - a `.dccamp` file (or drop the file onto the window), - **Open the demo** – the demo campaign, which uses every trigger kind and every special script, - **a mission of the built-in campaign as a copy** – its map as it starts, its texts and goals, added to the current campaign (the original stays untouched), - **my campaigns (online)** and **published campaigns** of all players (needs a login on a server with the savegame service). ## A mission The mission page has four tabs and a **Test play** button. Test play starts the mission with the script debug view (trigger zones on the map, the variables and a log of which trigger fired when); *Back to the editor* in the pause menu – or the end of the mission – returns to the editor. ### General Title, briefing (shown when the mission begins; Enter starts a new paragraph), starting gold, time limit, and hero waves (number of waves, time to the first wave). ### Goals - The goals of the mission; it is won when all are reached. Goals the map cannot have (shards on a map without shards, the gate without a gate, ...) are left out when the mission starts, so they can never be won by accident. A mission without goals is won only by a script (*Win*). - *Next mission*. - *Branches*: another goal (with its number) leads to another mission if it is reached first; the higher priority wins when several are reached. Goal kinds: defeat all heroes, take the shards, destroy the gate, raze the knight towers, defeat the rivals, loot gold (amount), survive waves (count), claim mana springs (count), free creatures (count). ### Map A mission has a **random map** or a **painted map**: - **Random map**: size, seed, water rivers (0–3), lava rivers (0–2), knight fortresses (0–3), rival masters (0–2), difficulty and portals. It is rolled **once per run of the campaign** (the run's seed is kept, so a restarted mission has the same map) – its scripts should use triggers without fixed places (timers, events, values) or zones that are sure to fit. - **Generate and paint the map** makes a map from these settings and opens the map editor; when it is done the mission has a **painted map**: the whole game state is stored in the campaign file, so it never changes. *Make it a random map* goes back. ### Scripts - **Special scripts**: *Start* (once), *Victory check*, *Defeat check* and *Clock* (every second). - **Triggers**: name, kind, *once* (fires only the first time) and *active* (switched on from the start). The second line holds the condition: zone, side, unit kind, comparison, number, time, ... *Blocks* opens the trigger's script. A red frame means a problem (missing zone, script problems). ## Map editor The map in the game's 3D view; tool bar on the left, options on top. | Tool | What it does | |---|---| | Ground | floor, earth, reinforced wall, rock, water, lava, bridges, gold/silver/ruby/diamond veins, steel; with an owner for floor and walls | | Rooms | the 14 rooms (and plain floor), with an owner | | Places | soul core (moves it), portal, hero gate (moves it), mana spring, core shard, rune chest, chained creature (kind, level) | | Units | creatures and heroes: kind, side (player, heroes, Mossgrim, Lady Nightwell, rival 3), level | | Towers | arrow, cannon, magic, rune forge tower; the dungeon's or the knights', level 1–3 | | Traps | the seven traps and three doors, armed | | Forts | a knight fortress (with or without a shard), rival masters (Mossgrim, Lady Nightwell, rival 3); level = strength | | Zones | trigger zones: rectangle, circle (drag from the middle), painted tiles (paint onto the selected tiles zone), line (drag from start to end); name, rename, delete | | Erase | removes units, towers, traps and doors on a tile | Options: brush size 1–5, rectangle, fill (connected area of the same ground), mirror (left/right, top/bottom, both – for fair maps), undo/redo (Ctrl+Z / Ctrl+Y). Camera: right button moves, middle button turns, wheel zooms, WASD/arrows and Q/E. *Done* stores the map in the mission. ## Block editor See [MISSION_SCRIPTING.md](MISSION_SCRIPTING.md). In short: the palette on the left (categories Speak, Units, World, Logic, Variables, Mission) – drag a block into the script; move blocks by their grip `≡`, drop them on the palette to delete them; the fields inside a block are set right there; the small switch in front of a value changes its kind (number, variable, gold, comparison, ...). Problems are marked red with a tooltip; the help line explains the block under the pointer. Ctrl+Z/Y undo/redo, Ctrl+C/V copy/paste the selected block, Delete removes it, Ctrl+F searches. ## Saving and sharing - **File**: `.dccamp` (JSON). A campaign with painted maps can be a few MB. - **Online** (server with the savegame service): own campaigns per user, overwrite on the next save; *Published* adds the campaign to the list every logged-in player sees and can open (as a copy) and play. Server API: `/api/campaigns`, `/api/public/campaigns` (see `server/src/main.rs`). - **Co-op**: the campaign last opened in the editor can be played in a co-op match (Multiplayer, *Editor campaign*), one mission per match; missions need a map of at least 72x72 and a goal besides rival masters. See `docs/MULTIPLAYER.md`. ## File format (`src/campaign_doc.rs`) ```json { "format": "dungeoncraft.campaign", "version": 2, "name": "...", "author": "...", "language": "de", "missions": [{ "key": "m01", "title": "...", "story": "...", "size": [96, 80], "seed": 101, "gold": 3000, "portals": 1, "goals": ["KillAll", "Loot(3000)"], "waves": false, "wave_limit": 0, "first_wave": 300, "time_limit": 0, "next": "m02", "branches": [{ "id": "b1", "goal": "Loot(5000)", "next": "m03", "priority": 1 }], "zones": [{ "name": "gate", "shape": "rect", "from": [40, 20], "to": [44, 24] }], "map": { "kind": "Random" }, // or { "kind": "Fixed", "game": "" } "gen": { "rivers": 1, "lava": 0, "forts": 1, "rivals": 0, "difficulty": 1 }, "scripts": { "start": [...], "victory": [...], "defeat": [...], "tick": [...], "triggers": [...] }, "pos": [40, 40] // the card in the graph }] } ``` Zone coordinates are tiles. Shapes: `rect` (`from`/`to`, inclusive), `circle` (`at`, `radius`), `tiles` (list), `line` (`from`/`to`). Version 1 files still load; their text scripts are not run.