Skip to content

Message of the day

Edit <root>/data/motd.toml to show a private message whenever a character enters the world. The repository ships an example at moongate_root/data/motd.toml. Restart the game server to apply changes.

lines = [
"Welcome ${player_name} to ${server_name} (${codename} ${version})!",
"Realm: ${realm_name} — players online: ${users_online}",
]

By default, the client opens its native Updates scroll after the enter-world sequence, with the rendered lines in file order. This happens on each login, including the first entry of a new character. Other players cannot see it, and no item is added to the backpack.

Choose the display mode in <root>/config/moongate.toml:

[ultima]
show_motd_gump = true

true is the default, including when the key is absent. Set it to false to keep one private Unicode system message per nonblank line in the journal. Restart the game server after changing the flag.

The native scroll supports Windows-1252 text, including Italian accents and punctuation such as — and €. If the complete rendered message uses other characters or exceeds 65,525 bytes, the server sends all valid lines to the Unicode journal instead and logs a warning. Text is never silently replaced or truncated. An empty MOTD opens no window.

Variable names are English snake_case and use the ${name} syntax.

Variable Value
${version} Server version, without build metadata
${codename} Server release codename
${server_name} shard.shard_name from config/moongate.toml
${realm_name} Client-facing name of the current game realm
${player_name} Name of the character entering the world
${users_online} Connected characters in the world on this game process, including the entrant

users_online does not count login-only sessions, disconnected sessions, characters not yet in the world, or players on another game process.

The game role loads and validates the file at startup. A missing file logs one warning and sends no MOTD. Malformed TOML, a missing lines array, invalid variable names, unknown variables, an entry that is not a string, an entry with a NUL character, and an entry that cannot fit a Unicode speech line stop startup; errors include the file path and the line index when applicable. Empty or whitespace-only entries are skipped. Text outside a complete ${...} token is literal.

A plugin resolver that fails, or a line that grows beyond a Unicode speech packet once its variables are replaced, skips that line and logs a warning without recording the rendered text. Later lines are still sent. If the character’s original session closes or is replaced, delivery stops.

A C# plugin can register variables in IMoongatePlugin.Register. Declare a dependency on com.github.moongate-community.moongate.plugins.ultima so the Ultima plugin has registered the variable registry first. Reference Moongate.Server.Ultima and import Moongate.Server.Ultima.Extensions.

container.RegisterMotdVariable(
"season_name",
(context, cancellationToken) => ValueTask.FromResult("Summer")
);

Then use ${season_name} in motd.toml. Names must match [a-z][a-z0-9_]*; duplicate names, including built-in names, fail plugin registration. Registration closes before file validation, so variables cannot be added at runtime. Resolver output is inserted as literal text and is never expanded again.

Made with ❤️ by Tom

Buy me a coffee