Authoring Dungeons
A walk-in dungeon from CommonLib 2.4.0, written as one file in your pack
CommonLib (ZiggfreedCommon) 2.4.0 adds dungeons. A dungeon is one file in your pack. A player goes in from a block, a character or a conversation line and lands in an area set up for their party: a fresh paste of your prefab. Each member who follows them in lands in the same area, and another party gets an area of its own. A run clears when the party does what the dungeon asks, and each member there collects a completion reward on the results screen.
The worked example on this page is Seasons of Orbis' graveyard, The Horseman's Graveyard. While Hallow's Eve runs, the Gravekeeper near Old Jack in the Forgotten Temple sends whoever presses F on him into it, and a run clears when the Headless Horseman falls.
The dungeon file
Server/ZiggfreedCommon/Dungeons/<Id>.jsonDungeons/The filename is the dungeon's id, matched without regard to case. Every leaf is inherited through Parent. The owner layer is mods/ziggfreedcommon/dungeons.json.
{
"Enabled": true,
"Share": {
"PartyLocked": true,
"MaxPlayers": 5,
"AreasPerCopy": 4
},
"Area": {
"Prefab": "Hallows_Eve/Hallows_Eve_Graveyard.prefab.json",
"EntryOffset": {
"Y": 1
}
},
"Complete": {
"Bosses": [ "Hallows_Eve_Headless_Horseman_Encounter" ]
},
"Rewards": {
"Lootable": "Hallows_Eve_Graveyard_Clear",
"Diminish": { "Steps": [1, 0.5], "Window": "Daily" }
},
"Copy": {
"EmptyCloseSeconds": 60
},
"Season": "Hallows_Eve",
"Text": {
"NameKey": "dungeon.hallows_eve_graveyard.name",
"DescriptionKey": "dungeon.hallows_eve_graveyard.description"
}
}Every leaf is optional. The table lists them all with what you get when you leave one out; each group is covered in its own section below.
| Field | Type | Default | Description |
|---|---|---|---|
Instance | string (template id) | ZiggfreedCommon_Dungeon_Void | The world template every copy starts from. See The world template. |
Enabled | bool | true | False closes the dungeon without deleting the file. |
Share | {PartyLocked, MaxPlayers, AreasPerCopy} | true, 5, 4 | Who goes in together, and how many parties one copy holds. See Parties and areas. |
Area | {Prefab, Spacing, EntryOffset} | none, 2048, the paste spot | The prefab pasted for each party, how far apart areas sit, and where a player lands. See The area prefab. |
Run | {TimeLimitSeconds, FailOnWipe} | no limit, false | How a run fails. See Runs. |
Complete | {Bosses, AllBosses, Objective, SurviveTimer} | nothing clears | What clears a run. See What clears a run. |
Rewards | {Lootable, Diminish, InChest} | pays nothing | The completion Claim. See The completion Claim. |
Copy | {EmptyCloseSeconds} | 60 | How long a copy stands once every area in it is empty, in seconds, before it closes. |
Difficulty | string | "" (normal) | A label for a harder version of a dungeon, such as Hard. Its runs are counted under it, and its completion Claim's repeat count is kept apart. |
Season | string (calendar event id) | all year | The calendar event the dungeon opens for. See When it is open. |
Text | {NameKey, DescriptionKey, ChestKey} | the id | Keys in your own lang file: the dungeon's name, which the lines a player reads about it use, and a line or two saying what it is. With no NameKey those lines show the id, and the completion Claim is titled with the Claims tab's own word, Rewards. ChestKey is the line under a clear's banner when Rewards.InChest puts the Claim in the boss's chest; unwritten, the library's own line says the reward waits in the chest where the boss fell. |
The graveyard's name is dungeon.hallows_eve_graveyard.name in the pack's hallowseve.world.lang, "The Horseman's Graveyard". Write the key as it stands in your own lang file, without the file's name in front.
The world template and the area prefab
Each copy of a dungeon is a world of its own, started from a world template. Your prefab is pasted into it once for each party that goes in, each paste in an area of its own.
The world template: Instance
Instance names a native instance template by its folder under Server/Instances/. Leave it out and every copy starts from the library's own, ZiggfreedCommon_Dungeon_Void: an empty void world in Adventure mode that saves nothing, running the library's dungeon gameplay config, ZiggfreedCommon_Dungeon. That config gets a player who dies back up in their own area with everything still in their bag (their gear still loses some durability, as on any death), and keeps every block as it was built (see Block rules).
If you name a template of your own:
- It must not pin its world with an
InstanceKey. A dungeon whose template does is an error, and it refuses entry. - While
Share.AreasPerCopyis above 1, it must run no portal timer and no world events: both belong to the whole world, so every party in the copy would share them. Either is an error that refuses entry. SetAreasPerCopyto 1, or name a template without them. - Its gameplay config sets the rules inside. The game's own
Default_Instancesends a player who dies out of the instance, and the game'sDefaultdrops half of each droppable stack on a death. To keep the library's rules, give your config the sameDeath.RespawnController,Death.ItemsLossModeandPlugin.ZigBlockRules, or makeZiggfreedCommon_DungeonitsParent.
The area prefab: Area
| Field | Type | Default | Description |
|---|---|---|---|
Prefab | string (path) | none | The prefab pasted into each area, as its path under Server/Prefabs/ with its extension, such as Hallows_Eve/Hallows_Eve_Graveyard.prefab.json. A dungeon with none, or with a path no loaded pack ships, cannot be entered. |
Spacing | int (blocks) | 2048 | How far apart two areas of one copy sit. While areas are shared it must be at least twice the server's view distance in blocks, or parties see each other and the dungeon refuses entry. 2048 is enough for any view distance. |
EntryOffset | {X, Y, Z} | the paste spot | Where an arriving player lands, in blocks from the spot the prefab is pasted at. |
- The prefab is pasted with its anchor on the area's spot, at height 64. Areas sit two to a row,
Spacingblocks apart. - The paste carries the prefab's entities and block states, so a boss fight, a spawn marker or an exit pad saved in the prefab comes with it.
- Every party gets a fresh paste. Before a used area is pasted again, the library clears out what the last party left there: creatures, drops and projectiles, never a player. It also empties every chest and other container inside the prefab's box, so each one starts with only what its own drop list puts in it, and the paste line in the log counts the containers it emptied.
- The area is pasted while the arriving player sits on the loading screen. A player who arrives while a new copy is still opening waits for it rather than opening another. Each paste's time is logged under
[dungeon].
The graveyard's prefab, Hallows_Eve/Hallows_Eve_Graveyard.prefab.json, is an enclosed graveyard whose anchor is the floor of its entrance room, so EntryOffset Y 1 stands an arriving player on that floor. It carries the Horseman's fight and his spawn marker, so every fresh paste stages a fresh fight, and a vanilla Leave_Instance pad behind the arrival spot.
Give players a way out
Leave_Instance block sends whoever walks onto it back where they stood when they went in. Put one in your prefab where players arrive.When it is open: Enabled and Season
A dungeon can be entered while Enabled is true (the default) and, when it names a Season, while that calendar event runs. Season takes a calendar event's id, such as Hallows_Eve; leave it out for a dungeon open all year. A child keeps its Parent's Season.
- Outside its season, a way in tells the player which event it opens for: "The Horseman's Graveyard only opens during Hallow's Eve." An event with no name reads "only opens in its season".
- Switched off, it reads "The Horseman's Graveyard is closed for now."
- A
Seasonno calendar event defines keeps the dungeon closed, and the audit warns about it.
The Gravekeeper's placement names the same Season, so outside Hallow's Eve he is not in the temple at all.
Parties and areas: Share
| Field | Type | Default | Description |
|---|---|---|---|
PartyLocked | bool | true | True: an area holds one party, and a player outside it gets an area of their own. False: players who are not in a party together share an area while it has room. |
MaxPlayers | int | 5 | How many players one area holds, counting those still on their way in. Less than 1 reads as 1. |
AreasPerCopy | int | 4 | How many parties share one copy, each in its own area. 1 gives every party a world of its own. |
- A player goes in with their party: the library's own party, which any player starts with
/zigpartyon a server running CommonLib. A player in no party is a party of one, so a dungeon can always be run alone. - Members go in one at a time, each through the way in. The first reserves an area, and each member who follows lands in it. Only members on their way in or inside count against
MaxPlayers, so a member who is offline neither goes in nor holds a place. When the area is full, the next member reads "There is no more room with your party in The Horseman's Graveyard." - A party fills a free area of an open copy before a new copy opens. A copy is a world named after the dungeon and a number, in lower case, such as
hallows_eve_graveyard-1. A copy whose ticks run slow (over 25 ms on average) takes no new party, and neither does a copy about to close. - A player who dies gets back up in their own area. A player who leaves the world or the server is no longer one of its members, and neither is one who walks more than half a
Spacingfrom their area's spot in a copy of more than one area. A player still on the way in after two minutes is let go.
The party's size and invite rules are the library's party settings, Server/ZiggfreedCommon/Party/ZiggfreedCommon.json: MaxSize 5, InviteTimeoutSeconds 60 and OwnerOnlyInvite false. A change there takes effect after a restart.
The way in
There are three ways in, and all three run the same entry with the same checks: a block's interaction chain ending in ZigEnterDungeon, a character's press F, and a conversation line. The last two open the Dungeon destination.
From a block: ZigRequires, then ZigEnterDungeon
{ "Type": "ZigEnterDungeon", "Dungeon": "<Id>" } sends the player in with their party. It decides nothing about who may go: put the gate in front of it. ZigRequires runs its Next for a player who meets its Requires block and its Failed for one who does not, and tells that player, in an error notice, the first thing they still need. Its Requires is the shared block a quest's gate uses (see Requirements); left out, it lets everyone through.
"Interactions": {
"Use": {
"Interactions": [
{
"Type": "ZigRequires",
"Requires": { "Quests": ["Yourpack_Intro"] },
"Next": { "Type": "ZigEnterDungeon", "Dungeon": "Yourpack_Crypt" }
}
]
}
}ZigEnterDungeonfinishes, running its ownNext, only when the player is on their way in. A refusal tells the player why (see below) and takes itsFailedbranch.- A player who is dead, still arriving from a teleport or being teleported is turned away without a word, as the game's own instance portals do.
- Any interaction chain can end in it, such as the
CollisionEnterchain of a pad players walk onto, the key vanilla'sLeave_Instancepad uses for its way out.
ZigRequires is also a trigger volume condition: { "Type": "ZigRequires", "Event": "ENTER", "Requires": { ... } } in an effect's Conditions lets the volume act only for a player who meets it, and says nothing to anyone else. Every boot, the library reads each pack's Server/TriggerVolumes/Effects/ files and logs one SEVERE line under [gate] audit for a ZigRequires condition that cannot be read, writes a key it does not know, or spells its Type slightly wrong, since the game would let everyone through such a volume. On an MMO Skill Tree server, /mmoconfig validate and its startup content audit list the same findings under gate, as ZigRequires volume validation.
From a character or a conversation: the Dungeon destination
{ "Type": "Dungeon", "Dungeon": "<Id>" } goes wherever an Open goes: a placement's Interact.Open, which runs on press F, or a conversation line's open action. The entry runs a moment later on the player's world. A player who is sent in has the page they have open closed as the loading screen takes them; a refused one reads why where they are looking. The Gravekeeper is placed this way:
{
"Name": "Hallows_Eve_Gravekeeper_Temple",
"Enabled": true,
"Where": {
"GameplayConfig": ["ForgottenTemple"]
},
"Identity": {
"Role": "Hallows_Eve_Gravekeeper"
},
"Anchor": {
"WorldSpawn": {
"Offset": { "X": -7.5, "Z": 4.5 },
"Yaw": 180.0
}
},
"Season": "Hallows_Eve",
"Lifecycle": {
"KeepAlive": true,
"Respawn": true,
"Fortify": true
},
"Interact": {
"Open": { "Type": "Dungeon", "Dungeon": "Hallows_Eve_Graveyard" }
}
}His role, Hallows_Eve_Gravekeeper, runs { "Type": "ZigPlacementInteract", "Open": { "Type": "Dungeon", "Dungeon": "Hallows_Eve_Graveyard" } } when pressed, so a Gravekeeper nothing placed, such as one spawned by command, opens the graveyard too. A press F has no chain to put a gate in front of, so to gate a character's way in, have them open a conversation whose line carries a Requires condition (the shared requirements block) and opens the Dungeon destination: the line shows only to players who meet it. See Conditions, Destinations and Placed NPCs.
What a refused player is told
Every way in tells a player who cannot go in why, in an error notice drawn into the page they have open or else in the corner. The words are in the library's ziggfreedcommon.dungeon.lang; the dungeon's name is its Text.NameKey.
| When | The player reads |
|---|---|
Enabled is false | The Horseman's Graveyard is closed for now. |
| Its season is not running | The Horseman's Graveyard only opens during Hallow's Eve. |
| Their party's area is full | There is no more room with your party in The Horseman's Graveyard. |
| They are already on their way into a dungeon | You are already on your way into a dungeon. |
| They are already in a dungeon | You are already in a dungeon. Leave it first. |
| The copy closed as they were sent | The Horseman's Graveyard closed just as you got there. Try again. |
| A mistake in the pack: no prefab, a prefab no pack ships, an audit error, a copy that would not open | The Horseman's Graveyard cannot be entered right now. |
| A way in names a dungeon no loaded file defines | That dungeon cannot be entered right now. |
A player never reads a pack author's mistake: the server log says what went wrong. An unknown dungeon id is logged once per id.
Runs: Run
| Field | Type | Default | Description |
|---|---|---|---|
TimeLimitSeconds | int (seconds) | no limit | How long a run may last before it fails. Zero or less means no limit. |
FailOnWipe | bool | false | True fails the run the moment every member in the area is dead at once. False lets the party get back up and carry on. |
- A run begins when the first player arrives in a fresh area. It counts that player and everyone already on the way in, and whoever arrives later joins it. The dungeon's leaves are read once, when the run begins, so an edit changes the next run, not this one.
- It fails when its time limit passes, when every member has left the area (nobody in it and nobody on the way), or, with
FailOnWipe, when every member in the area is dead at once. - When the time limit or a wipe fails it, everyone still in the area reads why: "Time ran out in The Horseman's Graveyard. The run failed." or "Your whole party fell in The Horseman's Graveyard. The run failed." A run that failed because everyone left tells nobody.
- A run that has ended, cleared or failed, takes nobody new. The area holds no new run until everyone has left it, and then it is pasted fresh for the next party, so a party that wants to go again leaves and goes back in.
The graveyard writes no Run: its runs have no time limit, and a party that falls carries on.
What clears a run: Complete
| Field | Type | Default | Description |
|---|---|---|---|
Bosses | string[] (encounter script ids) | none | The boss fights that clear a run, by their file names under Server/EncounterManager/. A list you write replaces an inherited one whole. |
AllBosses | bool | false | False: the first fight in Bosses to be won clears the run. True: every one of them must be won in the run. |
Objective | {Kind, Target, MatchMode, Qualifier, Amount} | none | Something the party must do inside the area, written the way a quest step is. Every member's moments in the area count toward one total for the party. Amount defaults to 1 and MatchMode to CONTAINS; one with no Kind asks for nothing. |
SurviveTimer | int (seconds) | none | How long the run must last, from its first arrival, before it clears. Keep it under Run.TimeLimitSeconds, or the limit fails every run first. |
A run clears the moment every leaf you write holds. Write one or more of them: a dungeon whose Complete writes none has no clear, and its runs can only fail. A boss fight counts for the run of the area its players are in. The objective's fields are the ones on Objectives and criteria.
The graveyard writes Bosses alone, so its run clears when the Headless Horseman's fight, Hallows_Eve_Headless_Horseman_Encounter, is won. The library's own example of the other two leaves:
"Complete": {
"Objective": { "Kind": "PICKUP_ITEM", "Target": "MyPack_Crypt_Relic", "Amount": 3 },
"SurviveTimer": 300
}With both written, the party must pick up three relics between them and last five minutes.
The completion Claim and the results screen: Rewards
| Field | Type | Default | Description |
|---|---|---|---|
Lootable | string (loot table id) | pays nothing | The loot table a clear rolls once for each member in the area, by its id under Server/ZiggfreedCommon/Lootables/. See Shared loot tables. |
Diminish | {Steps, Window} | every clear in full | How much a repeat clear pays in one window, counted per player for this dungeon and difficulty. See Diminishing returns. |
InChest | bool | false | True puts each credited member's Claim in the chest a boss leaves when a boss fight wins the clear: no results screen opens, the member sees a banner naming the clear with Text.ChestKey's line under it, and opening the chest offers the Claim with the fight's own. A member the chest holds no share for sees the results screen either way. See Reward chests. |
At a clear, each member in the area earns one Claim: the table rolled once for them, titled with the dungeon's name (its Text.NameKey). Rewards are collected, never handed over unasked, so the Claim waits until the player takes it. A roll that lands nothing writes no Claim, and does not count as a clear for Diminish.
{
"Name": "Hallows_Eve_Graveyard_Clear",
"Rolls": [
{
"Grants": {
"Rewards": [ { "Kind": "Currency", "Params": { "Currency": "Hallows_Eve_Sweets", "Amount": "10" } } ]
}
},
{
"Grants": {
"Rewards": [ { "Kind": "Currency", "Params": { "Currency": "Seasons_Of_Orbis_Festival_Token", "Amount": "1" } } ]
}
}
]
}With "Diminish": { "Steps": [1, 0.5], "Window": "Daily" }, a player's first clear of the graveyard each day pays this in full, and every later clear that day pays half of it. The day turns over at midnight UTC. The graveyard also writes "InChest": true, so its clear's Claim waits in the chest the Horseman leaves where he fell, beside his own.
The results screen
- Each member in the area at the clear sees the results screen: "Dungeon cleared", the run's time, what they and their party did (their damage to the bosses, the bosses beaten), and their completion reward with a Claim button.
- Claim hands the reward over and shows a notice of what they got, a reputation's gain included, the same notice as Claim on the Claims tab. Whatever does not fit in their bags, and a reward they leave, waits on the Claims tab in their menu.
- There is no Play Again button: a dungeon is entered again at its way in.
- A member who is dead or offline at the clear sees no screen, and their Claim waits on the Claims tab all the same.
The Horseman pays two more Claims of his own from his fight's script, his daily Claim and his Boss Kill Claim. Those are boss Claims, not the dungeon's: see A boss's Claim.
Block rules
In a copy of the library's template, survival and adventure players break, place and gather nothing, so every party finds its area as it was built. A player in creative mode can still break blocks by hand. What a survival player sees:
- Hitting a hard block shows the hit puff, but no crack, and the block never breaks.
- A plant vanishes for a moment and comes back.
- A blast still sets off explosive barrels, boomshrooms and traps, which react before the library can refuse the damage.
The rules come from the library's dungeon gameplay config:
{
"Parent": "Default_Instance",
"World": {
"AllowBlockBreaking": true,
"AllowBlockGathering": false,
"AllowBlockPlacement": false
},
"Death": {
"RespawnController": {
"Type": "WorldSpawnPoint"
},
"ItemsLossMode": "None"
},
"Plugin": {
"WorldEvents": {},
"ZigBlockRules": {
"CreativeOnlyBreaking": true
}
}
}World.AllowBlockBreakingis true because the game refuses every break while it is false, a creative player's included.Plugin.ZigBlockRules.CreativeOnlyBreaking(false unless set) then refuses every other breaker before the block takes damage: survival and adventure players, NPCs, explosions, and a projectile, which counts as whoever fired it. It also keeps a block-group cycling tool to creative.- Set
CreativeOnlyBreakingfalse to let everybody break, orAllowBlockBreakingfalse to let nobody. - A
Worldgroup you write replaces the parent's whole group, so write all three block switches. APlugingroup merges over the parent's.
For server owners: dungeons.json
mods/ziggfreedcommon/dungeons.jsonEach top-level key is a dungeon id, merged leaf by leaf over what the packs ship; an id no pack ships is a dungeon of the owner's own. A key starting with $ is not a dungeon. The server reads it when it loads the dungeons.
{ "Hallows_Eve_Graveyard": { "Enabled": false } }{ "Hallows_Eve_Graveyard": { "Share": { "AreasPerCopy": 2 }, "Copy": { "EmptyCloseSeconds": 30 } } }A server owner changes any leaf of any dungeon this way, such as letting more players into an area, without touching the pack that ships it.
/zigdungeon
/zigdungeon list # every dungeon and how it is set up
/zigdungeon status # the copies open now: areas in use, players inside and on the way, tick time
/zigdungeon close hallows_eve_graveyard-1 # close a copy now; everyone inside goes back where they came in
/zigdungeon enter Hallows_Eve_Graveyard # go in yourself, in an empty areaentertakes you in as a party of one, in an empty area, through the same checks every way in makes. When it refuses, it says exactly why, such as the prefab path no pack ships.closerefuses any world the library did not open as a dungeon copy.- The permission nodes are derived from the names:
ziggfreed.ziggfreedcommon.command.zigdungeonfor the command andziggfreed.ziggfreedcommon.command.zigdungeon.<verb>for each verb, and a verb needs both. Nobody holds them until you grant them, and the console holds everything.
Checking your work
The first time anyone tries to enter a dungeon after it loads, the library checks it for errors, and a dungeon with an error refuses entry: players read "cannot be entered right now". Each error is logged once under [dungeon] audit, saying what to fix. The whole audit, warnings included, runs at boot on a server started with the environment variable ZIGGFREEDCOMMON_AUDIT_ON_BOOT=1, which suits a test server. A switched-off dungeon is not audited.
| Finding | Severity | Means |
|---|---|---|
TEMPLATE_INSTANCE_KEY | error | The template pins its world with an InstanceKey. Name a template without one. |
SPACING_TOO_SMALL | error | While areas are shared, Area.Spacing is under twice the server's view distance, so neighbouring parties see each other. |
PACKED_PORTAL_TIMER | error | While areas are shared, the template runs a portal timer, which would close every party's run at once. |
PACKED_WORLD_EVENTS | error | While areas are shared, world events run in the template, and an event reaches every party in the world. |
UNKNOWN_DUNGEON_TEMPLATE | warning | Instance names a template no loaded pack ships, so no copy can open. |
NO_DUNGEON_PREFAB | warning | No Area.Prefab is written. The dungeon cannot be entered. |
UNKNOWN_DUNGEON_PREFAB | warning | Area.Prefab names a path no loaded pack ships. Write it with its extension. The dungeon cannot be entered. |
NO_DUNGEON_CLEAR | warning | Complete writes nothing that can clear a run, or its SurviveTimer outlasts Run.TimeLimitSeconds, so every run fails. |
UNKNOWN_DUNGEON_BOSS | warning | A Complete.Bosses id names no loaded encounter script, so that fight never clears a run. |
UNKNOWN_DUNGEON_LOOTABLE | warning | Rewards.Lootable names no loaded loot table, so a clear pays nothing. |
UNKNOWN_SEASON | warning | Season names no calendar event on this server, so the dungeon stays closed. |
UNKNOWN_TEXT_KEY | warning | A Text key is in no loaded lang file, so it shows as the raw key. |
A warning about a missing template, prefab, boss or table may only mean its pack is not installed on this server.
Counting runs: quests, achievements and Records
A quest step, a board contract or an achievement criterion can count dungeon runs, in one dungeon or in any, with one of four objective kinds:
| Kind | Counts |
|---|---|
INSTANCE_ROUND_STARTED | A run started, for the first player in and everyone already on the way |
INSTANCE_ROUND_WON | A run cleared, for every member in the area at the clear |
INSTANCE_ROUND_ENDED | A run taken part in, cleared or failed |
INSTANCE_ROUND_LOST | A run that failed, for everyone who took part |
The Target is dungeon: followed by the dungeon's Difficulty, so dungeon: with MatchMode PREFIX counts any difficulty. The Qualifier is the dungeon's id; leave it out to count every dungeon. A step that counts clears of the graveyard:
{
"Kind": "INSTANCE_ROUND_WON",
"Target": "dungeon:",
"MatchMode": "PREFIX",
"Qualifier": "Hallows_Eve_Graveyard",
"Amount": 1
}- Records has a Dungeons tab ranking the runs each player started, cleared and failed across every dungeon on the server.
/zigstats showlists a player's lines for each dungeon and difficulty, such asDungeon_Runs_Completed/dungeon:@Hallows_Eve_Graveyardfor normal clears of the graveyard. A clear also counts as a round won. See Records. - A boss fought inside a dungeon gets a tab of its own on Records' Boss Fights, named for the fight and the dungeon: "The Headless Horseman in The Horseman's Graveyard".
Known limits
- In a copy of more than one area, a player who strays out of their area (more than half a
Spacingfrom its spot) stops being a member, and if they then die they get back up at the first area's spot. - A block item whose
BlockTypecarries a prefab list still pastes that prefab, even though placing blocks is refused. - Creatures held in chunk sections outside the prefab's own survive the clear between parties.
- A
Dungeondestination naming an id no file defines is caught only when someone first uses it, with one warning in the log. ZigEnterDungeonfires noEnterInstanceTeleporterEvent, the event the game's own instance portals fire.
Related
- Claims - the Claims tab, boss Claims and diminishing returns
- ZiggfreedCommon - what the library owns, its owner files and commands
- Objectives and criteria - the step shape an objective and a run counter use
- Placed NPCs - placements and what press F opens
- Records - the Dungeons tab and Boss Fights