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) does two things:
-
wiki_help()(src/cmd/wikihelp.c) - in database-backed mode, searches an in-memory catalog of thepagestable (help_cache_get()). A background worker loads the catalog after boot and refreshes it every 60 seconds; the command itself never queries the database, and until the first catalog is published it answers that help is temporarily unavailable. Operation, limits and the staff refresh command are in help-cache.md.Titles match case-insensitively by substring, with
%and_wildcards (WIKIHELP_RESULTS_LIMITis 100,src/cmd/wikihelp.h). One match renders the full entry; multiple matches render the exact match plus "see also" links. 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. There is no browsing cooldown.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. The maintained importer writes category0for help-index and parsed-help entries, so those imported class/spec pages must include their complete lists. Do not assume they receive the category-driven additions. A database page explicitly assigned one of the categories above does receive those additions; its authored text should not duplicate them.
- 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. Every command name registered insrc/cmd/interp.chas an entry, plus 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.
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/{motd,news,faq,...} ------> mud_info / pages
lib/information/help_index -------------> pages (category 0)
help/duris_help_parsed.hlp --------------> pages (category 0; wins duplicate titles)
docs/lib/information/hints.txt ---------> pages
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.--localmeans a direct connection using.env, not a development database. 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.
- By default, maps files from
lib/information/intomud_info(motd, news, wizmotd, credits, faq, wizlist) andpages(help, help.1/2, ship/kingdom helps, chaos pouch help, faq, rules, 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 entries from
help/duris_help_parsed.hlpand parseslib/information/help_indexinline. Use--dry-runfor current topic counts and collisions. - 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/wizmotd are cached at boot and re-read by the immortal
pagecommand (level 60+,src/cmd/actcomm.c). Database news also publishes on the existing one-minute mud-info refresh; flat-file news uses boot andpage. Its content fingerprint drives the per-character(news)prompt marker, cleared by opening the news with paging enabled. Imported help pages reach players at the next automatic refresh, or at once withpage help; credits, FAQ and wizlist withpage info(information-cache.md). - 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.
Publishing news only
Use --news-only for a news update:
./scripts/import_help_to_prod.sh --news-only --dry-run
./scripts/import_help_to_prod.sh --news-only
This imports only lib/information/news into mud_info.name = 'news', preserving
the file's bytes, colors, and line breaks. Other information rows and all help
pages stay unchanged. The source must exist and contain at least one byte;
--news-only --clean is rejected. A live import requires an existing InnoDB
mud_info table and publishes in one transaction, so an SQL error leaves the old
news intact. It does not require a pages table. Connection options and live
confirmation work as for the bulk import, with the selected database displayed
before confirmation.
Dry-run lists the file and byte count without connecting to the database; it
does not compare against existing database text or create a backup. Review the
source and back up the destination before publishing. Without --news-only,
even an import without --clean overwrites matching information and help content.
After publishing, database-backed news refreshes on the next successful one-minute
mud-info read. Plain page (no arguments) requests an immediate refresh. Flat-file
news reloads on plain page or restart. page help refreshes only help pages.
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. - Keep the rules in
lib/information/rules. TheLAWS RULESentry inhelp_indexpoints there viahelp rules; do not add a duplicateRulesentry toduris_help_parsed.hlp, which would override this source. - Command attribute changes go in
docs/lib/information/command_attributes.txtand require a server restart (loaded once at boot). - The channels overview,
COMMUNICATIONS UTILITIES CHANNELSinhelp_index(help channels), lists every way players talk and says what is logged. That is the rule of ADR 0003; change the entry with the rule, and add a new channel to it. The overview,NCHATandSHOUTare owned byhelp_index; do not add competing parsed-help copies.
Related
- PC class rules and source ownership: CLASSES.md.
- Login hints:
docs/lib/information/hints.txtread bynanny.c. - Wiki export helpers and formatting utilities live alongside the loader in
wikihelp.c.