Skip to content

Help Articles

Kit Oliynyk edited this page Nov 14, 2026 · 4 revisions

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

Where articles live

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.

Anatomy of an article

<?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'.

Finding an article in game

  • 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 index lists the categories and help index <category> lists the articles of one.
  • Labels are categories, not names. help <label> does not open anything.

Categories

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:

  1. A player key in the persistent labels attribute.
  2. A non-player key there.
  3. The labels the engine assigns itself when it loads the article: spell gives magic, social gives socials, mobrace (a non-player race) gives world, race or raceaptitude gives races, religion gives gods, class gives classes, skillgroup gives skills, craft, craftskill or item gives items, clanskill, cardskill, language or skill gives skills, area gives world, clan gives society. The order matters: a spell also carries skill, so spell is tested first.
  4. A label ending in -skills gives classes.

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.

What the engine writes for you

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.

Writing the body

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 type Format:, Syntax: or See also in a body.
  • {C...{x is 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

One line per paragraph

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.

Language

  • 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.

Linking

  • 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{x only 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 seealso attribute, and do not list an id there that the body already links.

Keywords

  • 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.

Help ids

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 maxhelp prints 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 maxhelp also 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/refby and saved scripts point at it.
  • A duplicate id stops the load: HelpManager::registrate logs the clash and throws Duplicate 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) | 5 for the spell, | 6 for the affect handler, | 7 for 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.

Pre-merge checklist

  1. The XML is well formed.
  2. Other languages of the article are untouched unless the task was about them.
  3. The multiset of {hh<id> per language is as intended, and every id resolves.
  4. The %TOKEN% multiset of a translation matches its Russian source.
  5. No literal Format:, Syntax:, See also or translations in the body.
  6. No mixed-alphabet words, no { followed by a Cyrillic letter, no …, «», —, &quot;, &apos;, &gt;.
  7. No вы/ви in direct address, no э in Ukrainian, no ё.
  8. Exactly one topical label or none, and it is in the vocabulary.
  9. A new id is free and unique.
  10. A skill's help is still in place.

See also

Clone this wiki locally