Repository navigation
Data Configs
TL;DR: Game data lives in
dreamland_world, mounted at the runtime table directory. One folder per kind of data. XML folders are read by table loaders, JSON files byConfigurableplugins. Both are read when their plugin starts, soplugin reload mostapplies a change. Areas are the exception and load at boot only. Use when: you tune a number, add a skill, race, religion or command, need to know which code reads a file, or wonder why an edit did not show up. Source of truth:plug-ins/system/configurable.h,plug-ins/system/xmltableloaderplugin.h(TABLE_LOADER),src/dreamland.h(main config fields),src/plugin/pluginmanager.cpp,dreamland_world/. Verified: 2026-11-02 against dreamland_code 88da8302, dreamland_world 43880467, dreamland_fenia_public c28874b
| Mechanism | What it reads | When |
|---|---|---|
| Main config |
etc/dreamland.xml, the DreamLand object (src/dreamland.h) |
boot. The server rewrites it with the new worldTime every tick |
Table loader (TABLE_LOADER(Class, "folder", "Node")) |
every .xml in dreamland_world/<folder>, one object per file |
when the owning plugin loads |
Configurable (CONFIGURABLE_LOADED(folder, name)) |
dreamland_world/<folder>/<name>.json |
when the owning plugin loads |
| Area list |
area.lst.xml in areaDir, then each area file |
boot only |
| Fenia scripts | the script directories named in the main config | hot reload with cs commands, see Fenia-Scripts
|
Rules:
- A table loader or configurable runs in the plugin's
initialization. To apply an edit, reload that plugin by name or useplugin reload most.plugin reload changedcompares the mtime of the plugin.so, so an XML-only edit never marks anything changed. Usemost. -
plugin reload allalso unloads the[descriptor]plugin and drops every connection.mostkeeps it. Do neither with players online if you can avoid it. - A configurable file is parsed from UTF-8 and converted to the internal KOI8 encoding. A broken JSON file keeps the old value and logs an error. A missing file, or a file that did not parse, leaves C++ on its compiled defaults.
-
.config("folder/name")in Fenia returns the loaded JSON. Objects become Maps and arrays become array containers. A JSON float such as0.5reads as0and a boolean reads as1or0(measured live 2026-09-24), so a tunable shared by C++ and Fenia must be an integer (percent, centi-M). On a config array,for (v in arr)and a bare variable index throw, writearr[i + 0]instead..config()copies the whole file on every call, so read once and keep the result. - A new JSON file needs a
CONFIGURABLE_DECLin a plugin that has the JSON headers, otherwise.config()cannot see it. Thefightplugin works, theaiplugin does not compile that way. - Never hand-edit a file the server writes (see the table below). The server rewrites it, and an edit made while it runs is lost.
- In-game editors (
hedit,skedit,cmdedit,socedit,raceedit,reledit,fedit,greditand others) rewrite the XML of their table on the running server. A checkout on a running server can therefore differ from git until it is synced back.
| Folder | Holds | Loader (plugin) | Notes |
|---|---|---|---|
behaviors |
behavior definitions, one XML per behavior, plus services.json
|
feniaroot (BehaviorLoader) |
each carries its help article. services.json lists the services mobs sell |
bonuses |
daily and event bonuses (experience, learning, black friday) | bonus |
|
card-skills |
skills of the card deck | skills_loader |
|
clans |
clan definitions | clan |
|
clan-skills |
clan skills | skills_loader |
|
commands |
command definitions: name, aliases in three languages, flags, order flags, help |
command (CommandPluginLoader), commands/fenia by feniaroot
|
channels.xml holds the channel wording |
config |
JSON settings, weather XML and translations/ catalogs |
see the JSON table | |
craft-professions |
crafting professions | craft |
|
craft-skills |
craft skills | skills_loader |
|
craft-wearlocs |
tattoo wear locations | craft |
|
descriptions |
per-race, per-profession character descriptions for creation |
iomanager (nannyhandler.cpp) |
JSON, registered under descriptions/<race>
|
desires |
hunger, thirst, drunkenness, bloodlust | desire |
|
fenia.examples |
one sample script per Fenia entity kind | none | documentation only |
fenia.local |
legacy .f++ scripts for a local server |
none by name, see Local-Setup | KOI8-R text |
fight |
combat and item JSON |
fight_core, fight, loadsave, race
|
the biggest folder, listed below |
generic-skills |
class skills and spells, one XML each, with the help article inside | skills_loader |
the skill help id is the handler id, never delete or move it |
gquests |
global quest definitions | gquest |
the server writes these files |
grammar |
declension rules and argument synonyms | system |
|
helps |
standalone help articles | help |
abc maxhelp gives the next free id |
hometowns |
hometowns: altar, recall, pit, limits | hometown |
|
languages |
in-game languages | languages |
|
legacy-behaviors |
old-style mob behavior definitions |
loadsave (mobilebehaviormanager) |
|
liquids |
liquids | liquid |
|
notes |
note boards | note |
the server writes these files |
other-skills |
affect-only skills, set bonuses, tattoo gifts, breath attacks | skills_loader |
|
ports |
one XML per listening socket | iomanager |
see below |
prio |
command lookup priority, one JSON per language | command |
decides which command a prefix resolves to |
professions |
the thirteen professions | profession |
|
quests |
quest type definitions for the questor | quest |
|
race-aptitudes |
racial skills | skills_loader |
|
races |
races and mob races | race |
|
religions |
gods | religion |
|
scripts |
lint scripts for world data | none | run by hand |
skill-groups |
skill groups with their cast flavour lines | skills_impl |
|
socials |
socials, one XML each | social |
|
spell |
spell JSON | skills_impl |
|
wearlocations |
wear locations | wearlocation |
|
areas.local |
demo areas for a local server |
areas through areaDir
|
not live data |
Top-level files: badnames.xml (names refused at creation), bugtracker.xml and spellpriority.xml (a KOI8-R file, the priority order of spells, read by SpellManager).
Encoding: XML files declare their own encoding. Nearly all are UTF-8. bugtracker.xml, spellpriority.xml and one note board are still KOI8-R. Keep the declaration when you edit.
ports/<number>.xml has port, listen, local (only localhost), backdoor (one-line login protocol, no character creation prompts), websock (WebSocket framing), wrapped, allowedIP. The shipped files:
| Port | Role |
|---|---|
| 9000 | telnet, character creation |
| 1234 | WebSocket for the web client |
| 1236 | WebSocket with the old character creation flow |
| 9001 | backdoor, open to the network |
| 9127 | backdoor, localhost only |
apiPort in the main config is the HTTP API port and is not in ports.
etc/dreamland.xml, loaded into DreamLand (src/dreamland.h):
| Field | Meaning |
|---|---|
pulsePerSecond, pulseViolence, pulseMobile, pulseTick
|
timing, see Engine-Time-and-Pulses |
options |
server flags: pk, log_all, log_imm, wizlock, newlock, save_objs, save_mobs, shutdown, buildplot, log_comm
|
basePath, tablePath, miscPath, libexecPath, dbPath
|
runtime directories. tablePath is where dreamland_world is mounted |
areaDir, areaListFile, savedDir
|
area files, the list of areas to load, saved rooms and mobs |
playerDir, playerDeleteDir, playerRemortDir, playerBackupDir, tempFile
|
player files and their backups |
feniaDbDir, feniaScriptDir, feniaPublicScriptDir
|
Fenia database and script directories |
immLogFile, logPattern, shutdownFile
|
logs and the shutdown marker |
apiPort |
HTTP API, 0 turns it off |
bootVersion, worldTime, merchantBank
|
counters the server maintains |
buildplot marks a builder server: it turns off hunger and thirst updates and mob aggression against players.
One row per file. "Read by" names the C++ source (under plug-ins/) that declares the file. Fenia scripts may read more files through .config().
| File | Read by | Controls |
|---|---|---|
to_hit.json |
loadsave/tohit.cpp |
hit chance, armor damage reduction, model switch, see Mechanics-Combat |
saves.json |
fight/magic.cpp |
saving throw model and dispel chance, model 0 is the legacy roll |
str_app.json, int_app.json, wis_app.json, dex_app.json
|
loadsave/stats_apply.cpp |
per-stat bonus rows indexed by stat value: hit, carry, wield, damage, learn, practice, spell level bonus, missile hit and damage, defensive AC |
damage_nouns.json, damage_verbs.json, attack_nouns.json, skill_dammsg.json
|
fight_core/damage_impl.cpp, damage.cpp, attacks.cpp
|
words used in damage messages, per language |
material.json |
fight_core/material.cpp |
materials: price per kg, density, hardness, burns (ignition ease and burn duration, 0 never burns, -1 puts fire out), floats, vuln immunity bit, names. Wool at 4 to 5 is deliberate |
item_value.json, item_affixes.json, item_weight.json, pc_baseline.json, spell_value.json, spell_combat_value.json, magic_items.json
|
fight_core/* |
the item power ruler, see Item-Power |
weapon_tiers.json, weapon_damroll_tiers.json, weapon_ave_tiers.json, weapon_ave_penalty.json, weapon_level_penalty.json, weapon_value2.json
|
fight_core/weapontier.cpp, weaponcalculator.cpp
|
weapon tiers, base hitroll and damroll, average damage per tier and level, per-class multipliers, level penalty and dice. Rows are indexed by the weapon_class table order |
weapon_classes.json, weapon_names.json
|
fight_core/weapongenerator.cpp |
weapon classes and generated names |
weapon_affixes.json |
fight_core/weaponaffixes.cpp |
weapon flag affixes with prices, tier, alignment window and adjectives |
weapon_defense.json |
fight_core/weapons.cpp |
defence factors per weapon class in percent |
armor_profiles.json, armor_names.json
|
fight_core/armorgenerator.cpp |
armor families and names |
mob_tiers.json |
race/mobbodyconfig.cpp |
mob tiers: how hit points, damage, armor, experience and variance derive from level, race and form. Tier 10 is the training dummy |
mob_forms.json |
race/mobbodyconfig.cpp |
mob forms and parts, their groups, renames and effects |
loot.json |
fight/fight_death.cpp |
corpse looting: share lost by a wanted player, items allowed per corpse for others, which loot kinds can be taken |
combat_ai.json, boss_mods.json
|
declared in fight/fight_death.cpp
|
profiles and boss moves for the scripted combat AI |
weapon_names.json and weapon_classes.json must have the same set of weapon class keys. If one has a key the other lacks, name generation returns early, the name config stays at its default and the next short-description build throws, which crashes the server on every area reset.
| File | Read by | Controls |
|---|---|---|
config/update.json |
updates/update.cpp |
autoquit: minutes idle before a player is quit, -1 off. lostlink: minutes before a link-dead player is quit, 0 means at once |
config/areaquest.json |
quest/core/areaquestcleanupplugin.cpp |
lifetime: days before an untouched area quest is cancelled |
config/affectpanel.json |
web/impl.cpp |
the columns and short labels of the web affects panel |
config/flagmessages.json |
system/morphology.cpp |
per-language names of flag table entries |
config/mssp.json |
iomanager/mssp.cpp |
MSSP server status fields |
config/settings.json |
comm/configweb.cpp |
pages, wording and limits of the web settings dialog |
config/achievements_public.json |
comm/help.cpp |
public achievement list |
config/weather.xml |
updates/weather.cpp |
weather and sunrise lines per season, three languages |
config/translations/*.json |
system/translations.cpp |
translation catalogs, see L10n |
spell/damage_tiers.json |
skills_impl/feniaskillaction.cpp |
spell damage dice per tier at level 1 and level 110 |
spell/handless_flavour.json |
skills_impl/defaultspell.cpp |
cast lines for casters without hands |
grammar/rules.json |
system/morphology.cpp |
Russian and Ukrainian ending rules for declension |
grammar/synonyms.json |
system/arg_utils.cpp |
argument synonyms: all, yes, no, in, on, from, to, by |
prio/commands_<lang>.json |
command/commandmanager.cpp |
command order for prefix matching, one list per language |
behaviors/services.json |
feniaroot/behaviorloader.cpp |
services sold by mobs: names, prices, spell, target |
Do not hand-edit while a server runs: config main file values (worldTime), gquests/*.xml, notes/*.xml, bugtracker.xml, and anything an in-game editor owns.
- New value in an existing file: add the key, read it with a default in C++ (
item_value("measure", "key", default)style) and tolerate absence. In Fenia, check for null. - New JSON file: declare it with
CONFIGURABLE_DECL(folder, name)orCONFIGURABLE_LOADED(folder, name)in a plugin with JSON headers. Rebuild. The file name and folder become the.config()path. - New XML table: add a
TABLE_LOADER(Class, "folder", "Node")and register the class. See Engine-Architecture. - After editing,
plugin reload mostfor a running dev server, then check the log forConfigurable <path> loaded with N entries.
Start here
Get running
Contribute
- Contribute
- Contributing Workflow
- Code Style
- Accessibility
- Writing Player Text
- Game Design Principles
Build areas
- Building
- OLC
- OLC Rooms
- OLC Mobiles
- OLC Objects
- OLC Resets
- OLC Line Editor
- OLC Other Editors
- Area Format
- Area Quests
- Mob Forms and Parts
Fenia
- Fenia
- Fenia Language
- Fenia Triggers
- Fenia Gotchas
- Fenia API
- Fenia Scripts
- Fenia Behaviors
- Fenia Skills and Spells
- Fenia Cookbook
- Fenia Grammar
Engine
- Engine Architecture
- Engine Time and Pulses
- Output Format
- Mechanics Combat
- Mechanics World
- Data Configs
- Item Power
Localization
Clients
More