Repository navigation
Help Articles
TL;DR: Help articles live in several XML homes, each with its own article class. Every article has a global numeric id, per-language keywords and text, and optionally one category label. Write the body as one line per paragraph, link meaningful things by id, and never change or reuse an id. Use when: you write, edit, move or review a help article, give a skill or command a help text, or pick a help id. Source of truth:
src/core/helpmanager.{h,cpp}(HelpArticle,registrate,getCategory),plug-ins/help/(helpformatter.cpp,areahelp.cpp,helprelated.cpp,helpmeta.cpp),plug-ins/comm/help.cpp,plug-ins/comm/helpcategory.cpp,dreamland_world/helps/*.xml. Verified: 2026-11-02 against dreamland_code 88da8302, dreamland_world 43880467
| Home | Article classes | Edit it for |
|---|---|---|
dreamland_world/helps/*.xml |
Help (standalone) |
game concepts, lore, clans, religions overview, quests, immortal docs. Files: help, anatolia, clan, group, quest, religion, immort. |
Skill, spell and craft XML in dreamland_world (generic-skills, clan-skills, other-skills, card-skills, craft-skills, race-aptitudes) |
SkillHelp |
one skill or spell |
dreamland_world/commands/*.xml |
CommandHelp |
one command |
dreamland_world/socials/, races/, religions/, professions/, skill-groups/, craft-professions/, behaviors/, languages/, notes/
|
SocialHelp, RaceHelp, ReligionHelp, ProfessionHelp and ClassSkillHelp, SkillGroupHelp, CraftProfessionHelp, BehaviorHelp, LanguageHelp, NoteHelp
|
the thing the file defines |
The <helps> section of an area file |
AreaHelp |
the zone article (lore) and other area-local articles |
An embedded article sits inside the file of the thing it describes, so its keywords and title are composed from that thing's names. A standalone article carries its own.
Counts in the world repository on 2026-11-02: 551 SkillHelp, 245 SocialHelp, 240 CommandHelp, 151 Help, 85 BehaviorHelp, 75 RaceHelp, 44 ReligionHelp, 23 SkillGroupHelp, 13 ProfessionHelp, 13 ClassSkillHelp.
Reload: help changes in the world repository load with a plugin reload (plug reload most). The selective plug reload changed follows plugin binaries and does not notice an XML-only edit. Area XML is read at boot, so zone helps appear after a restart. See Data-Configs.
<?xml version="1.0" encoding="UTF-8"?>
<Help type="HelpContainer">
<node id="1" seealso="1375" level="-1" type="Help" labels="gods hub">
<extra l="en">adepts atheism gods marks</extra>
<extra l="ru">адепты атеизм боги знаки</extra>
<extra l="ua">адепти атеїзм боги знаки</extra>
<keyword l="en">cults religions</keyword>
<keyword l="ru">культы религии религия</keyword>
<keyword l="ua">культи релігії релігія</keyword>
<text l="en">...</text>
<text l="ru">...</text>
<text l="ua">...</text>
</node>
</Help>A skill, command or race article is leaner and sits inside the owner:
<help id="676" seealso="700" level="-1" type="SkillHelp">
<text l="en">%FMT% *%CMD%* _%VICT%_
Warrior classes ...</text>
<text l="ru">...</text>
<text l="ua">...</text>
</help>| Part | Meaning |
|---|---|
id |
Global number. {hh<id> links to it. See Help ids. |
type |
The article class, decides the title and the keywords composed by the engine. |
level |
Smallest trust that can see it. -1 is everybody. Higher levels hide the article from players. |
labels |
Category. See Categories. Most articles need none. |
seealso |
Up to four hand-picked ids for the "See also" line. |
ref |
The commands a command article covers. |
refby |
A number makes the article an alias of that article: a lookup opens the target. |
keyword l |
The title terms and primary lookup words, one element per language. |
extra l |
Hidden synonyms for lookup. |
title l |
Optional. Overrides the composed title. |
text l |
The body, one element per language. |
Multi-word keywords use single quotes: 'new thalos'.
-
help <words>matches the keywords of every language and ranks fuzzy matches. A numeric argument opens the article with that id. - A leading facet word limits the search:
skill,spell,class,race,command,area,religion,clan. -
help indexlists the categories andhelp index <category>lists the articles of one. - Labels are categories, not names.
help <label>does not open anything.
An article belongs to at most one topical category. It is the first token of labels, optionally followed by facets.
Player categories, in display order: start, char, combat, skills, magic, classes, races, gods, items, quests, world, society, comm, socials.
| Key | English | Contents |
|---|---|---|
start |
Getting started | the ordered newbie reading path |
char |
Your character | stats, alignment, ethos, death, experience, remort, followers |
combat |
Combat | damage, accuracy, lag, fleeing, PK |
skills |
Skills and learning | skills, skill groups, practice, languages |
magic |
Spells and magic | spells and how to cast |
classes |
Classes | professions, per-class skill lists |
races |
Races | playable races and aptitudes |
gods |
Gods and religions | religions, cults, the Eight Paths |
items |
Items and economy | equipment, containers, shops, crafts, behaviors |
quests |
Quests | quests, questors, global quests |
world |
World and travel | zones, atlas, movement, non-player races |
society |
Players and clans | clans, groups, laws |
comm |
Communication and settings | channels, configs |
socials |
Socials | emotes |
Non-player keys exist for articles that stay reachable by keyword and link but never appear in an index: imm, credits, engine, deprecated. Do not change level on an engine article, the login flow reads those articles directly.
How the category is decided, in this order:
- A player key in the persistent
labelsattribute. - A non-player key there.
- The labels the engine assigns itself when it loads the article:
spellgivesmagic,socialgivessocials,mobrace(a non-player race) givesworld,raceorraceaptitudegivesraces,religiongivesgods,classgivesclasses,skillgroupgivesskills,craft,craftskilloritemgivesitems,clanskill,cardskill,languageorskillgivesskills,areagivesworld,clangivessociety. The order matters: a spell also carriesskill, sospellis tested first. - A label ending in
-skillsgivesclasses.
So embedded articles need no label. Only standalone concept and command articles are labelled by hand. Engine labels (spell, cmd, race) cannot be removed by editing XML and should not be written there. Two facet tokens are written by hand after the category: clan (the filter help clan <word> depends on it) and hub.
The category display names are data in plug-ins/comm/helpcategory.cpp. The website and the in-game browser use the same resolver.
A hub is the front door of a category: a short orientation, then groups of links with half-line notes. It narrates, it does not list every member (the index does). Adding a skill or a zone should need no hub edit.
The article classes compose parts of the text, so do not type them:
| Class | Composed |
|---|---|
SkillHelp |
the title and the stats header (level, mana, lag). Never repeat these numbers in prose. |
CommandHelp, SocialHelp
|
title and keywords from the names. A social's own text stays empty, the engine builds the demo table. |
RaceHelp, ReligionHelp
|
title and a metadata bullet list (one fact per line) before the prose. Command articles build a similar block. |
ProfessionHelp, ClassSkillHelp
|
title only, no metadata block |
AreaHelp (the zone article) |
the title "Zone ", bullets for levels, danger, author, translator, other name and how to get there from the central square, then the prose, then the zone's visible quests |
| any article | a "See also" line with up to four related articles: your seealso ids first, then articles of the same category that link here, then rare shared keywords |
The metadata block is built from help_meta_line(label, value), which makes " * Label: value" lines. A run of these lines becomes a real list on the website, so a screen reader announces it as a list. The help pipeline never wraps. Clients wrap, the server never inserts a newline.
Titles of composed articles are the entity's own name, so fix them in the entity (<name l="ua"> of the skill, the command, the race, the area). An authored <title l> must exist in all three languages or in none. A standalone Help node with no title falls back to a block of all its keywords in capitals, so every new standalone article needs an authored trilingual title. Format: Topic: subtopic, sentence case, no trailing period, no colour codes, at most 60 characters. Command articles share a prefix word per category (for example Combat: ...), keep it consistent with the category name.
Markup is described in Text-Markup. In short:
-
*word*is a command the player can type,_word_is a placeholder,=term=marks the term the article defines (once, at first mention). -
%FMT%and%FFF%write the syntax lines,%A%a bullet,%CMD%the command name. Never typeFormat:,Syntax:orSee alsoin a body. -
{C...{xis a cyan subheader on its own line, all capitals. - Placeholders go in
_id_form. A<id>is lost for the reader and a raw<breaks the XML. - Every opened colour is closed with
{x.
Templates by class:
| Class | Skeleton |
|---|---|
| Concept | one or two sentences on what the term is and why the player cares, one to four paragraphs with links, optional {C subsections, optional %A% list, optional %FMT% block if the concept has commands |
| Command |
%FMT%/%FFF% lines, one per syntax variant (drop _arg_ when there is none), then one or two paragraphs that start with what it does, then limits and cost |
| Skill or spell |
%FMT% *%SPELL%* _%VICT%_ for spells or %FMT% *%CMD%* ... for skills, then what it does and what the strength depends on, then who can use it, then an optional one-line warning. Passive skills omit the %FMT% block |
| Race | who they are (look, character, lore, links to related races), then mechanics (aptitudes, special senses, resistances, class leanings). Take every immunity, resistance and aptitude from the race XML, never from memory |
| Religion | lore paragraph, then %A% lines for Paths, gifts, restrictions and sacrifices, optional closing lore. These %A% attribute lines keep their line breaks |
| Class | what the class is good at with links to its signature skills, obligations, then %A% pros and cons |
| Zone | only lore and optional practical notes. The engine adds the header. Two to six links to neighbouring zones, gods and clans |
| Behavior |
%FMT% with the interaction verbs, then one or two paragraphs on what the item does |
The client wraps lines. The file must not contain a line break inside a paragraph. Separate paragraphs with exactly one blank line.
Line breaks that stay, because they are structure:
- blank lines between paragraphs
- any line that starts with a
%FMT%,%FFF%,%A%,%SA%marker, even after colour codes - all-capital subheader lines
- list lines (
-,*,%A%, numbered) - table-like lines with leading indentation or columns separated by two or more spaces
- everything between
%PAUSE%and%RESUME%
Join only a prose line that does not end a sentence and whose next line starts in lower case. After joining, collapse double spaces outside aligned tables. Screen-reader users navigate by header and marker lines, a joined header is a lost landmark. When in doubt keep the break.
- Each
<text>,<keyword>,<extra>and<title>block holds one language. That includes zone names and link anchors. Only Latin technical terms may cross over. - Write for the second person singular (
ты,ти,you). - Use official names. Look them up in this order: the XML the engine reads (skill, command, race, religion, area, class files), then World-Canon. Never transliterate a name on your own or take it from another wiki.
- Rules for punctuation, alphabets, apostrophes and tone: Writing-Player-Text.
- Link on first mention: classes, races, gods, zones, clans, skills and spells, commands you tell the player to use, and concepts that have an article.
- Three to ten links per screen. More reads as spam, especially with a screen reader. A body of more than about 300 characters with no outgoing link is a defect.
- Prefer the id form
{hh<id>anchor{x. It survives keyword changes. The keyword form{hhword{xonly when the word is literally the keyword of the target in that language. - The anchor is in the language of the surrounding text, declined to fit the sentence, and matches how the target names the thing in that language. Check the target's keyword in that language first.
- Every
{hh<id>must resolve. If there is no article to link, add the term to an existing article's<extra>or create the article. - Do not link a hub for a passing mention. Every body link is an inbound edge for the automatic "See also" of the target.
- Do not write a "See also" line. Use the
seealsoattribute, and do not list an id there that the body already links.
- Standalone and zone articles: every language that has a body has a keyword element in the same language.
<extra>synonyms are recommended. - Embedded articles get their keywords from the names of the thing. Add a
<keyword l>only for real synonyms. The engine adds the names and aliases of the entity in all three languages. - Lower case, multi-word phrases in single quotes, one language per element.
Every article id is a global number shared by all homes, including area helps. The rules:
- Take the highest id in use plus one. The coder command
abc maxhelpprints it from all loaded articles, which is the only complete set (other homes and in-game edits may hold ids a repository scan cannot see). Run it again right before you merge, a parallel change may have taken the id.abc maxhelpalso prints the first gap in the numbering: only maintainers who know the gap never held an article should use it. - Never reuse the id of an article you deleted, old links and saved scripts may still point at it. Never change the id of an existing article. Links,
seealso,ref/refbyand saved scripts point at it. - A duplicate id stops the load:
HelpManager::registratelogs the clash and throwsDuplicate help ID. At boot or at a plugin reload this is a crash. - A skill that has a spell, an affect handler or a skill command takes the identity of that handler from its help id:
(help id << 4) | 5for the spell,| 6for the affect handler,| 7for the command. Scripts and saved data are bound to that number. A skill with such a handler and no help id throws "ID not found or zero" and the boot loops. - So never delete a skill's help, never move it to another file, never renumber it. Hide it with a high
level(the corpus uses 102 and above), and link to it from elsewhere if the text is needed there. - Standalone and area ids use the same number space as skill ids. A fresh id may not collide with a skill help.
A GitHub check in the world repository (scripts/lint-help-boot.py) catches duplicate ids inside the world and skills without a help. Area files are in a separate repository, so a cross-repository clash is only found when the server loads both.
- The XML is well formed.
- Other languages of the article are untouched unless the task was about them.
- The multiset of
{hh<id>per language is as intended, and every id resolves. - The
%TOKEN%multiset of a translation matches its Russian source. - No literal
Format:,Syntax:,See alsoor translations in the body. - No mixed-alphabet words, no
{followed by a Cyrillic letter, no…,«»,—,",',>. - No
вы/виin direct address, noэin Ukrainian, noё. - Exactly one topical label or none, and it is in the vocabulary.
- A new id is free and unique.
- A skill's help is still in place.
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