How in-game help works end to end: source material, import pipeline, and runtime serving.
Runtime path (what players see)
The help command (do_help, src/cmd/actinf.c:6527) does two things:
-
wiki_help()(src/cmd/wikihelp.c) - in database-backed mode, queries thepagestable on the main MySQL connection:SELECT title FROM pages WHERE title LIKE '%<term>%' ORDER BY title ASC LIMIT <N>(
WIKIHELP_RESULTS_LIMITis 100,src/cmd/wikihelp.h.) One match renders the full entry; multiple matches render the exact match plus "see also" links. User input is escaped (escape_str()wrapsmysql_real_escape_string). Misses are logged tolib/etc/help(logit(LOG_HELP, ...)), which is useful for spotting missing topics. Entries are stored wiki-formatted;dewikify()converts[[...]]markup into ANSI-colored output. Requests are rate-limited by thehelp.cooldown.secsproperty (default 2s).Two page features are applied at render time (
src/cmd/wikihelp.c,wiki_help_single()):- Redirects: a row with
category_id1 whose text starts withRedirect: <target>is followed to<target>. - Dynamic sections: rows with certain
category_ids get content appended from code/properties, not from stored text: 25 race (classes, racial stats, innates), 9 class (allowed races, innates, specs), 16 spec (races, innates, skills, spells), 10 class-skillset (innates, skills, spells). TitlesMulticlassandRacesalso get hardcoded sections. Editing those pages means authoring only the static part.
- Redirects: a row with
-
attrib_help()- appends per-command attributes (stat usage) loaded at boot fromdocs/lib/information/command_attributes.txt(src/cmd/wikihelp.c, boot loader). If the file is missing, only a debug log line notes it. Coverage is complete: every command name registered insrc/cmd/interp.chas an entry, plus legacy entries keyed by ability names that are not commands (apply poison,parry, ...) which servehelp <ability>lookups. Each entry lists theGET_C_*stats its handler (or skill-gated helper chain) actually uses; commands whose handlers consult no stats carry just the header line. The loader holds up toCMD_ATTRIB_MAXentries (1024,src/cmd/wikihelp.h) and bounds-checks the count, logging and skipping anything beyond the cap.
Without MySQL (-D__NO_MYSQL__ builds), the same command loads and caches the
tracked source files that feed the database importer. It applies the importer's
precedence - individual lib/information pages, then help_index, then
duris_help_parsed.hlp - and provides case-insensitive exact and substring
searches without a database connection. Missing or structurally invalid source
catalogs fail closed with the normal help-system error instead of silently
returning the former disabled stub.
The same client-free content path serves the existing mud_info callers for
motd, news, wizmotd, credits, FAQ, rules, and wizlist directly from their
allow-listed lib/information/ files. This keeps boot/login and information
commands functional without changing the database-backed lookup path.
Content pipeline
lib/information/* help/ database
|- motd, news, faq -+ |- duris_help.hlp +-------------+
|- help, rules, ... |-->|- duris_help_parsed.hlp ->| pages |
+- hints.txt, help_index +- (parsed inline by the | mud_info |
import script) +-------------+
scripts/import_help_to_prod.sh
scripts/import_help_to_prod.sh:
[!WARNING] Despite its name, this script can write to any database selected by
.envor to a remote host supplied with--remote. Run--dry-runfirst, verifyDB_HOST,DB_PORT, andDB_NAME, and take a database backup before a live import.--cleandeletes all rows frompagesbefore re-importing content. The script prompts for confirmation for live and clean operations.
- Maps files from
lib/information/intomud_info(motd, news, wizmotd) andpages(help, help.1/2, guild/ship/kingdom helps, faq, rules, info, credits, wizlist, hints). hints.txtnow lives atdocs/lib/information/hints.txt; the script reads it from there (the login screen streams it viasrc/account/nanny.c).- Imports the parsed help entries from
help/duris_help_parsed.hlp(~500+ topics); the help index is parsed inline by an embedded Python heredoc in the script (~1500 entries as of the immortal-command and full spell/skill coverage). - Import order matters: Section 2 (
help_index) runs before Section 3 (duris_help_parsed.hlp). Both write with DELETE-by-title + INSERT, so a title present in both files ends up owned byduris_help_parsed.hlp. Titles compare case-insensitively (MySQL default collation). Check both sources before adding an entry tohelp_index. - Title parsing in
help_index: unquoted titles are truncated at(-PURGE (Spell)stores page titlePURGE; quoted titles keep everything inside the quotes -"ECHO (IMMORTAL)"stores the full string. Use quoting whenever you need parentheses in a page title. - motd/news/wizmotd are cached into memory at boot (
src/world/db.c) and re-read only by the immortalpagecommand (level 60+,src/cmd/actcomm.c). After importing new copies, runpageor restart; otherwise players keep seeing the old text. - Content is hex-encoded into
DELETE+INSERTSQL so arbitrary text survives; supports--dry-run. lib/information/help_indexcarries one entry per immortal command (everything listed bywizhelp, levels 57-62), written against the command implementations insrc/. Bare-command titles (POOFIN (Immortal Command)-> pagePOOFIN) are exact-match discoverable; names colliding with spells/skills are quoted so the parentheses survive ("ECHO (IMMORTAL)"). Because import deletes by title, new entries must never re-use an existing bare title.
Editing help
- Authoring rules and formatting conventions:
docs/content/HELP_STYLE_GUIDE.md. The style guide is spell-oriented (stat header block); immortal command entries inhelp_indexinstead use aSyntax:line, a rank/level line, a short description, andSee also:- follow the existing entries there. - In-game topic text lives in
pages; the import script is the only write path (no in-game editor exists - nothing insrc/inserts into or updatespages). Update the source files and re-run the import script; editing the database directly would silently diverge from the flat-file sources. See the warning above before importing to a shared or remote database. - Command attribute changes go in
docs/lib/information/command_attributes.txtand require a server restart (loaded once at boot).
Related
- Login hints:
docs/lib/information/hints.txtread bynanny.c. - Wiki export helpers and formatting utilities live alongside the loader in
wikihelp.c.