Skip to content

Configuration ​

EmakiDungeon ships three configuration files: the global plugins/EmakiDungeon/config.yml, the per-dungeon plugins/EmakiDungeon/world/<dungeonId>/config.yml, and the reward box GUI plugins/EmakiDungeon/gui/rewardbox.yml. After you edit them, run /edg admin reload (this command is run by a player with emakidungeon.admin); running instances are unaffected, only newly created instances pick the changes up

The top-level version and language fields are maintained by the resource sync process — do not edit them by hand. Per-dungeon configs have no schema compatibility layer and are validated strictly at load time. The "Range" column below marks keys with source-level validation; keys showing — are not range-checked by the code, and invalid values are handled in one of two ways:

  • Load error (the dungeon is skipped, console reports an invalid dungeon configuration): pool.max-worlds, enter.prepare-window-seconds, enter.wait-timeout-seconds, enter.wait-channel, the limits.daily.time-window format, and days/weeks entries under limits
  • Silent fallback: the plugin drops invalid entries, clamps them to a boundary, or replaces them with the default (see each row)

Global config.yml ​

debug ​

KeyTypeDefaultRangeDescription
debug.enabledbooleanfalsetrue / falseDebug anchor logging; prints detailed instance, party, and limit events to console
debug.retention-daysint30—How many days audit and debug logs are kept before cleanup

limit and commands ​

KeyTypeDefaultRangeDescription
limit.max-instancesint20—Global cap on concurrent instance worlds (including spare worlds); new challenges are refused once reached
commands.modestringblacklistblacklist / whitelistCommand filter mode: blacklist refuses only what commands.rules lists, whitelist allows only what it lists
commands.ruleslist<string>[]See descriptionRule = command root + argument pattern, for example "/tpa player"; write the placeholder player where a player name goes
escape.blacklistlist<string>[]Supports * wildcardsEscape-command blacklist (for example "/tp *", "/back"); highest priority, no allow-rule can exempt it

party and isolation ​

KeyTypeDefaultRangeDescription
party.max-sizeint4—Party member cap
party.invite-modestringpublicpublic / apply / inviteWhat happens when a player without a party asks to join: public joins directly, apply files an application for approval, invite only lets invited players in (other values behave like invite)
isolation.global-chat-defaultbooleanfalsetrue / falseDefault global listening for new players; each player can switch with /edg globalchat at any time

general and rewardbox ​

KeyTypeDefaultRangeDescription
general.timezonestring""Empty or a timezone idTimezone for entry-limit bucketing; empty uses the server timezone
rewardbox.enabledbooleantruetrue / falseReward box master switch; when off, dungeon payouts go straight to the inventory, falling to the ground as drops when it is full

script GraalJS host ​

KeyTypeDefaultRangeDescription
script.enabledbooleantruetrue / falseLoad scripts/<dungeonId>.js with every instance; turning it off disables scripting entirely
script.timeout-msint5000—Timeout for a single script handler (milliseconds); on timeout the script is disabled and the instance continues
script.fail-on-errorbooleanfalsetrue / falseWhether a script failure fails the run; false only disables the script and keeps everything else running

monitor ​

KeyTypeDefaultRangeDescription
monitor.mspt-p95-msint55> 0, or <= 0 to disableConsole alert plus audit log entry when the steady-state MSPT P95 exceeds the value
monitor.mspt-p95-enter-msint200> 0, or <= 0 to disableMSPT P95 threshold for the enter/prepare phase: within 65 seconds after an enter-flow marker (world acquisition, wait, or entry completion) this value is judged instead, alerting and auditing the same way; all other times it falls back to monitor.mspt-p95-ms
monitor.memory-slope-mb-per-minint64> 0, or <= 0 to disableHeap slope (MB/minute) alert threshold
monitor.queue-backlog-secondsint5> 0, or <= 0 to disableSustained write-queue backlog (seconds) alert threshold

storage / folia / action ​

KeyTypeDefaultRangeDescription
storage.bstatsstringdisableddisabled only for nowbStats is not wired up this phase; it will be integrated through CoreLib once the interface lands
folia.held-worlds-maxint10—Global cap on suspended worlds on Folia; at capacity new challenges are refused as full and the state resets on restart
action.<segmentId>map{}Action pipeline linesDungeon lifecycle actions; the segment id is the key and the value is a CoreLib action pipeline

The action section supports 11 segment ids: dungeon_enter, dungeon_exit, dungeon_room_clear, dungeon_gate_open, dungeon_wave_start, dungeon_score, dungeon_complete, dungeon_fail, dungeon_reward, dungeon_ending, dungeon_destroy. You write them with the same syntax as the CoreLib actions, for example:

yaml
action:
  dungeon_enter:
    - 'self | send_message text="<green>进入副本</green>"'

Per-dungeon world/<dungeonId>/config.yml ​

When this file is missing, the plugin generates it from the bundled template at startup or reload; existing files are never overwritten

Metadata and entry ​

