Kzeroko KTM2

Quest Data

Define quest identity, prerequisites, selection conditions and resolution cooldowns.

Updated Sep 24, 2026 10 min read

A quest definition combines objectives, rewards and rules for when a player or team may accept it. Definitions reload as one validated catalogue: a broken prerequisite graph or invalid definition keeps the previous catalogue intact.

Where the files live

Use data/<namespace>/quests/**/*.json. Each file defines one quest; data/example/quests/misc/visit.json normally becomes example:misc/visit. An explicit id overrides that identity. Ordinary resource-pack priority selects the resource at a shared file path; different surviving files that claim the same quest ID reject the quest catalogue reload.

Quest definitions are server data. Titles and descriptions are client translations in assets/<namespace>/lang/en_us.json and zh_cn.json, not fields inside the quest. This checkout’s demonstration quests in docs/examples/quests/ are authoring fixtures rather than installed gameplay content.

Minimal example

This is the visit-location objective shape used by the demonstration fixtures, reduced to required fields. Save it at data/example/quests/first_tick.json. It completes on the next qualifying player tick after acceptance because it has no location filter; add an objective condition to require a destination.

{
  "tier": "misc",
  "prerequisites": [],
  "objectives": [
    {
      "id": "visit",
      "progress_type": "boolean",
      "type": "isekaiexpansion:visit_location",
      "data": {}
    }
  ],
  "rewards": []
}

Fields

Root

FieldTypeDefaultWhat it does
ididentifierFile resource IDOverrides quest identity; malformed identifiers reject the definition.
tierstringRequiredSelects the tier below; blank or unknown values reject the definition.
chapteridentifierisekaiexpansion:side_stories for misc and bounty; isekaiexpansion:prologue otherwiseGrouping ID. Trimmed; blank rejects. Unqualified names use isekaiexpansion. No separate chapter-registration check.
prerequisitesarray<object>RequiredAll listed completion requirements must hold. Empty accepts no prerequisite.
conditionsobjectNo additional pick restrictionContains pick; wrong container type rejects.
conditions.pickobject / array<object>Always trueGeneral condition tree evaluated when picking. An array means all children.
complete_cooldownarray<object>[]Resolution cooldown rules below; empty disables both restrictions.
objectivesarray<object>RequiredNon-empty objective list. Every objective must complete.
rewardsarray<object>RequiredOrdered reward list; empty grants none. Repeated entries are allowed.
client_visiblebooleantrue for misc and bounty; false otherwiseIncludes the definition and its profile state in normal client synchronisation. Does not prevent server activation.
misc_picker_weightinteger1Positive relative selection weight. Supplying this field outside misc rejects it, even when its value is 1.
misc_poolsarray<string>[default] for misc; [] otherwiseMisc-only pool membership. Empty or all-blank input becomes default; duplicates collapse. Unknown names reject.
bountyobjectRequired for bounty; absent otherwisePhysical commission metadata; see Bounty data. Rejected on other tiers.
mainstory_progressobjectUnbounded integer rangeMain-story tiers only; presence outside main-story tiers rejects.
mainstory_progress.mininteger-2147483648Inclusive lower bound on the picking player’s story progress.
mainstory_progress.maxinteger2147483647Inclusive upper bound; less than min rejects.
Tier constantAccepted JSON namesSelection behaviour
MAINSTORYmainstory, main_storyOne-time: either a previous completion or failure prevents restarting.
IMPORTANT_MAINSTORYimportant_mainstory, important_main_storySame one-time eligibility and story-progress filtering.
MISCmisc, misc_quest, misc_questsPool-based weighted selection; successful completion unlocks repetition.
BOUNTYbountyWeighted board postings; a receptionist-confirmed live contract authorizes progress, and the issuing receptionist settles it. The paper copy is optional.

Tier and pool names trim whitespace, ignore case and replace spaces/hyphens with underscores. Pool constants are DEFAULT, TOWN, COMBAT, DEBUG, ADVANCEMENT, CRAFTING, FORGERY and ALCHEMY; their JSON names are default, town, combat, debug, advancement, crafting, forgery and alchemy.

