Command table
MadROM dispatches every player command through the global cmd_table
defined in src/interp.c
. Each entry uses the struct cmd_type
layout declared in src/interp.h
so that the interpreter can discover the handler function, the positions and trust levels that may execute it, and whether immortals should see it in command listings.
Entry layout
The fields of struct cmd_type
describe both how a command is invoked and how it is presented:
Field | Declared in | Purpose |
---|---|---|
name |
src/interp.h |
Text players type at the prompt. Abbreviations work so long as they are unique. |
do_fun |
src/interp.h |
Function pointer to the implementation, usually defined in one of the act_*.c files. |
position |
src/interp.h |
Minimum character position (for example POS_DEAD , POS_STANDING ) required before the interpreter will call the handler. |
level |
src/interp.h |
Minimum level or trust that may use the command. |
wizbit[WIZ_BITS] |
src/interp.h |
Optional wizard flag requirements. The stock table leaves these as zero but they can gate commands behind custom wiznet-style permissions. |
log |
src/interp.c |
Controls logging with the LOG_NORMAL , LOG_ALWAYS , and LOG_NEVER constants. Entries flagged LOG_ALWAYS are written to the immortal log even without fLogAll . |
show |
src/interp.c |
When set to FALSE the command is hidden from the commands listing, though it still works when typed directly. |
Because the interpreter checks commands in the order they appear in cmd_table
, related entries are commonly grouped together in the source file.
Adding a command
To wire a new command into the game:
- Declare the handler – Add a
DECLARE_DO_FUN(do_yourcommand);
prototype tosrc/interp.h
so the table can reference it. - Register the entry – Insert a row into
cmd_table
insrc/interp.c
with the command name, handler, required position, level, wizard bits, logging mode, and visibility flag. - Implement the behavior – Provide the
do_yourcommand
function in an appropriate source file (often one of theact_*.c
modules). Make sure it follows the standard signature so the interpreter can invoke it.
Immortal commands should set the level
field to the appropriate trust threshold and toggle log
or show
to control auditing and visibility. Mortals-only commands typically leave wizbit
at zero.
Social commands
Emotes and socials bypass the command table and instead use the social_table
array that load_socials
populates in src/db2.c
. Each entry is a struct social_type
with fields such as name
, char_no_arg
, others_no_arg
, char_found
, others_found
, vict_found
, and optional self-targeted strings. To add a social, append the new definition to the socials data file read by load_socials
; the loader handles $
sentinels for empty strings and #
markers that terminate each definition.
Logging and snooping
When the interpreter dispatches a command it calls the handler after running the logging and snoop hooks in src/interp.c
. Commands that set log
to LOG_ALWAYS
, characters flagged with PLR_LOG
, or a server with fLogAll
enabled generate entries in the immortal log and on the secure wiznet channel. The snoop system also echoes the final command line to any administrators snooping the player before the handler executes.