KeyTypeDefaultRangeDescription
display-namestring示例副本Any textDisplay name shown in lists and messages (bundled template default)
descriptionstring一份用于演示的线性副本配置Any textDungeon description (bundled template default)
difficulty-groupstringdefaultAny identifierDifficulty group identifier
enter.timeout-secondsint1800—Per-run time limit (seconds); when it expires the run is failed: DungeonFailEvent (TIMEOUT) fires and a failure settlement runs (audit [settle] records event=fail, reason=timeout and duration_ms; settlement commands and drops still execute), players are sent back to their pre-entry position, and the instance is destroyed as fail:timeout; DungeonCompleteEvent is not fired and the leaderboard is not updated
enter.prepare-window-secondsint10>= 1Ready-confirmation window (seconds); missing the window cancels the challenge; below 1 the dungeon fails to load
enter.wait-channelstringbossbarbossbar / scoreboard / chatProgress channel for the world preparation wait; any other value fails dungeon loading
enter.wait-timeout-secondsint60>= 1Maximum world preparation wait (seconds) before auto-cancel; below 1 the dungeon fails to load
pool.max-worldsint5>= 1Instance world cap for this dungeon (including spares); at capacity players are told to retry later; below 1 the dungeon fails to load
pool.warm-reservesint2>= 1 (lower values clamp to 1)Hot spare count = active instances + this value (never above pool.max-worlds); 2–3 is recommended so clone/mount finishes before the next entry and spare creation never overlaps the player's entry spike; defaults to 2 when absent

limits entry limits ​

The evaluation order is fixed as month > week > day: if any tier is unsatisfied or exhausted, entry is refused and lower tiers are not evaluated. count: 0 means unlimited for that tier, and negative values are treated as 0

KeyTypeDefaultRangeDescription
limits.daily.countint1>= 0Entries per day; 0 is unlimited
limits.daily.time-windowstring"""HH:mm-HH:mm" or emptyDaily challenge window; may cross midnight (for example "23:00-01:00"); a malformed value fails dungeon loading
limits.weekly.countint0>= 0Entries per week
limits.weekly.dayslist<int>[]1–7 (1 = Monday)Allowed weekdays; empty list does not restrict; a bad entry fails dungeon loading
limits.monthly.countint0>= 0Entries per month
limits.monthly.weekslist<int>[]1–6Allowed week-of-month (Monday-based); empty list does not restrict; a bad entry fails dungeon loading
limits.cooldown-secondsint0>= 0Cooldown between entries; negatives become 0

world and difficulty ​

KeyTypeDefaultRangeDescription
world.simulation-distanceint6—Simulation distance applied per instance world
world.entity-limitint0—Entity cap per instance world; 0 means unlimited
difficulty.<tier>.mob-multiplierdouble1.0 (normal)>= 0Mob stat multiplier; negatives clamp to 0
difficulty.<tier>.drop-multiplierdouble1.0 (normal)>= 0Drop amount multiplier; negatives clamp to 0
difficulty.<tier>.respawn-countint3 (normal)—Remaining player respawns before spectating

The template ships normal and hard tiers (hard uses 1.5 / 1.2 / 1), and players pick one in the difficulty panel of the entry flow. Leave the difficulty section empty to keep the default two tiers, or add and remove tiers freely

score and drop ​

KeyTypeDefaultRangeDescription
score.damage-weightdouble1.0—Damage contribution weight
score.kill-weightdouble1.0—Kill contribution weight
score.heal-weightdouble1.0—Healing contribution weight
score.death-weightdouble1.0—Death contribution weight
score.defense-weightdouble1.0—Damage-taken / defense contribution weight
score.maxdouble100.0Falls back when <= 0Score cap (completion time is not weighted yet); 0 or a negative value silently restores the default 100
drop.levelsmapcommon: 1, rare: 3, epic: 5Integers, values below 1 become 1Drop level weights, used by the score-based distribution mode
drop.default-modestringfreeSee mode-allowedDefault drop distribution mode; an unknown mode falls back to free
drop.mode-allowedlist<string>[free, roll, killer, score, share]Subset of the five modesModes offered to the leader in the distribution panel; invalid entries are dropped, and if all are invalid the default five are used

The five modes: free vanilla drops for anyone to pick up, roll automatic rolling, killer to the killer, score weighted by run contribution, share split across the party; drop.mode-allowed decides which of them appear in the panel

Remaining per-dungeon keys ​

KeyTypeDefaultRangeDescription
commands.allowlist<string>[]Same syntax as global commands.rulesExtra commands allowed in this dungeon; can override the regular guard, never the escape blacklist
interaction.containersbooleantruetrue / falseWhether containers can be opened inside the dungeon
interaction.hoppersbooleanfalsetrue / falseWhether hoppers work; off by default
timer.messageslist<int>[300, 60, 10]Second marksCountdown reminder marks pushing "N seconds left" to players
settlement.commandslist<string>[]Console command linesCommands executed one by one on clear; %player% placeholder supported, handy for EmakiItem/EmakiLevel payouts
leaderboard.max-entriesint100Falls back when < 1Leaderboard entries kept before evicting the worst; 0 or a negative value restores the default 100

Reward box GUI gui/rewardbox.yml ​

The layout of this GUI is fixed and not configurable; only two numbers are exposed:

KeyTypeDefaultRangeDescription
default-pagesint1—Base visible pages for players without a higher page permission
capacity-slotsint135—Total reward box capacity in slots; reaching it means the box is full - see Challenges & Rewards for the full rules

Flow file world/<dungeonId>/flow.yml ​

This file holds every flow module (rooms, waves, gates, options) and is generated when missing. See Flow & Triggers for the full structure