The normal pick path permits a solo player or a team’s owner. It rejects already-active quests and unmet prerequisites, then checks cooldowns and pick conditions. Main-story selection uses the first eligible definition ordered by minimum story progress, then quest ID. Misc selection uses relative weights among eligible candidates in the requested pool and optional chapter; weight does not bypass eligibility. A completed misc quest must remain unlocked for repetition.

Prerequisites, objectives and rewards

FieldTypeDefaultWhat it does
prerequisites[].questidentifierRequiredAnother quest in the same successfully loaded catalogue. Self references, duplicate references, missing targets and cycles reject reload.
prerequisites[].minimum_completionsinteger1Required successful completion count, at least 1; failure counts do not satisfy it.
objectives[].idstringRequiredNonblank, unique within the quest; also forms translation keys.
objectives[].progress_typestringRequirednumeric accumulates progress; boolean completes from a flag. Case-insensitive, trimmed, hyphens normalised.
objectives[].requiredinteger1Positive numeric target. A boolean objective requires exactly 1.
objectives[].typeidentifierRequiredRegistered objective type, such as isekaiexpansion:visit_location. Unknown type rejects reload.
objectives[].dataobjectRequiredType-specific fields, content triggers and supported failure rules. Empty is valid only when that type needs no fields.
objectives[].conditionsobject / array<object>Always trueObjective-event filter tree. Uses a different set of leaf types from conditions.pick.
rewards[].typeidentifierRequiredRegistered reward type; unknown type rejects reload.
rewards[].dataobjectRequiredReward-specific payload; no implicit empty object.
data.progress_per_tickinteger1For visit_location: positive progress per qualifying player tick. Boolean progress still completes on its first qualifying event.

Objective payloads and event filters are documented in Quest objectives. Reward payloads and recipient selection are in Quest rewards.

Pick conditions

Condition objects use type and data. Arrays at any condition-node position are shorthand for isekaiexpansion:all. The following table describes general conditions used by picking and objective content triggers; it does not describe objective event-filter leaves.

FieldTypeDefaultWhat it does
typeidentifierRequiredRegistered general condition type. All built-ins below use isekaiexpansion.
dataobjectRequiredCondition payload. Unknown payload keys do not add checks.
data.childrenarray<object>[]Recursive children for all, any and not; children may themselves be shorthand arrays.
data.mininteger-2147483648Inclusive lower bound for range conditions below.
data.maxinteger2147483647Inclusive upper bound; max below min rejects.
data.valuebooleantrueExpected team membership for has_team.
data.target_rankstringRequired in practicePromotion target; missing becomes an empty string and then rejects as unknown.
data.crossed_onlybooleanfalseobjective_progress additionally requires progress to cross into the range on this event.
TypeMeaning
isekaiexpansion:allEvery child must pass; stops at the first failure. Empty passes.
isekaiexpansion:anyAny child may pass; stops at the first success. Empty fails.
isekaiexpansion:notNegates exactly 1 child; any other child count rejects.
isekaiexpansion:player_levelPicking/event player’s Isekai Core level is within min–max. Missing player fails.
isekaiexpansion:player_rankPlayer’s numeric adventurer rank is within min–max. Missing player fails.
isekaiexpansion:adventurer_rank_promotion_readyIsekai Core reports readiness for target_rank; does not promote.
isekaiexpansion:has_teamReal team membership equals value; a solo profile is not a team.
isekaiexpansion:team_member_countCount of online players in the same quest profile is within min–max.
isekaiexpansion:team_average_levelFloor of the online profile members’ mean Isekai Core level is within min–max.
isekaiexpansion:team_average_rankFloor of their mean numeric adventurer rank is within min–max.
isekaiexpansion:objective_progressCurrent objective progress is within min–max. A pick has no current objective, so this leaf always fails there.
isekaiexpansion:sequenceStateful content-trigger condition; rejected anywhere inside conditions.pick, including nested groups. See Quest objectives.

Online-member checks do not count offline teammates and do not require the same dimension. If no matching online member is found and there is an acting player, that player is the fallback member.

For objective_progress, boolean false/true becomes 0/1. Numeric crossed_only requires previous progress below min and new progress within the inclusive range; jumping beyond max fails. Boolean crossing requires false → true, as well as the range check. Ordinary pick conditions should use player/team leaves, not objective progress.

Isekai Core owns adventurer ranks. Checked against its local source checkout for the consumed 0.4.0-build60: accepted promotion targets are copper, silver, gold, diamond, mythril, adamantite, stormyx and celestium, case-insensitive and trimmed. none is rejected here. Readiness requires the next rank and, beyond the initial rank, the dependency’s reputation requirement; already holding the target does not pass readiness. This is a source-checkout verification, not a claim of binary equivalence.

Resolution cooldowns

FieldTypeDefaultWhat it does
complete_cooldown[].typestringRequiredALL or THIS, trimmed and case-insensitive. At most one entry of each type.
complete_cooldown[].dataobjectRequiredCooldown payload.
complete_cooldown[].data.valueintegerRequiredNon-negative game-time ticks; 0 disables this rule. For example, 1200 ticks is 60 seconds at 20 ticks per second.

Despite the field name, both completion and failure start the resolution clock. THIS uses this quest’s most recent resolution. ALL uses the latest resolution, in this profile, among currently loaded quests that have a positive ALL rule. It does not use every quest indiscriminately.

Each candidate applies its own authored duration to the relevant clock. Both rules must expire before selection succeeds; negative elapsed time is treated as 0, and no previous resolution means no cooldown. Time is world game time, not real-world time spent with the server stopped.

Translation keys

TextTranslation key pattern
Quest titlequest.<namespace>.<quest-path>.title
Quest descriptionquest.<namespace>.<quest-path>.desc
Objective titlequest.<namespace>.<quest-path>.objective.<objective-id>.title
Objective descriptionquest.<namespace>.<quest-path>.objective.<objective-id>.desc
Chapter titlequest_chapter.<namespace>.<chapter-path>.title
Chapter descriptionquest_chapter.<namespace>.<chapter-path>.desc

Paths replace slashes with dots. Objective IDs replace both slashes and colons with dots. Choose IDs whose normalised forms remain distinct; unique raw IDs alone do not guarantee unique translation keys.

Validation

InputResult
Missing tier, prerequisites, objectives or rewardsRejects the definition and keeps the previous quest catalogue
Empty root object or empty objectivesRejected
Empty prerequisites or rewardsAccepted
Unknown root keyIgnored; no additional behaviour
Unknown objective, reward or condition typeRejected
Invalid identifier syntax or incompatible field typeRejected during parsing
Unregistered chapterAccepted as a grouping ID; translations are separate
Missing prerequisite target, self reference, duplicate prerequisite or cycleRejected
Duplicate quest ID across surviving resourcesRejected
Duplicate objective ID within a questRejected
Invalid field range, wrong tier-specific field, duplicate cooldown type or pick sequenceRejected
Other referenced game resourcesValidated by each objective/reward parser or at execution; successful quest parsing alone does not prove they exist

Malformed JSON text can be discarded by the underlying resource-reading stage before quest validation. The atomic guarantee applies to the definitions delivered to the quest parser; it is not a promise that every unreadable resource preserves an earlier entry.

Reloading

Server data reload rebuilds the catalogue and increments its revision only after definition and prerequisite-graph validation succeeds. A successful empty catalogue replaces the old one. Saved quest profiles are separate from these definitions; changing IDs is not a save-data migration.

Full client synchronisation sends visible definitions and the corresponding filtered profile. Clients still need translation assets locally. The Quest runtime page describes sync triggers, active-state reconciliation and diagnostics.

  • Quest objectives — objective types, event filters, delivery, content actions and failures.
  • Quest rewards — reward fields, recipients and failure handling.
  • Quest runtime — state ownership, persistence and integration.