Changelog
Bug Fixes
Section titled “Bug Fixes”- hosting: ship the complete README example in the package (dfc250f)
Upgrade notes
Section titled “Upgrade notes”- There are no new database migrations in this release.
- New package
Moongate.Hosting: the generic host layer (startup services, event bus, plugin contracts and registry, configuration sections, game loop, timers, diagnostics, shutdown and bootstrap contracts) moved out ofMoongate.Server.Coreand depends only onMoongate.Core.Moongate.Server.Coredepends on it, so existing references keep working. Namespaces and type names are unchanged. - A plugin is built for one exact Moongate version: rebuild plugins against 0.20.0. A binary built against 0.19.0 will not load, because some types now live in the
Moongate.Hostingassembly.mgctl plugin installalso accepts a plugin that depends onMoongate.Hostinginstead ofMoongate.Server.Core. mgctl initadds the files a root lacks and never replaces one that is there. The new quest scripts (scripts/quests/), the new item and mobile templates and the updated spell, spawn and item files reach a root that already exists only if you delete the ones you did not edit and runmgctl initagain.
Features
Section titled “Features”- quests: flags and messages as quest rewards, 11 more quests (#778) (f849aa6)
- quests: escort objectives, 24 more quests (#776) (1da2e25)
- quests: deliver and timed objectives, 18 more quests (#774) (16f6561)
- quests: skill objectives and the 26 New Haven training quests (#772) (8b4be50)
- quests: the items monsters drop, 14 more quests (#770) (d60b0e4)
- quests: any-of quests and kill objectives limited to a region (#768) (fbe7fdd)
- quests: the Mondain’s Legacy monsters the quests kill, and 26 more quests (#766) (904b7cc)
- quests: the givers’ skills, teaching and shouts, and the tools they wear (#764) (fa6f296)
- quests: the givers of the migrated ML quests, their places, and the switch-on (#762) (6250867)
- quests: random-loot bag rewards for the migrated ML quests (#760) (f5e4877)
- quests: migrate the ModernUO quests, slice 1: the converter and the engine support (#758) (e1e85b4)
- quests: quests in Lua (ML model) (#756) (f6810fd)
- status: the extended status bar (0x11 version 6) (#754) (2bf89bc)
- combat: resistances and elemental damage (#753) (7dbf0e8)
- combat: weapon special moves with effects (#752) (69ea7ca)
- combat: weapon special moves, the engine and four moves (#751) (c27762b)
- chat: guild and alliance chat, and the chat button (#746) (d071a41)
- profile: read and write the character profile (0xB8) (#745) (443eefb)
- party: the spells of a place spare the party (#740) (6b4cd86)
- party: the bars of the members and their places on the map (#739) (da52d7c)
- party: invitations, the leader and the party chat (#738) (27b5f3e)
Bug Fixes
Section titled “Bug Fixes”- ctl: accept a plugin that depends on Moongate.Hosting (241d4b6)
- party: findings of the global review (#742) (ce3b16e)
Features
Section titled “Features”- network: send queue, idle timeout, limit per address and discard of overlong frames (#734) (f5867cc)
Features
Section titled “Features”- ctl: read plugin releases from Codeberg and point the docs at it (#731) (861d6c1)
- trade: drop on a player opens a trade window (357d240)
- trade: the engine of the secure trade (2446361)
- trade: the 0x6F packets of the secure trade window (bbe36ce)
- trade: a hidden layer for the box of a secure trade (98049fa)
- pets: the commands of a pet in its menu, and friends that move it (b7088f2)
- pets: rename a pet from its status bar (7490c34)
- pets: followers travel with their owner through gates, recall and teleporters (2db34de)
- pets: mobile.teleport can bring the followers of the mobile along (091935b)
- npcs: the hirelings stand in Jhelom, as ModernUO’s spawner places them (982f431)
- npcs: hirelings that work for gold, follow and fight, and leave when it is spent (2c15695)
- npcs: the ten hirelings of ModernUO as templates (cb8a087)
- pets: pet.hire and pet.hire_period for scripts, and the hire speech keywords (ad5601a)
- pets: hire a creature with no taming entry and keep it out of the loyalty drain (631ad3e)
- death: who earned a creature’s corpse loots it with no crime for two minutes (10c829b)
- combat: a landed blow is credited to its player, a pet’s to its master (825f90c)
- combat: the aggressor service keeps the damage each player dealt (c57e2f8)
- combat: the formula of the loot rights of a creature and its setting (035dc91)
- death: who fought a player loots its corpse with no new crime (244cf7b)
- world: an innocent that fought a player is grey to it (6624d44)
- combat: the aggressor lists redraw the mobiles of a fight (1484f57)
- lua: mobile.aggressors and mobile.aggressed (a66e560)
- murder: the report reads the aggressor lists (d88f789)
- combat: decide the crime rule from the aggressor lists (6aa192b)
- combat: aggressor lists service (cf0444f)
- ctl: the community repository is the default, with docs (c3ff9d3)
- ctl: plugin install by id from the releases of a GitHub repository (f623808)
- ctl: plugin install by id from a folder of packages (49989a1)
- docker: the image, the compose example and the chart run the server under mgctl run (12288c2)
- scripts: run_server.sh runs the server under mgctl run (42284cd)
- ctl: completion and help list mgctl run (4139c81)
- ctl: mgctl run keeps the server up and starts it again after a restart or a crash (3fb9676)
- server: exit with code 75 after a restart request (3e62dd4)
- commands: the restart command, in the eight languages (e177ed4)
- server: the shutdown service tells a restart from a shutdown and holds the one pending stop (a557811)
- core: the exit code a server uses to ask for a restart (aeb2a0b)
Bug Fixes
Section titled “Bug Fixes”- trade: close the review findings of secure trade (cda5c74)
- pets: refresh the health bars around a renamed creature only when it has no session (d2fd810)
- pets: friends roll and follow themselves, names survive rides and the stable (b5edc6b)
- pets: the followers that travel follow ModernUO’s rules for who goes (665827c)
- npcs: a hireling leaves no gear or gold behind and a hired mage casts (5476c7a)
- combat: credit the poison and the reflected damage, keep a dead player’s damage (b6ec4bf)
- combat: redraw only what changes colour, and never let a redraw break a pass (ed1b602)
- combat: keep the aggressor lists until the death scripts have run (f96baaa)
- ctl: the review findings of plugin install by id (d45b188)
- docker: one-shot server modes of the example skip the launcher, the grace period covers the save, the image docs say the root is prepared at every start (e692309)
- ctl: the root preparation before a start is quiet when it works and is not cut short by a stop (53dbf08)
- ctl: Dispose is the last member of the launcher (ecdd2c8)
- ctl: a stop reaches the server once whatever came first, and the launcher’s edges follow the spec (756798f)
- restart: the schedule holds the pending stop, a cancellation is a shutdown, the restart line is logged before the log closes (3ed8e45)
0.17.0 (2026-10-14)
Section titled “0.17.0 (2026-10-14)”Upgrade notes
Section titled “Upgrade notes”- The world catalog and the auth catalog were each squashed into one migration:
migrations/world/0001_world.sql, andmigrations/auth/0001_auth.sqlwith0002_account_bans.sqland0003_ip_bans.sql. A database made by 0.16.0 cannot be upgraded across this:mgctl initand the server stop on the old files, so the two schemas have to be made again. The steps are in “Moving to the one-file catalogs” in docs/persistence-operations.md. To keep accounts and world, write a.sql_backupwhile 0.16.0 still runs; then stop the server, delete the old files in<root>/migrations/authand<root>/migrations/world(a Docker or Kubernetes volume has them under/data/migrations/), runmgctl init <root>, drop theauthandworldschemas and their rows inmoongate_migrations.history, runmgctl migrate apply --target authand--target world, load the backup files withpsqland start. - The item and mobile template ids lost their graphic prefix:
0x19b9_iron_oreis nowiron_ore,0x0e75_backpackisbackpack_2,0x0eed_gold_coinisgold_coin.items.template_idstores the id, so the rows of a 0.16.0 world carry ids the new templates do not have; the commit that renamed them (#612) says so and wiped the development world databases. A template, script, shop, craft or spawn file of your own that names a shipped id has to be renamed too. mgctl initadds the files a root lacks and never replaces one that is there. To get what changed in files a 0.16.0 root already has, delete the ones you did not edit and runmgctl initagain:templates/items,templates/mobiles,templates/loots,templates/shops,templates/gumps,templates/books,scripts/,data/crafts/,data/messages,data/skills.toml,data/starting_items.toml,data/pet_food.toml,data/harvest.toml. Refresh them together: they use the renamed template ids.- New data files:
data/spells.toml(without it no spell can be cast; the spell scripts are inscripts/spells/),data/champions.tomlanddata/portraits.toml(both may be missing),templates/carves/,templates/shops/animal_trainer.toml, new files indata/crafts/for the other crafts, and new gumps intemplates/gumps/andscripts/gumps/. - New configuration keys, all with defaults:
ultima.show_motd_gump(true),ultima.combat.item_wear_enabled(true),ultima.pets.bonding_days(7),[ultima.vendors]withuncommon_multiplier,rare_multiplier,epic_multiplierandlegendary_multiplier(1.25, 1.5, 2.0, 3.0) andadmin_api.session_max_age_minutes(480). The defaults ofultima.items.backpack_templateandultima.items.gold_templateare nowbackpack_2andgold_coin: if yourconfig/moongate.tomlnames the old ids, change them. The server configuration page lists every key. - New
mgctl plugin install|list|remove: it installs a.nupkgplugin package (a file or anhttpsaddress) into<root>/plugins/, checks the exactMoongate.Server.Coreversion and asks for confirmation; seedocs/installing-plugins.md. Stop the server first. - Plugin bundles now share the entry assembly of the bundles they reference: a plugin that uses another plugin’s types lists it in
dependenciesand keeps it out of its own bundle, and a bundle built against a newer version of the shared assembly than the one loaded is refused at start. See “Depending on another plugin” indocs/plugins.md. - The administration gRPC contract only grew. New services:
AdminCharacters,AdminFirewall,AdminHelp,AdminJail,AdminLogs,AdminOperations,AdminPlayers,AdminSchedule,AdminTemplates. New RPCs:GetAccount,UpdateAccountAccess,ChangeAccountPassword,BanAccountandUnbanAccountonAdminAccounts,GetMetricsonAdminServer,RefreshonAdminSession(a new token, up tosession_max_age_minutesafter the login).AccountSummaryhas two new fields,ban_reasonandbanned_until. No field or RPC of 0.16.0 was renamed or removed, so a client generated from 0.16.0 keeps working. A session issued before the upgrade cannot be renewed; it expires. - New staff commands:
skill,write,items,npcs,mark_rune,add_spellandadd_reagents. IP bans are kept inauth.ip_bansand set through the administration API (AdminFirewall). - New Helm chart in
deploy/helm/moongate, published tooci://ghcr.io/moongate-community/charts/moongatewith each release: Kubernetes 1.26 or later, PostgreSQL 16, Redis 7.4 and a ReadOnlyMany or ReadWriteMany claim with the client files. Docker and Compose users have no new requirement, but a volume made by 0.16.0 needs the first note above before the new image starts. - A new character gets, among much else: the whole of Magery and Necromancy, the bard skills, tracking, stealing, poisoning and the other trades, the crafts (blacksmithing, tailoring, tinkering, fletching, cooking, cartography, alchemy, inscription), champion spawns, player guilds, bleeding and parrying, wear and repair of weapons and armor, carving, engraved stones and map items. Most of this was not tried with a real client yet.
⚠ BREAKING CHANGES
Section titled “⚠ BREAKING CHANGES”- convert: items.template_id stores the id, so every existing world save breaks by design: the change ships in development stage and the world databases are wiped.
Features
Section titled “Features”- admin: account detail and account characters through the administration API (33e4952)
- admin: account detail and account characters through the administration API (79a5a3f)
- admin: ban and unban accounts through the administration API (063f53b)
- admin: ban and unban accounts through the administration API (f3fab60)
- admin: character detail and intervention through the administration API (552ff8a)
- admin: character detail and intervention through the administration API (a38e8d1)
- admin: host metrics through the administration API (a97fb25)
- admin: host metrics through the administration API (17ebb76)
- admin: item and mobile template CRUD through the administration API (08cec39)
- admin: item and mobile template CRUD through the administration API (66a103b)
- admin: jail administration through the administration API (61e5060)
- admin: jail administration through the administration API (dda569e)
- admin: recent logs through the administration API (9529b2a)
- admin: recent logs through the administration API (d53cd7b)
- admin: refresh of the administration session token (e0cf832)
- admin: refresh of the administration session token (e6b83ef), closes #672
- admin: schedule status through the administration API (d600962)
- admin: schedule status through the administration API (383a6ca)
- admin: the firewall - IP bans through the administration API (0fcf1d7)
- admin: the firewall - IP bans through the administration API (5265cd3)
- admin: the GM help queue through the administration API (f920050)
- admin: the GM help queue through the administration API (aeaf503)
- arrow: the quest arrow packet (0xBA) and the arrow Lua module (9da208e)
- carving: blade.lua carves corpses, corpse.lua hears on_carving, shipped tables for the farm animals (c13239a)
- carving: carve entries tell the carver a client text (396c6d1)
- carving: carve service, carve module, on_carving hook and the corpse_carved event (952c5ee)
- carving: carve tables in templates/carves and a carve field on mobile templates (ce7c4a8)
- carving: carve tables, blades carve corpses, on_carving hook and corpse_carved event (1f30374)
- carving: the 100 carve tables of UOX3 and the carve field of 104 creatures (6f5929c)
- chivalry: implement Slice 1 - core infrastructure and simple spells (#686) (ff9359d)
- combat: a landed hit wears the weapon and a blow wears the armor it lands on (31b54a9)
- combat: item durability service with ModernUO’s wear rules and a config switch (1d63c14)
- combat: staves and crooks are their own weapon kind (0f47aec)
- combat: staves and crooks are their own weapon kind and wear armor by 0 or 1 (12cf498)
- combat: the bleed, the creature trigger and the bandage bind (f3569de)
- combat: the bleed, the creature trigger and the bandage bind (0835869)
- combat: the shield blocks by a Parry roll, as the classic pre-AOS rule (ae60c10)
- combat: the shield blocks by a Parry roll, as the classic pre-AOS rule (8383294)
- combat: weapon damage and armor rating follow the hits of the piece (279ac0e)
- combat: weapons and armor wear out (durability, slice 1) (c3e416e)
- commands: .add_spell fills a spellbook and .add_reagents fills the backpack with the reagents of a spell, a circle or all (e6848f6)
- commands: .skill sets a skill of the targeted mobile (e484d69)
- commands: .write targets an engraved stone and opens the gump to write on it (c2603f1)
- commands: skill command sets a skill of the targeted mobile (a71d99c)
- convert: item and mobile template ids without the graphic prefix (#612) (63090a0)
- convert: the craft of inscription is built from data/spells.toml, with the pen and ink a scribe’s tool (3e367cb)
- convert: uox-carves turns UOX3’s carve.dfn into carve tables and sets the carve field of the mobile templates (89032a4)
- convert: uox-spells writes the spells of Necromancy from a table (0dd1a33)
- crafting: a Repair item button in the crafting gump of the crafts that mend (3ae32c3)
- crafting: repair rules of ModernUO’s classic repair for the weapons and armor that wear out (830aa3f)
- crafts: inscription writes the scroll of a spell from a carried book, its reagents, a blank scroll and the mana of its circle (e94a79f)
- crafts: inscription, scribes write the scrolls of the spells they know (7576232)
- crafts: recipes may name a spell and a mana cost, and a main skill least below zero (9ff26d4)
- ctl: mgctl plugin install, list and remove (9a95eab)
- ctl: plugin install, list and remove (cd91113)
- data: spell_circles from UOX3’s SPATTACK for 99 mobile templates (27a6f7b)
- gmtools: the Items tool looks item templates up and gives or puts them, with a preview (d25f973)
- guards: guard_outsider and guard_outsider_archer, guards of the wilds that fight monsters for real, with a prey option for creature scripts (bcb4a7c)
- guards: guard_outsider, guards of the wilds that fight monsters for real (caf59b9)
- guilds: the player guilds of their guildstones (617) (895128d)
- guilds: the player guilds of their guildstones (617) (5d386e2)
- gumps: button_item, sprite, master, cliloc on text and colour on html in the XML (c7f6a4f)
- gumps: data/portraits.toml, its loader and the portrait service (6924c7d)
- gumps: gump.is_open, gump.close_all and columns in g:paginate (264cc7d)
- gumps: layout entries for buttontileart, picinpic, mastergump and a coloured html (404d0a3)
- gumps: new XML controls, Lua functions and creature portraits (d39c2fe)
- gumps: the Lua builder takes button_item and sprite, and slots call their on_click (d8a72d4)
- gumps: the portrait element, g:portrait and gump.portrait (f2fa514)
- gumps: the portraits converter and file, and the picture in the Animal Lore gump (6eae6b5)
- implement Meditation skill (46) with active and passive effects (b2da262)
- items: .items opens a gump of its own to look item templates up and give them or put them at your feet (546ff48)
- items: .items, a gump of its own to look item templates up and give them (4541815)
- items: can_decay hook keeps a due ground item for one more decay time (1910f03)
- items: can_drop_on and on_dropped_on hooks for items dropped on a non-container item (5a451c3)
- items: engraved stones, bought from an architect, placed and written on by their owner (d0c4bde)
- items: item.search finds item templates by id, name or graphic (01212fc)
- items: on_added, on_removed, on_item_added and on_item_removed hooks (402240d)
- items: on_delete hook through a new item event service (676bed9)
- items: on_mobile_near hook and the watch_range item template field (cadb110)
- items: on_move_off hook when a mobile steps off an item’s cell (1dc1e94)
- items: on_tooltip hook appends script lines to a player’s property list (5d9ae65)
- items: read the hits of a weapon or armor from its props and template (bcf8900)
- items: repair weapons and armor from the crafting gump (durability, slice 2) (9c9d146)
- items: the bandage cures a poisoned patient (6cea358)
- items: the bandage cures a poisoned patient (2de8ba5)
- items: the engraved stone script and its read and write gumps (46fe499)
- items: the engraved stone template and the architect’s shop line, 10000 gold (902dd70)
- items: the tooltip of a weapon or armor shows its durability (7c2e4d8)
- items: the traps of the treasure chests — arm, spring, one charge (a81d560)
- items: tooltips show the damage, speed, armor and strength of weapons and armor (7b4dc3a)
- lua: add shared cooldown and random helpers (45a5ad9)
- lua: mobile.turn turns a mobile on the spot; remove_trap bends over a carried chest (b8148cc)
- lua: share cooldown and random helpers (c689c16)
- magic: Magery slice 3, circles 5 to 8 (c9fdae9)
- motd: show a configurable native Updates window (4c72fb7)
- motd: show a configurable native Updates window (9cf95be)
- mounts: mount stones show a puff of smoke and play a sound where the rider gets on or off (fbe486d)
- mounts: mount stones, a backpack item that rides its mount and gets off on the next double click (cd33718)
- mounts: mount stones, an item in the backpack that rides its mount and gets off on the next double click (e63f274)
- npcs: .npcs opens a gump to look mobile templates up with a picture and spawn them at your feet (d9d82fe)
- npcs: .npcs, a gump to look mobile templates up with a picture and spawn them (a1e175a)
- npcs: a calmed creature fights and hunts no one until its time is up (7c31860)
- npcs: a provoked creature fights the creature a bard set it against (0986454)
- npcs: casters fight from where they can cast, with the classic mage’s choice (103c9ce)
- npcs: edge-triggered rules of the low health and low mana events (d285a40)
- npcs: monsters cast spells (cca9ca6)
- npcs: npc.search finds mobile templates by id, name or body (eaf0856)
- npcs: on_attack, on_hit, on_miss, on_combat_start and on_combat_end hooks (deff1cf)
- npcs: on_damage and can_die hooks for NPCs (7248cf0)
- npcs: on_enter_region and on_leave_region hooks (e1f51c4)
- npcs: on_heal hook through a new mobile.heal function (2e1f9ea)
- npcs: on_health_low and on_mana_low (30f1521)
- npcs: on_resurrect, on_tame and on_release hooks (184df3d)
- npcs: queue on_health_low and on_mana_low from the state service (483d5e9)
- npcs: the spell_circles of a mobile template and npc.spell_circles (f889e5d)
- persistence: the auth catalog is one migration (23aeb0a)
- persistence: the auth catalog is one migration (#629) (0c2b17e)
- persistence: the world catalog is one migration (21a3223)
- persistence: the world catalog is one migration (#627) (13a645b)
- plugins: bundles share the entry assembly of the bundles they reference (fe149aa)
- plugins: bundles share the entry assembly of the bundles they reference (baf224c), closes #685
- plugins: log each loaded disk plugin with its id, name, version and description (024246d)
- scripting: cliloc module publishes the client texts many scripts say (7c37945)
- scripting: item, mobile, death, tame and craft events for scripts that listen with events.on (20e4ce0)
- scripting: item.durability and item.set_durability read and set the hits of a weapon or armor (0fcd792)
- scripting: item.is_movable and item.loot_type (2babba5)
- scripting: item.split, item.layer, item.can_hold, and the view of a chest told on move_into (e842f4a)
- scripting: item.weight and mobile.hands_empty (708bd83)
- scripting: run a synchronous hook inline while a script is running (59851d1)
- scripting: script events for NPCs, items and vendors (4dc60e7)
- scripting: world.distance, mobile.skill_points and pet.owner (31ff170)
- scripts: cache what a script defines per script and function (62ac746)
- scripts: common geo and speech helpers and numbers.in_ranges (0d302c5)
- scripts: ScriptHooks catalog of every NPC and item hook the server calls (cb6880e)
- scripts: synchronous hook runner with a recursion guard (63afe33)
- skills: Begging grovels a coin or two out of a human NPC (6) (c3df5ce)
- skills: Camping lights a campfire on kindling (8) (ea70e86)
- skills: Detect Hidden names the trap of a chest picked directly (800471a)
- skills: Detect Hidden names the trap of a chest picked directly (3e4db22)
- skills: Discordance weakens a creature while the bard plays (5458748)
- skills: Herding walks a wild animal where the crook points (12) (57255a9)
- skills: implement Remove Trap (48): disarm the trap of a container (55597c3)
- skills: implement Remove Trap (48): disarm the trap of a container (4af4188)
- skills: instruments can be played and teach Musicianship (921fb87)
- skills: Item Identification, with ModernUO’s classic rules (34947e6)
- skills: Peacemaking calms a creature or everyone in range (9ba7488)
- skills: Poisoning rides a potion onto a blade or food (30) (70159ab)
- skills: Provocation sets two creatures against each other (f430395)
- skills: read a weapon or armor with Arms Lore (3b823d5)
- skills: Stealing, with ModernUO’s classic rules (0eb2c2b)
- skills: Taste Identification, with ModernUO’s rules (a52d79a)
- skills: Tracking with the quest arrow packet 0xBA and the arrow module (a424ac4)
- skills: understand the dead with Spirit Speak (31dbda4)
- spawns: the champion spawn regions, slice 1 — the engine and the six classic spawns (a9d3068)
- spells: CastAt, the cast of an NPC at a target it has (af27138)
- spells: Exorcism, the last spell of the necromancers, over the champion spawns (8fc3a01)
- spells: Necromancy, slice 1 — the school, the book and six spells (4e7697c)
- spells: Necromancy, slice 1 — the school, the book and six spells (b83a276)
- spells: Necromancy, slice 2 — the four forms on mobile.disguise (72627b0)
- spells: Necromancy, slice 3 — the three summons (0751892)
- spells: Necromancy, slice 4 — Evil Omen and Wither; Exorcism waits (fdde097)
- spells: spell.cast_at and spell.can_cast_at for the scripts of NPCs (3721579)
- spells: spell.find_book gives the carried spellbook that holds a spell (905b082)
- spells: the last four magery spells — Magic Trap, Magic Untrap, Magic Lock and Unlock (3516217)
- spells: the last four magery spells — Magic Trap, Magic Untrap, Magic Lock and Unlock (10ea2b0)
- templates: low_health_at, the percent under which an NPC script hears on_health_low (e5d4cd0)
- tracking: the Tracking skill script with its gumps and texts (8664952)
- vendors: a template tagged owner_on_buy makes the buyer the owner of what it buys (cb8fcde)
- vendors: can_buy, can_sell, on_bought and on_sold hooks on the vendor’s script (47ab69f)
- vendors: jewelers engrave rings and wedding bands with a text (79af71c)
- vendors: jewelers engrave rings and wedding bands with a text (c0d7b4d)
- vendors: pay more for rarer items and give gems a random rarity (1e29571), closes #584
- vendors: veterinarians and animal trainers sell the mount stones, 6000 the horse and 7000 the others (b97ae3a)
Bug Fixes
Section titled “Bug Fixes”- admin: refresh keeps the lifetime and deadline of the login (51fd5fd), closes #672
- arrow: clear the arrow by the serial it was shown with (790e536)
- carving: a corpse on another floor is out of reach, a carved corpse is shown again, a ghost opens a corpse whose script has no use hook (2b1afaa)
- carving: farm animal amounts as ModernUO, empty carve for ethereal and summoned kinds, mongbat and crane tables, converter reads every block and every line end (d568e15)
- carving: show the pieces laid on the ground beside a full corpse (3454437)
- carving: the blade needs a line of sight to the corpse or the tree (6af62ac)
- carving: the corpse is judged again after on_carving, the roll keeps its texts, pets and summons are not carved, a full corpse lays the rest on the ground (1f16632)
- ci: the package verifier takes the portable contracts from the folder (f838764)
- combat: a creature already fighting turns on a closer visible aggressor (811cd67)
- combat: a pet keeps its commanded target, a switch keeps the swing delay, a lost target is no target (c2ab48b)
- combat: Arms Lore reads a staff as plain like ModernUO and the staff kind covers UOX3’s whole staff group (f5ced53)
- combat: reflected damage names the wearer as the source of the stats change (b034c44)
- commands: .add_spell writes and shows a book once, .add_reagents keeps the backpack within its weight (2f44f9c)
- convert: a school written by hand after Necromancy survives a reconversion (9f8e298)
- convert: the first template of a chain that sets Magery decides if a creature casts (4803238)
- convert: uox-spells keeps the Magic Lock sound the data ships, and the check ignores the hand-written necromancy (ebfe4c6)
- crafting: a held piece, a dead player and a lost tool mend nothing; a pick that is no item says so (48f7eeb)
- crafts: a failed inscription ruins one of every resource, the blank scroll too, and takes no mana (3866240)
- crafts: a recipe that names a spell the catalog does not hold stops the server at startup, and spells load before crafts (37d846c)
- crafts: a scroll that lands at the feet is not said to be in the backpack (c223e43)
- crafts: inscription is tried in the windows of the classic data file, and the converter keeps the list of blank scrolls without –spells (1887910)
- crafts: the mapmaker sells and buys the mapmaker’s pen, which opens cartography, and the vendor converter keeps a template named like its type (efc175d)
- ctl: harden plugin install after review (bd8806a), closes #658
- defects found reviewing the features merged on 2026-10-12 (1e94680)
- defects found reviewing the features merged on 2026-10-12 (#624) (1ad3638)
- gmtools: the Items tool pages on the server and keeps the page, frames its search box, says when it cuts the list, and shows typed placeholders as typed (e577e09)
- guards: a guard fights a wild monster wherever it stands, not only in a guarded region, so one spawned by hand in a graveyard does (5c0b9bd)
- guards: the guards of the wilds leave the blue-named townsfolk of the monster script alone, see past a crowd of mates, and are weaker, with their damage told as it is (ea9c49c)
- guild and poisoning defects found in review (#624) (25fe266)
- guilds: the deed founds a guild, and a one-sided offer is taken back (617) (c65a5c0)
- guilds: the deed founds a guild, and a one-sided offer is taken back (617) (9a84869)
- guilds: the membership maps its Id and the guild tables get their serial sequences (617) (2830bec)
- gumps: placeholder button ids and pages cannot collide or close the gump, picinpic order, close_all count, paginate columns, reopened gumps in close_all, and the attribute rules of text (df305b1)
- gumps: text_entry literal=“true” keeps a player’s text as it is, and the stone’s write gump uses it (223179e)
- items: a box of spaces is no text, quotes around the words are dropped, the text keeps clear of wide pictures, and the pages and docs follow (763d600)
- items: a player’s on_move_off runs before the on_move_over of the new cell (93ad13e)
- items: can_drop is told the destination, so an engraved stone cannot be dropped in a bag someone else can lift (7cec803)
- items: free text tooltip lines stop at the slots left; a single click does not run on_tooltip (7b8501f)
- items: item.give names the receiving mobile as the actor of on_added (2955792)
- items: on_delete runs once and only for items that are in the world (5eae375)
- items: strip markup from the cleaned title, not before the control characters go (e420e46)
- items: the cut of a text keeps every character, only half a surrogate pair goes (3c5ad19)
- items: the engraved stone is movable, never decays and stays with a dead owner (ddcce00)
- items: the title of an engraved stone loses angle brackets and a leading hash (50a2f46)
- mounts: mount stones never stack, the docs say where a stone may be to get off, and review tests (6067054)
- npcs: a creature declares that it flees at its spawn, and a stale or tamed declaration is cleared (cc3f451)
- npcs: a creature gives up prey it cannot reach even when the prey moves (576664d)
- npcs: a human template has the body of its race, so every townsperson is found; the picture is drawn only for a body that has one; the spawn is said as asked (8e62d82)
- npcs: a queued low event is dropped when its NPC died or left, and mana low needs spell_circles (629efa1)
- npcs: a raised pet is silent on low mana until it has regenerated (27e7cce)
- npcs: combat end says killed for a creature that died, hooks that kill or cure are respected, real damage reaches on_hit (1ae8e45)
- npcs: monster AI findings of the comparison with the other emulators (d3fea09)
- npcs: the caster’s pause counts from the start of the cast, heals fall back and need no sight, no spell means melee (a2b0d3e)
- npcs: the mana re-arm of a weak caster stays one above the low line (4f4a21f)
- npcs: the script declares that a creature runs from blows, the combat service knows no script id (765b12c)
- npcs: walk_to is blocked at once while the NPC casts, and the usings of two test files are in order (55fc179)
- persistence: the low event states of an NPC are left out of its snapshot, so a healed NPC is not dirty (4611ac9)
- plugins: share bundle entry assemblies by assembly name and refuse a newer reference at start (6ef33d6)
- review findings on the fix branch (#624) (26a9ce8)
- scripting: hooks asked from inside hooks nest at most 8 deep (fdd56de)
- scripts: mind blast says the resisting text of magic.cliloc, and the guard test finds a published number written anywhere in a script (f7fb75c)
- scripts: the resurrect gump asks geo.near for the healer, stealth keeps its module table, and the helper guard and docs close the review gaps (e529d92)
- skills: let Remove Trap disarm a chest the player carries (948e328)
- skills: the review findings of Discordance (197a619)
- skills: the review findings of Item Identification (b68cc64)
- skills: the review findings of Provocation (19544d6)
- skills: the review findings of Stealing (f462d75)
- skills: the review findings of Taste Identification (686cd87)
- skills: the review findings of the bard skills (b15b0a0)
- skills: the seconds of Spirit Speak grow with every point (e50e623)
- skills: what Arms Lore says of a mobile and of the props it reads (6302d99)
- spawns: the skulls of a champion ring lie on the ground, not under it (1e15793)
- spells: Blade Spirits and Energy Vortex roll their seconds only once a place is found (6a4e4dd)
- spells: dispel and mass dispel show one puff for a summon they undo (21e0221)
- spells: magic arrow stops when the target cannot be harmed and hurts it after the caster left (e785dee)
- spells: the gesture only on a human body, and no recovery kept for an NPC (59929a4)
- templates: outsider guards are a fair fighter, 81 to 101 hit points and damage 5 to 11, not a near-immortal one (17badc1)
- templates: outsider guards sit between the first and second tuning, 116 to 146 hit points and damage 8 to 18 (35bf6af)
- templates: TemplateContentService disposes the gate of its writes (c7ce20b)
- tracking: the review findings of the Tracking skill (b22bab8)
- use RemoveProp and the pre-AOS meditation rules, with tests (a9101f3)
- vendors: a sale or purchase is re-checked after can_sell and can_buy ran (4f0a3db)
- vendors: an engraving order can be cancelled, expires and never blocks lessons (f4f7aa0)
- vendors: cut rarity prices in decimal and keep the gem rarity in the converter (fb4547d)
- vendors: the buy window reuses the vendor’s two containers, so a second window is not read from the first (1996ec2)
Performance Improvements
Section titled “Performance Improvements”- scripting: event subscribers are counted per event instead of scanned (960a0b3)
0.16.0 (2026-10-09)
Section titled “0.16.0 (2026-10-09)”Upgrade notes
Section titled “Upgrade notes”- One new world migration,
0026_help_pages.sql(the queue of the pages to the game masters): runmgctl init <root>and thenmgctl migrate apply --root-directory <root> --target worldbefore starting the server, or setpersistence.auto_apply_migrations = true. mgctl initadds the files a root lacks and never replaces one that is there. To get what changed in files a 0.15.0 root already has, delete the ones you did not edit and runmgctl initagain:templates/items,templates/mobiles,templates/shops(new: what each vendor sells),templates/gumps,templates/spawns,templates/npc_lists,scripts/,data/messages,data/skills.toml. New data files:data/taming.toml,data/pet_food.toml,data/schedule.toml,data/harvest.tomlanddata/crafts/.- New configuration sections, all with defaults:
[ultima.help],[ultima.schedule],[ultima.stable],[ultima.pets]. The server configuration page lists every key. - The C# converters and
mgctl convertare gone: the converters are now the Python ones intools/convert(moongate-convert, run withuv). - A new character can be mounted, tame animals, stable pets, fish, chop wood, mine and craft carpentry; pets lose loyalty over time unless fed. Most of this was not tried with a real client yet; mounts slice 1, the Help menu and the Go gump were.
Features
Section titled “Features”- a mounted rider moves at mounted speed (663317b)
- a rider cannot mine, fish or use Stealth (d1b009a)
- a rider dismounts when it dies (b28894a)
- a rider swings with the actions of a mount (a6e8309)
- a tamed creature follows its owner and obeys its words (69be765)
- a teleporter can refuse a rider (0d282f3)
- convert: the carpentry tools get the carpentry_tool script (f6bd543)
- convert: the DFN reader and the tables of the UOX3 converter in Python (8e2f55d)
- convert: the Python books converter, modernuo-books (68f859f)
- convert: the Python converters, part 1 (signs, teleporters, places, chests) (8eb4b70)
- convert: the Python converters, part 1: signs, teleporters, locations and treasure chests of ModernUO (ecd904b), closes #441
- convert: the Python converters, part 2 (books, vendors, guildmasters, spawns) (e463d91)
- convert: the Python converters, part 3 (UOX3) (780843d)
- convert: the Python guildmasters converter, modernuo-guildmasters (05b0e20)
- convert: the Python npc lists and spawn regions pass of uox (266aa65)
- convert: the Python spawns converter, modernuo-spawns (e6ebeae)
- convert: the Python starting items pass of uox (d31a948)
- convert: the Python uox command for items and loot (2e830f5)
- convert: the Python vendors converter, modernuo-vendors (a3fa79d)
- convert: the UOX3 mobile pass in Python, NPCs, creatures and name lists (0b2d112)
- convert: UOX3 create menus into data/crafts, carpentry first (e3ce41d)
- ctl: mgctl convert modernuo-vendors (3fb4a5f), closes #431
- data: a pickaxe digs iron ore out of rock, and a forge smelts it into ingots (109f953)
- data: a place is of one kind of wood, and a master finds rare things with the logs (5ec8c76)
- data: an axe held in the hands chops a tree for logs (a589133)
- data: an axe saws logs into boards, and a blade hacks kindling off a tree (8af3e84)
- data: an axe saws logs into boards, and a blade hacks kindling off a tree (3129158)
- data: Call a game master in the help menu, the kind and the line of the request (4ad6634)
- data: carpentry, the first craft of a shared crafting engine (8270273)
- data: exceptional items, the maker’s mark, tool wear and make last (909f18a)
- data: exceptional items, the maker’s mark, tools that wear out and make last (9ac39f6)
- data: kinds of wood, rare finds and the axes’ bonus in a fight (7a6e111)
- data: the crafting engine and the carpentry tools (c648f8b)
- data: the crafting gump (1e68e90)
- data: the door script opens for an NPC in its way, and the docs (059a81b)
- data: the fishing pole fishes: water, eight seconds, a fish, old footwear or nothing (12ea4b3)
- data: the help gump and its script, I am stuck, commands and rules (f47f400)
- data: the texts of the help gump in the eight languages (f8e4407)
- data: the texts of the help requests in the eight languages (c2f7935)
- double-click mounts a creature and dismounts the rider (b63e1cc)
- ethereal mounts in the mount service (e2fcf0b)
- guildmasters (7d33847)
- mount and dismount service (5195bf0)
- pet loyalty, food and obedience (#489) (baed95f)
- scripts: Anatomy, Evaluating Intelligence, Forensic Evaluation and Detecting Hidden (d9a12bc)
- scripts: Anatomy, Evaluating Intelligence, Forensic Evaluation and Detecting Hidden (d8361a7), closes #425
- scripts: lockpicks pick the locked treasure chests (34d6dea)
- scripts: lockpicks pick the locked treasure chests (f173883), closes #427
- scripts: Sell in the vendor script and the vendor module (091ea81), closes #433
- scripts: shopkeeper.lua and the vendor Lua module (cbfb980), closes #431
- scripts: Stealth and Snooping (2b979d0)
- scripts: Stealth and Snooping (a59ad4c), closes #429
- scripts: the clean bandage heals, and raises a ghost (7fd563d)
- scripts: the clean bandage heals, and raises a ghost (519075a), closes #421
- scripts: training dummies and archery buttes work (8067131)
- scripts: training dummies and archery buttes work (7f0575e), closes #423
- server: a hit that does damage leaves blood on the ground (9a6e2b0)
- server: a hit that does damage leaves blood on the ground (cfd210b), closes #419
- server: a path may be planned through a closed door that is not locked (13e7878)
- server: a script that picks a place is told the land of its cell (cd137f1)
- server: a script that picks a place is told the static that was picked (93951de)
- server: Christmas snowballs and gifts, and the on_login hook of the events (4652f2d)
- server: Christmas snowballs and the gift at login, and the on_login hook of the events (904d048)
- server: fishing with a pole, and resources that run out by area (7966873)
- server: give gold to a player through the bank service (6489370), closes #433
- server: guildmasters speak to the player only (20d143d)
- server: Halloween trick or treat, the first event with content (e48a442)
- server: Halloween trick or treat, the first event with content (6567c74)
- server: harvest areas have a vein, and an axe hits harder with Lumberjacking (c0a788b)
- server: harvest resources that run out by area and come back, the harvest Lua module and world.is_water (6862740)
- server: hide and unhide for the staff, and the staff snoops anyone (05a21b7)
- server: load the crafts of data/crafts and their resource lists (b4c36d3)
- server: lumberjacking with an axe (7fefc84)
- server: mining iron ore and smelting it at a forge (31029aa)
- server: npc guilds, joined by speech and gold (9b60493), closes #439
- server: npc.walk_to opens the door in the way of an NPC that opens doors (8282fb1)
- server: NPCs open the doors in their way (c3e0566)
- server: packets of the vendor sell list (7d7ba2c), closes #433
- server: packets of the vendor shop window (55876af), closes #431
- server: sell to a vendor (0cdb463), closes #433
- server: shop data, loader and shop service (fe5b52e), closes #431
- server: skill trainers (f19bbe0), closes #437
- server: take carried gold through the bank service (7d8bcd2), closes #431
- server: the calendar arithmetic of the schedule, daylight saving included (43683b4)
- server: the craft service and the craft Lua module (876cacd)
- server: the GM page queue, Call a game master and .pages (1b2e8ea)
- server: the Help button is a recognised packet, no longer an unregistered opcode (c069374)
- server: the Help button opens a menu with “I am stuck” (e45fb32)
- server: the Help button opens the help menu (06ec511)
- server: the help Lua module, the settings and the nearest starting city (bd97714)
- server: the help module gives scripts the queue of the requests (df647f7)
- server: the help page entity, its table and the settings of the queue (850169c)
- server: the help page service, the queue of the requests for the game masters (f60fa5b)
- server: the messages of the schedule and the script service of the events (78a1fc9)
- server: the NPC door service: who opens doors, and the door ahead is asked to open (da1fd18)
- server: the pages command and the gumps of the help requests (3f054aa)
- server: the schedule file, its loader and the time zone setting (cf82336)
- server: the schedule Lua module and the event command (5010e15)
- server: the schedule service, timed tasks and the shutdown with warnings (88d2345)
- server: the schedule, scheduled shutdown and seasonal events (b3e40fe)
- server: the seasonal events, their dates, the staff modes and the hooks (2635fab)
- server: the tooltip says exceptional, who crafted an item and the uses left of a tool (2c80b6a)
- server: the towns are decorated while Halloween and Christmas are on (a026a84)
- server: the towns are decorated while Halloween and Christmas are on (b1854d1)
- server: the ultima.help settings, the wait and the pause of ‘I am stuck’ (274e6d1)
- server: vendor restock and resale (c78f7dd), closes #435
- server: vendor shop window and purchase (34e52a0), closes #431
- skill trainers (f83e2dc)
- tag the horse templates with their mount item (e202a9c)
- templates: ModernUO shops, vendor docs and translations (f947124), closes #431
- templates: the guildmasters of ModernUO (6ab95f3), closes #439
- templates: the guildmasters wear and carry the items of their trade (bb13381)
- templates: the sell tables of ModernUO’s shops, docs and translations (690eaac), closes #433
- the .tame command gives a creature an owner (207a017)
- the Animal Taming skill (ca2ae70)
- the ethereal statuettes (6e1112b)
- the followers of a player and the tame of a creature (b442b2f)
- the pet Lua module (9e75478)
- the stable Lua module (5d72254)
- the stable service (c6a6262)
- the stablemaster (b2ce5fb)
- the taming data from ModernUO (07d93a7)
- the taming data, its loader and service (1ad983a)
- vendors, slice 1 (shops and buying) (f596e99)
- vendors, slice 2 (selling to vendors) (fadd343)
- vendors, slice 3 (restock and resale) (d03c5a8)
Bug Fixes
Section titled “Bug Fixes”- a tamed creature goes for nobody (55eec6a)
- convert: the locations converter corrects Cell 7 of the jail (eb56697)
- convert: the review of the Python converters part 1 (88b960c)
- convert: the review of the Python converters part 2 (7742888)
- convert: the review of the Python uox converter (316eb6c)
- data: armorers and smiths sell the metal helmets (edad344)
- data: regenerate the items and mobiles that were older than the converter (10f83c9)
- data: regenerate the items and mobiles that were older than the converter (6cad556)
- data: the context menu entries of vendors and trainers use the client’s whole text numbers (092afd9)
- data: the review findings of boards and kindling (4825b01)
- data: the review findings of carpentry slice 2 (af041c8)
- data: the review findings of the kinds of wood (19281a1)
- data: the shops sell the weapons and tools they lost, and healers, spinners and the fortune teller keep a shop (717297d)
- review criticals of the pet loyalty (e21b7a8)
- scripts: nobody but a game master drops items into a locked chest (874f831)
- scripts: the dummies and buttes of .decorate run their scripts (0858a45)
- scripts: the review findings of Stealth and Snooping (e9fa70e)
- scripts: the review findings of the bandage (86fc4af)
- scripts: the review findings of the lore skills (4ba4d93)
- server: a vendor looks at its customer from the eyes, not along the floor (1adc071)
- server: a vendor offers Buy and Sell only when its shop sells or buys, and the fishers have a shop (43ad747)
- server: an item given joins the stack of its kind in the backpack (bcbd3ea)
- server: check the price before making the goods, and vendors that cannot serve do not claim the speech (323f3ff)
- server: one answer per saying and the candies of the converted templates (bd15f88)
- server: the blood gives way when the serial pool runs short and never lies off the map (e5ba0e5)
- server: the decorations reach Trammel, skip items, and a stale pause cannot place twice (2013f95)
- server: the hooks of the seasonal events run on the loop and the timers cannot stop it (4111225)
- server: the minors of the vendors review (9cb38f1)
- server: the review findings of carpentry (08a67b2)
- server: the review findings of fishing (73d13a6)
- server: the review findings of lumberjacking (e74b535)
- server: the review findings of mining and smelting (84b1368)
- server: the review findings of the doors NPCs open (3c92d1d)
- server: the review of selling to vendors (f7bb7a3)
- server: the review of skill trainers (549916c)
- server: the review of the bank payment (491ef47)
- server: the review of the guildmasters (d92ff38)
- server: the review of vendor restock and resale (6bc6ec3)
- server: vendors are paid straight from the bank box (08c100a)
- templates: no vendor pays more for an item than the lowest price it is sold at (6e44290)
- templates: shops buy the plain piece of an armor or weapon and sell every material (13e43a1)
- the minor review findings of mounts (7312018)
- the minor review findings of pet loyalty (94d0812)
- the minor review findings of the ethereal mounts (66fb52a)
- the minor review findings of the pet orders (d55c6cd)
- the minor review findings of the stable (ed21227)
- the minor review findings of the taming (5ef2702)
- the review findings of mounts (bbfbae5)
- the review findings of the pet orders (e32669f)
- the review of the GM page queue (289d731)
- the review of the help menu (aea59de)
- the review of the removal of the C# converters (47e2648)
0.15.0 (2026-10-07)
Section titled “0.15.0 (2026-10-07)”Upgrade notes
Section titled “Upgrade notes”- Nine new world migrations,
0017_mobile_criminal.sqlto0025_mobile_murder_counts.sql(criminal flag, jail sentences, bulletin messages, deferred container foreign key, book attachment claims, stat locks, murder counts): runmgctl init <root>and thenmgctl migrate apply --root-directory <root> --target worldbefore starting the server, or setpersistence.auto_apply_migrations = true. mgctl initadds the files a root lacks and never replaces one that is there. To get what changed in files a 0.14.0 root already has, delete the ones you did not edit and runmgctl initagain:templates/items,templates/mobiles(every creature template now carriesflee_at, andarcherguardis new),templates/gumps,templates/books,templates/decorationsandscripts/.- New configuration sections, all with defaults:
[ultima.skills],[ultima.combat],[ultima.crime],[ultima.murder],[ultima.jail],[ultima.bulletin_boards],[ultima.bank]. The server configuration page lists every key. - Players now fight, die and come back as ghosts at an ankh or a healer. Creatures that go for everyone (the
monsterscript) attack players and townsfolk, and the guards kill them. A criminal player is still only stood on by the guards. - Most of the new gameplay was not tried with a real client yet; death, healers, monsters and the books were.
Features
Section titled “Features”- add claimable item attachments to letters (b17c749)
- books: add a gift letter with 100 gold coins (ad3a42c)
- books: add staff command to create template documents (e7d93f5), closes #377
- books: create and read personalized scrolls (b64d648)
- books: import the static ModernUO catalog through mgctl (0fc6da1)
- books: load and render readable text templates (44821da)
- books: readable scrolls from personalized text templates (d5dbac3)
- books: translate the complete lore catalog and preserve reimports (4399a60)
- books: translate the lore catalog into seven supported languages (e507339)
- converter: import ModernUO book texts and ship readable catalog (e7f0a49)
- converter: preserve validated book translations on reimport (26e1f8e)
- converter: read static ModernUO book content without executing scripts (af62a76)
- converter: the combat fields and the kind of weapon of UOX3 items (53852b5), closes #390
- data: a blank book for every new character, and the docs of writable books (8083177)
- data: FLEEAT as flee_at on 46 templates, and the docs of archers and fleeing (34d354b)
- data: the banker offers Open Bank Box in its context menu (2d9fddb)
- data: the imported books are books, with the covers of their source (613479c)
- data: the wait of every skill a player uses directly, as ModernUO (cff2449)
- deliver personalized documents through starting items (1207bbb)
- deliver personalized documents through starting items (9bcff9e)
- docs: publish English and Italian authored documentation (aeca974)
- docs: show examples under the functions of the Lua API reference (2659a40)
- docs: support English and Italian authored documentation (9338fc6)
- expose localized letter attachment withdrawal (5f3114b)
- freeze letter rewards during document creation (05856ca)
- persist atomic letter attachment claims (133517c)
- persistence: world.jail_sentences table for the jail sentences (4329ff5)
- prepare frozen book attachments from templates (67ecf1c)
- scripting: the jail Lua module (7b7535d)
- scripts: the guards standing in the towns notice a criminal and go to it (64657bb)
- scripts: the guards standing in the towns notice a criminal and go to it (d6efad1), closes #330
- server: .kill takes a player, and the docs of player death, ghosts and ankhs (5dfc88d)
- server: .resurrect and mobile.resurrect raise a ghost, mobile.is_dead tells who is one (77ae0c5)
- server: a book item opens the client’s book (cbff651)
- server: a chest of bread and water in every jail cell, and the release note (534f881)
- server: a client text with something appended (0xCC) (2c276c7), closes #365
- server: a document source may make its book writable (fc33b88)
- server: a document source may set the graphic of its item (4041e59)
- server: a ghost is shown by war mode, does not reveal itself by a step and uses only what its script allows (9252a1b)
- server: a ghost regenerates nothing, uses no skill and lifts nothing (0f38346)
- server: a human corpse is drawn dressed; items in ground containers have tooltips (43384c3)
- server: a human corpse is drawn dressed; items in ground containers have tooltips (#342) (991a9f2)
- server: a jail sentence can carry its reason (13c961f)
- server: a jail sentence can wait for its prisoner (6afc2e1), closes #337
- server: a jail sentence carries its reason (f972940), closes #334
- server: a Lua module runs the commands of the server (73e0d0b)
- server: a mobile can be a criminal, with its timer and the grey name (2eebf1d)
- server: a mobile can be a criminal, with its timer and the grey name (2bb309b), closes #325
- server: a mobile notes when it last took a step (6fe9e89)
- server: a player dies and becomes a ghost (1922d18)
- server: a player reads the place it enters and the protection of its guards (cf72376)
- server: a player reads the place it enters and the protection of its guards (48d8248), closes #320
- server: a player with a bow or a crossbow shoots, spending ammunition (6eb3128)
- server: a script makes a player’s client walk to a spot (0x38) (c715371)
- server: a script posts on a bulletin board (9d163d8), closes #349
- server: a successful skill check can raise a stat (634a6ad), closes #372
- server: a waiting jail sentence starts at the login (2afddad), closes #337
- server: an item says what it is worth on its tooltip (48b2f5f), closes #365
- server: an NPC dies and leaves its corpse (0565b2d)
- server: an NPC dies and leaves its corpse (#340) (1c2cb9e)
- server: an NPC turns to who speaks to it (4cf2aab)
- server: an NPC with a bow or a crossbow shoots from its range, with the arrow flying to its target (a15dc57)
- server: an NPC’s script may take an item dropped on it (on_drag_drop) (696c51a)
- server: ankhs ask a ghost whether it wants to live, and the decoration places both pieces of each (e4028bb)
- server: archer guards shoot what they go for from the range of their bow (7a23541)
- server: archers keep to their bow’s range and a hurt creature runs, in the shared creature script (4fac4e1)
- server: balance, withdraw and deposit of the bank (633842f), closes #361
- server: bank checks (bc06b1d)
- server: book text is split into pages of eight lines (2db1453)
- server: bulletin boards are placed and open on a double click (de4e5d3), closes #343
- server: bulletin boards: read, post, reply and remove (23e89e4)
- server: combat fields in the item templates (915e281), closes #390
- server: combat kills a player at no hit points and a ghost does not fight (8628e59)
- server: combat notes aggressions, a dead player’s corpse knows its owner, login forgets old counts (ab0aeac)
- server: combat reads the weapon and the armor of a player (fa2b4e9), closes #390
- server: combat reads the weapons and armor of items (d1eab1f)
- server: combat settings, formulas and the skill check by chance (5a7c83c), closes #384
- server: containers keep to their item limit (6b65cbc), closes #361
- server: context menus (slice 1) (49b1b4c)
- server: create_check and add_gold commands for game masters (4fde788)
- server: data/jail.toml with the ten jail cells (8baa3e4)
- server: dyes and dye tubs dye what is dyeable (0893808)
- server: dyes and dye tubs dye what is dyeable (#336) (9706828)
- server: every hostile creature fights, and the animals keep to themselves or run (163b1d2)
- server: gold and bank checks dropped on a banker are deposited (34e344f)
- server: guards appear beside the criminal, not on it; the dead are wanted no more (6a50fd3)
- server: healers offer a ghost to come back, at the cost of a tenth of its fame (7933be5)
- server: healers refuse murderers, evil healers raise anyone, a resurrection costs a murderer skills and stats, guards go after the reds (375b160)
- server: jail <name> opens the gump on a player by its name (de8fe91), closes #337
- server: jail a player who is offline (37de1ab)
- server: jail settings in [ultima.jail] (789d23b)
- server: jail with a gump, timed sentences, a fine, a release note and cell rations (7cab5f2)
- server: jail.send takes a player who is offline (6a8824a), closes #337
- server: JailService sends a mobile to a cell for some days (4ff407b)
- server: looting the corpse of an innocent player is a crime, guards call for murderers (10d33bd)
- server: Lua functions for bank checks (42954d2), closes #365
- server: Lua functions for the bank’s gold and client texts of NPCs (d807f45), closes #361
- server: Lua scripts post, list and remove on a bulletin board (21ae5d5)
- server: Lua scripts post, list and remove on a bulletin board (31d30e6), closes #349
- server: melee combat, bare-handed: a player fights and kills an NPC (fb8743b)
- server: monsters go for the townsfolk too, guards kill monsters, and the review findings (17f9e87)
- server: native books (1c59f1a)
- server: NPC scripts hear of a death with on_mobile_killed, player or NPC (902260a)
- server: NPCs do not sense a ghost (2f87c8e)
- server: players open, read, post and remove on a bulletin board (9fe4650), closes #343
- server: resurrect brings an NPC back from its corpse (fae4d4e)
- server: resurrect brings an NPC back from its corpse (#355) (f623d77)
- server: saying “guards” in a guarded region brings a guard onto a criminal (a2afe2c)
- server: saying “guards” in a guarded region brings a guard onto a criminal (1e4dc17), closes #327
- server: skills are used, checked and gained (7f6d062)
- server: skills are used, checked and gained (5955d75), closes #364
- server: stat settings and the stat locks of a mobile (91bd067), closes #372
- server: stats rise with skills, with caps and locks (3f73733)
- server: the .jail command (756380c)
- server: the ammo service spends an arrow or a bolt at each shot and leaves some on the ground (ebf4b82)
- server: the ammunition of a bow or a crossbow, found in the backpack (a26c8f8)
- server: the animate command plays an action on the mobile you target (14920fc)
- server: the archer guard template, and the guards called in Ilshenar and Malas are archers (3f1accf)
- server: the attack request starts a fight and peace ends it (3e4f87a), closes #384
- server: the bank writes and cashes checks (dffe9fb), closes #365
- server: the banker tells the balance, withdraws and deposits (fed75a5), closes #361
- server: the banker writes checks and a double click cashes them (7b56f7e), closes #365
- server: the banker’s speech commands, criminals refused, item limit of containers (6737eaa)
- server: the book header and pages packets (6f233c3)
- server: the book packets carry what a player wrote (cd8fc26)
- server: the book packets carry what a player wrote (1c2c11f)
- server: the bulletin board service: post, reply, remove, expiry and capacity (40af883), closes #343
- server: the carrier of a writable book writes its title, author and pages (5bf3b93)
- server: the client asks for a context menu and chooses from it (59e1e25)
- server: the client sets the locks of its skills (70909a3), closes #369
- server: the client sets the locks of its stats (9a07081), closes #372
- server: the combat gear service and the weapon families (84e5d64), closes #390
- server: the combat Lua module and a monster that fights (bab2514), closes #384
- server: the combat service, the combat packets and the attack request (0c90d76), closes #384
- server: the console says who is jailed and who is released (5e88d44)
- server: the context menu packet (d3ac21f)
- server: the context menu service, with the server’s entries and a script’s (1319108)
- server: the end of a jail sentence takes the fine and gives a release note (41a7324)
- server: the Enhanced Client’s icons choose an entry of a context menu (146ad2c)
- server: the flee_at of a template, from UOX3’s FLEEAT, and combat.range for the scripts (8eee26a)
- server: the gmtools command and its docs (20d0ee2), closes #376
- server: the gmtools gump with the weather tool (ceb2b2d), closes #376
- server: the gmtools gump, a sidebar of GM tools with the weather first (17336c7)
- server: the gump that asks the victim to report a murder (493e00e)
- server: the header says when and how the binaries were built (b985b9a), closes #353
- server: the jail finds player characters by name (0c88dc9), closes #337
- server: the jail gump and the release note script (425a48e)
- server: the jail gump lists homonyms and waiting sentences (3cf8941), closes #337
- server: the jail gump opens without a target, picks it and goes to a cell (a2e1314)
- server: the jail gump opens without a target, picks it and goes to a cell (e93f664), closes #332
- server: the jail sentences a player who is offline (324b0ec), closes #337
- server: the living hear a ghost as oOo and nobody answers it (9905f90)
- server: the murder counts of a mobile, saved, and the red name of a murderer (0aeb4b1)
- server: the murder service counts reported kills, asks the victim, and forgets with time (cfbb55a)
- server: the packets of the bulletin board (0x71) (79e6f09), closes #343
- server: the place entered reads in green, the place left in red (17407f8)
- server: the Season tool of the gmtools gump (ed048e2), closes #381
- server: the settings of the bank (6358ef8), closes #361
- server: the stat locks are sent at login and kept by SetStatLock (37f8428), closes #372
- server: the table and the settings of bulletin board messages (1c809a9), closes #343
- server: the Time tool of the gmtools gump (7382e6e), closes #383
- server: the version and uptime commands (4c03d36), closes #353
- server: the wait after a skill is set in skills.toml (341d6ef)
- server: town guards kill the criminal NPC (#358) (ab34d9a)
- server: town guards kill the criminal NPC and appear beside it (f8efb33)
- server: version and uptime commands; build time and configuration in the header (7ffe7ce)
- server: weight, overloading and the stamina a step costs (011ca9e)
- server: weight, overloading and the stamina a step costs (af10b4b), closes #316
- server: whispers, yells and emotes are heard, each within its own range (0cd176e)
- server: world.weather_profile and world.set_weather (26fd00f), closes #376
- server: writable books (7c867d3)
- server: written pages go back to the saved text of a book (b060f48)
- supervise exactly-once attachment withdrawal (31ca65e)
Bug Fixes
Section titled “Bug Fixes”- books: preserve Czech names in grammatical context (36751dc)
- books: refine Polish and Czech source fidelity (13e2063)
- books: support nested scroll use and existing-root upgrades (329212e)
- books: validate starting item capabilities and align documentation (ff4dc40), closes #386
- books: validate starting items and align documentation (19fb4a0)
- ci: take the workspace back on a rootless Docker too (e542246)
- converter: validate escaped book sources and preserve serialized text (8d960e4)
- ctl: run_server.sh shows the banner once (f3f4029)
- data: a monster that is hit turns on the one who fights it (829e310)
- data: the furniture of old Magincia is no longer placed (040ce87)
- data: the notoriety of a template reaches the NPC, and vendors, bankers and guards are invulnerable (c1d8ff8), closes #389
- data: the old Haven of Trammel is set aside, and an underscore sets a decoration file aside (cde7219)
- data: the translated ModernUO books are laid out as the English source (cd35753)
- defer letter integrity checks during SQL backup restore (1de899d)
- docs: close the open minors of the Lua documentation (3960ebb)
- docs: close three gaps of the Lua API reference build (7726453)
- docs: the bulletin board Lua docs name world.now, not os.time (4502b42), closes #349
- docs: the packet list entry of 0x89 uses a variable field for its items (9601f4f)
- persistence: a world save no longer fails when an item is written before its container (0ae142a)
- persistence: a world save no longer fails when an item is written before its container (0a66cf8)
- preserve letter receipts and propagate deferred logout faults (688d848)
- respect nested capacity and exclude item-use scripts during claims (f3c8e95)
- scripting: name script parameters in snake_case and tidy the Lua guide (b0b1396)
- scripts: settle the findings of the guard script review (6b6a598), closes #330
- server: a banker hands out the gold whatever it weighs, as ModernUO (53f3602), closes #361
- server: a human NPC falls dressed when it dies (cdb13b6)
- server: a human NPC falls dressed when it dies (163c182)
- server: a human NPC no longer falls naked when it dies (977f6e4)
- server: a prisoner holding an item on its cursor waits for its release (3521ab5)
- server: a skill used too soon is answered once a second, and its text is not logged whole (ebb9890)
- server: a view full of items no longer disconnects the client (0f7579e)
- server: accept the world map’s 0xF0 query instead of closing the connection (25fa5cb)
- server: an item says its rarity on its tooltip only above common (2818b5c)
- server: settle the findings of the bank checks review (a102d89)
- server: settle the findings of the bank commands review (f00be19), closes #361
- server: settle the findings of the bulletin board review (84b8219), closes #343
- server: settle the findings of the combat gear review (0f8e09b), closes #390
- server: settle the findings of the combat review (fc4abdd), closes #384
- server: settle the findings of the context menus review (a67fd86)
- server: settle the findings of the criminals review (4723cfc), closes #325
- server: settle the findings of the dressed corpse review (6a75217)
- server: settle the findings of the dye review (2ba3589)
- server: settle the findings of the gmtools review (93b0e70), closes #376
- server: settle the findings of the guard call review (78e89d4), closes #327
- server: settle the findings of the jail reason review (6376da1)
- server: settle the findings of the native books review (2db49af)
- server: settle the findings of the NPC death review (f1e297d)
- server: settle the findings of the offline jail review (efa365f), closes #337
- server: settle the findings of the region messages review (6bb2abc), closes #320
- server: settle the findings of the resurrect review (226dc57)
- server: settle the findings of the skills review (4bf9e90), closes #364
- server: settle the findings of the stat gain review (f557f30), closes #372
- server: settle the findings of the version and uptime review (c316462), closes #353
- server: settle the findings of the weight and fatigue review (9bd7237), closes #316
- server: settle the findings of the writable books review (b4d41eb)
- server: settle the minors of the bank checks review (950bcc6)
- server: settle the minors of the version and uptime review (c827d60)
- server: settle the minors of the writable books review (a11924c)
- server: the final save is not cut at shutdown; a human NPC does not fall naked (7d55bdf)
- server: the final world save is no longer cut after 5 seconds (6192e13)
- server: the gmtools messages take 30185 and 30186 (f43f52c)
- server: the jail waits for a login to finish, and the gump tells a sentence that is over (d393afb)
- server: the review findings of archers and fleeing (654010b)
- server: the review findings of player archery (7e5e8a5)
- server: the review findings of player death (4e2ee84)
- server: the review findings of the archer guards (dc36d4c)
- server: the review findings of the healers (ecc66a7)
- server: the review findings of the murder counts (03bc22d)
- server: the server says why it refuses an attack and what it receives (5930f78)
- server: the staff gives an item to an NPC from any distance, and a far player is told why it came back (e44cee8)
- server: the status window shows the damage of the fists (35aa03f)
- the review findings of the null-forgiving cleanup (889854e)
- validate starting documents in the configured language (e2ca776)
0.14.0 (2026-10-04)
Section titled “0.14.0 (2026-10-04)”Upgrade notes
Section titled “Upgrade notes”- Two new world migrations,
0015_mobile_hunger.sqland0016_mobile_thirst.sql: runmgctl init <root>and thenmgctl migrate apply --root-directory <root> --target worldbefore starting the server. Existing characters and NPCs start full and quenched. - Or let the server do it: the new
persistence.auto_apply_migrations = truemakes a start add the bundled core migrations the root lacks and apply the pending ones, plugin bundles included. It is off by default, needs a database role that may change the schema, and never writes SQL from the entities. With a Docker image an update is then a new tag and a restart. mgctl initadds the files a root lacks and never replaces one that is there. To get what changed in files a 0.13.0 root already has, delete the ones you did not edit and runmgctl initagain:templates/items(food and drinks now carryscript_id = "food"and"drink"),templates/mobiles(the undead carryscript_id = "monster"),templates/spawns(the Tokuno and Malas spawners are on their own maps),data/starting_items.toml(bread and a pitcher of water for every new character) anddata/messages(the new texts in the eight languages; without them the English text is used).- Hunger and thirst are on by default: a player loses a point of each every five minutes, at 0 hunger its hit points do not come back and at 0 thirst its stamina does not. Turn them off with
hunger_enabled = falseandthirst_enabled = falseunder[ultima.regeneration]; the same section sets the regeneration rates. - New for the staff:
add <template>,removeon an item lying on the ground,set <hits|mana|stamina|hunger|thirst> <value>. New in the console: TAB completion of commands and arguments, and the history with Up and Down. - New for scripts:
mobile.animatewith named animations,mobile.body_type,mobile.hunger,mobile.thirst,mobile.message_cliloc,npc.home,npc.wander,npc.can_see,npc.players_in_sight,item.in_range, the sharedscripts/common/teleport.lua, and a generated Lua API reference in the documentation.
Features
Section titled “Features”- console: complete command arguments with TAB (68386dd), closes #298
- console: complete commands with TAB and walk the history with Up and Down (99cc385), closes #295
- console: TAB completion and Up/Down history (56e7628)
- console: TAB completion of command arguments (1358379)
- converter: the starting gold, bread and water come from the converter (68f92f1)
- ctl: the UOX3 converter gives a mobile its script (11697ce)
- data: every new character starts with bread and a pitcher of water (4afa9ac)
- docs: dump the Lua modules, functions and enums the server publishes (3ab93c1)
- docs: generated Lua API reference on the site (768e516)
- docs: render the Lua API reference pages from the dump (329349d)
- docs: serve the Lua API reference under /lua/ with its sidebar group (bc0abb0)
- item.in_range and a teleport module the item scripts share (52338fb)
- monster AI for skeletons and zombies, mobile animations, remove for ground items (398afb3)
- npc.home, npc.wander, npc.can_see and npc.players_in_sight (4eab6a6)
- regeneration of hits, mana and stamina, hunger and food (f3a74cb)
- scripts: a monster script that notices players, walks to them and stands guard (aa1baf9)
- scripts: food is eaten, and a staff command sets a mobile’s bars and hunger (f88e10e)
- scripts: item.in_range and a teleport module the item scripts share (8ca924d)
- scripts: play an animation of a mobile from Lua (9a70486)
- scripts: the npc module strolls, knows its home and says what an NPC sees (5e53768)
- scripts: the other undead of the graveyards take the monster script (f9330a2)
- server: a start can add the bundled migrations and apply the pending ones (3401ea6)
- server: a start can add the bundled migrations and apply the pending ones (2f4d00d), closes #310
- server: add puts an item on the ground where a game master targets (0aa0df2)
- server: colour the console log with a Moongate theme (54ecf4b)
- server: hits, mana and stamina come back with time, and players get hungry (5ae4191)
- server: players get thirsty, and drinks quench it (03fd75f)
- server: players get thirsty, and drinks quench it (86316e9), closes #308
- server: remove also takes an item lying on the ground (2db8909)
- spawns: turn off a spawn region whose whole area has no spot (3e34592)
Bug Fixes
Section titled “Bug Fixes”- console: settle the findings of the argument completion review (430ebb1), closes #298
- console: settle the findings of the console completion review (7e79102), closes #295
- ctl: a ModernUO spawner keeps the map it names, not its folder’s (5024754)
- docs: print Lua help text as written and close the review’s findings (4e5d562)
- scripts: settle the findings of the item helpers review (4710a01)
- scripts: settle the findings of the monster script review (c811d18)
- scripts: settle the findings of the npc helpers review (0276fe3)
- scripts: settle the findings of the thirst review (ba154fd), closes #308
- server: settle the findings of the auto-apply review (c6da5a4), closes #310
- server: settle the findings of the regeneration review (02f5dc4)
- server: settle the minors of regeneration and hunger (d915ee7)
- spawns: never put a spawn region’s fixed ceiling below the ground (a3348d3)
Reverts
Section titled “Reverts”- spawns: undo the ground floor for a fixed spawn ceiling (26b78a6)
0.13.0 (2026-10-03)
Section titled “0.13.0 (2026-10-03)”Upgrade notes
Section titled “Upgrade notes”- Three new world migrations,
0012_mobile_flags.sql,0013_world_state.sqland0014_world_state_one_row.sql: runmgctl migrate apply --root-directory <root> --target worldbefore starting the server, which refuses to start while migrations are pending. - Run
mgctl initagain on an existing root to add the new data (locations.toml), templates (the treasure chests and their spawn regions, the town container tables, the go gump) and scripts (clock.lua,fillable.lua,gumps/go.lua); existing files are preserved, so adoor.luayou changed keeps closing with the old timer, which a restart loses. - Then run
.decorateonce as an administrator to place the town containers and the clocks, and.initial_spawnto fill the treasure chest regions. - A door saved open by 0.12.0 has no timer and stays open until someone uses it.
- New optional
[ultima.world]settings start with their defaults:pathfinding_rangeandpathfinding_max_nodes. - New in the world: the go gump with named places, treasure chests, town containers that fill, clocks, NPCs that walk around obstacles. New for scripts: a mobile’s stats, skills and flags, shard props, item events that refuse, item timers, the text prompt. Combat, death, skill use and gain are not yet available.
Features
Section titled “Features”- A* pathfinding service (9a0f7d2)
- ctl: convert the named places of ModernUO into locations.toml (438b317)
- ctl: convert the treasure chests of ModernUO’s spawners (c32184e)
- data: the content tables of the town containers (626cbec)
- data: treasure chests hold piles as ModernUO’s (b7b65f0)
- go gump of the named places and travel by name (3774a04)
- ground items block movement, closed doors among them (730018e)
- item scripts can refuse a lift, a drop, an equip and an insert (41a2693)
- mobile flags, war mode and shard props from Lua (3ca3e33)
- moongates: make the moongates glow (f3455e6)
- more Lua modules and functions over the existing services (b68ffbe)
- NPCs walk a path from Lua (npc.walk_to, npc.find_path) (b29ec84)
- read and write a mobile’s stats and skills from Lua (roadmap 0.1, slice 1) (d27ec4c)
- respawning treasure chests in dungeons (slice 1) (45ceb95)
- saved item timers, item.equip, item.find and the text prompt from Lua (669614b)
- scripts: an item script can refuse to be lifted, dropped, worn or filled (e57cf83)
- scripts: ask a player for a line of text from Lua (b08008a)
- scripts: keep shard-wide props across restarts (fd9a61f)
- scripts: list the mobiles around an NPC (0f17b8d)
- scripts: make, change and move items from Lua (e21c2df)
- scripts: put an item on a mobile and find items by template from Lua (fd2d45f)
- scripts: read and write a mobile’s stats and skills from Lua (b759d98)
- scripts: read mobiles and the world from Lua (f85c02e)
- scripts: region change event and NPCs stepping on items (e685e9f)
- scripts: spawn, delete and turn NPCs from Lua (679e02c)
- scripts: target cursor from Lua (486d5a3)
- scripts: the real time, an NPC’s template and loot rolled into a container (94a3dc5)
- scripts: timers an item keeps across restarts (382072a)
- scripts: town containers fill up when they are opened (21fc0b5)
- scripts: walk an NPC along a path from Lua (74cd8e9)
- server: a mobile can be hidden, frozen and in war mode (4ae1d9e)
- server: A* pathfinding service (ea10749)
- server: change a mobile’s numbers, skills, name and looks and tell the clients (892748e)
- server: clocks tell the time and the staff sees the blockers (a710927)
- server: decorate places the town containers as fillable (0c27ab2)
- server: find the ground items of a cell without searching its sector (03852c0)
- server: go gump of the named places and travel by name (b5c8d99)
- server: go reads a place written with slashes (5f13f8b)
- server: ground items block movement, closed doors among them (a257af4)
- server: hidden mobiles leave the players’ screens, war mode is answered, flags from Lua (2b70e4e)
- server: item templates can hold loot and gold (ccf5ede)
- server: items go into a container on the ground and those around see it (a11f5f7)
- server: keep the path each NPC walks (cbf1e56)
- server: load the named places and keep them as a tree (5a08d13)
- server: piles merge inside a container on the ground; chest scrolls of ModernUO’s circles (0673448)
- server: register and document the pathfinding service (c1e86e5)
- server: spawn an item on the ground with its gold and loot (c2ae8f3)
- server: spawn regions can spawn items on the ground (f67b58c)
- server: treasure chest templates that decay though fixed (36aeb09)
- server: wait ten seconds before searching again a path that was not found (0e0c28b)
- town containers that fill up (slice 2) (47bd992)
Bug Fixes
Section titled “Bug Fixes”- ci: take the workspace back before the image jobs check out (236dcf5)
- scripts: settle the findings of the fillable containers review (843a999)
- scripts: settle the findings of the Lua modules review (a2b35ae)
- scripts: settle the findings of the refusing events review (9c660a7)
- scripts: settle the findings of the timers and prompt review (7d290dd)
- scripts: settle the minor findings of the timers and prompt review (0dc4a33)
- scripts: settle the minors of the fillable containers (a0272e5)
- server: a character does not bring back an item the world moved on from (58d0e6f)
- server: do not leave an empty chest row and say when a region finds no spot (bd4a715)
- server: go gump says when a place is refused and cuts long texts (45d24a6)
- server: settle the findings of the chest minors review (0597819)
- server: settle the findings of the go gump review (5b5d50f)
- server: settle the findings of the items-block-movement review (44415a1)
- server: settle the findings of the mobile flags review (98a0dbd)
- server: settle the findings of the mobile state review (5d7f31e)
- server: settle the findings of the pathfinding review (4a7fa49)
- server: settle the findings of the treasure chests review (6be6457)
- server: settle the findings of the walk_to review (98c64ce)
- server: settle the minor findings of the mobile flags review (eaf16c1)
- server: settle the minor findings of the refusing events review (4f1baf9)
- server: spawned items keep to their own cells and are counted without a scan (fe24cfc)
- server: the spawn texts no longer say NPCs for a region of items (c71a577)
- settle the minors of the treasure chests (27a1602)
Performance Improvements
Section titled “Performance Improvements”- index the contents of containers (d4f37ef)
- server: find what a mobile owns through the indexes (5d2570f)
- server: index the contents of containers (d0cb264)
0.12.0 (2026-10-02)
Section titled “0.12.0 (2026-10-02)”Upgrade notes
Section titled “Upgrade notes”- One new world migration,
0011_item_grid_index.sql: runmgctl migrate apply --root-directory <root> --target worldbefore starting the server. - The tools are now one:
mgboot <root>ismgctl init <root>, the migration runner ismgctl migrateandmg-uoxconvismgctl convert. The server executable is namedmgserver; the Linux installer keeps themoongatecommand. - New optional settings start with their defaults:
[sql_backup](off),network.enable_ping_serverandnetwork.ping_port(a UDP ping server on port 12000, on by default). - Run
mgctl initagain on an existing root to add the new data (moongates.toml, the messages of each language as a directory), templates (teleporters, signs, gumps, the bank box, the moongate) and scripts; existing files are preserved. Then run.decorateonce as an administrator to place the teleporters, the signs, the town doors and the public moongates. - New in the world: gumps from XML and Lua, teleporters and moongates, the bank, seasons, moon phases, region music and graphic effects. Combat, pathfinding AI, death and skill gain are not yet available.
Features
Section titled “Features”- automatic rotating SQL backups and the sql_backup command (23608e2)
- bank: add the bank box and the service that opens it (e08ef2e)
- bank: bank box opened by the bankers’ bank keyword (43b22df)
- bank: keep bank contents out of reach while the bank is closed (2bb7652)
- bank: open the bank box from Lua and from the bankers (eb3f1eb)
- boot: migrations and converters inside mgboot (0a8dd2e)
- clock: add the moon phases and show them in .time (5c63cd1)
- commands: add .go to take a game master to a place (56fdd53)
- commands: add .gump to open a gump of templates/gumps on yourself (5a53a67)
- commands: add .music to show or try the region music (03d9127)
- commands: add .time to show the game time where you stand (436836a)
- console: add console lock to lock the console input again (c580c58)
- console: console lock and GitHub-ready exception reports (f04e22f)
- converter: add modernuo-spawns to convert ModernUO spawners (07bd014)
- converter: convert ModernUO’s teleporters.json into decoration files (1552887)
- data: log the total time of the data loaders (20161d8)
- data: ship ModernUO’s world and dungeon teleporters (5f1cf99)
- decorations: generate the town doors from the map’s door frames (60aa7ca), closes #238
- decorations: place the shop and world signs of ModernUO (e6e55b1), closes #238
- decorations: town doors and shop signs with .decorate (8dea7fb)
- effects: graphic effects with packets, service, Lua module and named enums (bcda5a3)
- effects: graphic effects with packets, service, Lua module and named enums (e309cc0), closes #247
- gumps: add the gump packets (9f082ff)
- gumps: ask before decorating with a gump of templates/gumps (bbdf893)
- gumps: build gump layouts with their string table (95ad693)
- gumps: build gumps from Lua and fill XML slots (fcea41a)
- gumps: chain gumps with bind and open (a41ea23)
- gumps: gump core with checked answers (902cee0)
- gumps: gumps built in Lua, slots, chained gumps and a tutorial (59e535e)
- gumps: hand the gump answers to the gump service (7213c95)
- gumps: load XML gumps checked against gump.xsd (53c8dc6)
- gumps: open gumps on players and check their answers (ff34dd2)
- gumps: open XML gumps from Lua and call their scripts (45a9e71)
- gumps: ship the tutorial gumps (a1c5bd5)
- gumps: tell a gump when the server closes it, and harden the layout (dd9af68)
- gumps: turn an XML gump into a layout for one opening (e7db8d0)
- gumps: XML gumps checked by an XSD, with Lua scripts (f95ef34)
- import ModernUO’s world and dungeon teleporters (d2b000f)
- items: container grid slots for the Enhanced Client (b9df717)
- items: find an item’s worn root and keep the bank out of sight (c62396f)
- items: give every item in a container a grid slot for the Enhanced Client (e7bb03a), closes #239
- localization: load a language’s messages from a directory of toml files (d06c08a)
- localization: load a language’s messages from a directory of toml files (ed6425c), closes #221
- logging: show only the message and the report of an exception on the console (9aaf34d)
- logging: write GitHub-ready reports of logged exceptions (6f14e39)
- moongates: add the plain moongate item with one destination (b0d6076), closes #262
- moongates: plain moongate item with one destination (882a6d4)
- moongates: public moongates with a destination gump (2f6d939)
- moongates: public moongates with a destination gump (2a98a5a), closes #255
- name the server executable mgserver (b791277)
- network: answer UDP pings on port 12000 (bc1dd2b)
- network: answer UDP pings on port 12000 (a86734a), closes #232
- one tool, mgctl, for root setup, migrations and converters (b27aa9b)
- persistence: export a database’s data as a COPY script (2c68362), closes #242
- persistence: expose the data export on the persistence service (0c548d1), closes #242
- scripting: add the player_say script event (f194c2d)
- scripting: add world.moon for the moon phases in Lua (eb05e77)
- scripting: call a function value a script handed to the host (a361f5f)
- scripts: add run_server.sh to publish a release into dist and start it (ab5a8a0)
- scripts: pass the other options of run_server.sh straight to the server (ae4b2ff)
- scripts: teleporter item script and the mobile Lua module (108fe25)
- seasons: add .season to show or set a map’s season (4c5c6b6)
- seasons: count game days and add the season rotation settings (4384f85)
- seasons: follow each player’s season and send it with light and weather (e58d011)
- seasons: read a region season and inherit it from the parents (134791e)
- seasons: region seasons, optional rotation and .season (8dbc994)
- server: add the SQL backup service with schedule and rotation (db5b3e1), closes #242
- server: add the sql_backup command and register the backup service (d6c7ec1), closes #242
- server: add the sql_backup configuration section (8ebc696), closes #242
- server: move a mobile to any spot of its map (5fe3c37)
- server: name the server executable mgserver (5f87900)
- server: place the teleporters of the decoration files (9e24be9)
- server: show hidden ground items only to the accounts that see them (7505971)
- server: teleport a mobile on its map (61fbc07)
- server: teleport a mobile to another map (c7ebab2)
- server: tell the scripted items a player steps on (3086d74)
- spawns: add .initial_spawn to fill the whole world at the next check (4065e9e)
- spawns: fill each region to its max at its first spawn after the start (f2a58da)
- spawns: Malas, Tokuno and TerMur spawns from ModernUO (cc650c2)
- spawns: populate Malas, Tokuno and TerMur from ModernUO (49218e1)
- spawns: populate New Haven with ModernUO’s spawn points (4122822)
- spawns: show how full the world is in the spawn summary (882085a)
- speech: pass the client’s speech keywords to on_speech (1ef398a)
- TAB completion for mgctl (e789e31)
- teleporters across maps (9f0e090)
- teleporters: teleporters that answer a word (97e4784)
- teleporters: teleporters that answer a word (e134240), closes #252
- tools: rename mgboot to mgctl and ship it as the only tool (0b20840)
- tools: TAB completion for mgctl (acb551d)
- walk-on teleporters on the same map (abc2395)
- weather: resend a player’s weather on request (49ba3a9)
- world: play the music of the region a player is in (532bdae)
- world: region music (4620588)
Bug Fixes
Section titled “Bug Fixes”- bank: settle the important findings of the bank review (83ed754)
- bank: settle the minor findings of the bank review (2620e31)
- build: clear the analyzer warnings of the Release build (8b4eb3f)
- characters: bring a created character into the world (4af97f4)
- characters: bring a created character into the world (57baecd), closes #236
- characters: settle the findings of the create and enter world review (7ac0aaf), closes #236
- ci: let git see the workspace when checking the third-party notices (214062b)
- converter: settle the important findings of the modernuo-spawns review (059ff79)
- data: log the data loader times in milliseconds (a24ea17)
- decorations: keep generated doors out of doorways an item closes (0b62a47), closes #238
- effects: settle the findings of the effects review (88fbc07), closes #247
- gumps: check gump files more closely and warn about missing on_click functions (b91c99b)
- gumps: escape and tidy gump texts, and keep the open gumps consistent (e0abca3)
- gumps: open slot gumps from scripts and check built gumps like files (9ab08e9)
- gumps: refuse namespaced gump files, bound the ids, and never wait on a closed session (3781acb)
- gumps: settle the minor findings of the gump review (b8ed55f)
- gumps: write layouts the client can read on every host and client (6fe82be)
- items: settle the findings of the container grid review (0ddb4f6), closes #239
- localization: settle the minor findings of the messages directory review (10b3f0c), closes #221
- logging: settle the review findings and test the logger end to end (e991a38)
- login: accept the hardware information the Enhanced Client sends at login (52f0e5f)
- moongates: settle the findings of the moongate item review (6db15a7), closes #262
- moongates: settle the findings of the public moongates review (0be02a0), closes #255
- music: inherit parent music and play .music on the game loop (aa07c0c)
- music: settle the minor findings of the region music review (9ef07ac)
- network: settle the findings of the ping server review (96b150d), closes #232
- network: settle the minor findings of the ping server review (0dc2e38)
- network: stop the listener without reporting a transport failure (6662c41)
- packets: accept the character profile request of the Enhanced Client (3aa1985)
- packets: hold a login burst of packets instead of disconnecting the client (c5220e6)
- persistence: declare the account API access default the shipped SQL sets (4336fb3)
- persistence: leave table and column comments out of the schema comparison (dd50bab), closes #231
- persistence: settle the findings of the save-diff review (4cbf228)
- persistence: settle the findings of the SQL backup review (a86d88c), closes #242
- scripts: export MOONGATE_ROOT in run_server.sh (1c4bfef)
- scripts: publish run_server.sh’s build into a clean dist (dcac661)
- seasons: settle the important findings of the seasons review (f21cf8b)
- server: settle the findings of the map change review (43321d7)
- server: settle the findings of the mgserver review (a3b24b2)
- server: settle the findings of the teleporter import review (31f7e47)
- server: settle the findings of the teleporters review (4224ce3)
- server: settle the minor findings of the SQL backup review (bac30d9), closes #242
- settle the code findings of the documentation audit (80a3740)
- settle the minor findings of the teleporter reviews (cfaec26)
- speech: read the unicode speech of any client instead of disconnecting it (1db662f)
- teleporters: settle the findings of the keyword teleporter review (1a45227), closes #252
- tools: settle the findings of the completion review (6981b76)
- tools: settle the findings of the mgctl review (9c892ed)
Performance Improvements
Section titled “Performance Improvements”- localization: count the values of a message without throwing exceptions (4bf83e0)
- persistence: write only the snapshots that changed in a world save (9605976)
- persistence: write only the snapshots that changed in a world save (3622c21)
0.11.0 (2026-09-30)
Section titled “0.11.0 (2026-09-30)”Upgrade notes
Section titled “Upgrade notes”- No new database migrations.
- New optional
[ultima.world]settings for the game clock and the light (seconds_per_uo_minute,day_light,night_light,dungeon_light,jail_light,lamp_post_light) start with their defaults; nothing to change. - Run
mgbootagain to add the new data (regions, weather), templates (world decoration, NPC lists, spawn regions, mobiles withmovement) and scripts (door.lua,light.lua, the updatedwander.lua); existing files are preserved. Then run.decorateonce as an administrator to place the world decoration. - The world fills itself with NPCs from the spawn regions over the first minutes; days and nights pass, dungeons are dark and regions have their weather. Combat, pathfinding AI, death and skill gain are not yet available.
Features
Section titled “Features”- commands: add .spawns to list the spawn regions where you stand (566cd21)
- commands: add fame and karma for game masters (dd33911)
- commands: add the decorate command (e9e69a9)
- commands: add the globallight command (ae4dd20)
- commands: add the lock and unlock commands (3675634)
- commands: add the weather command (7296108)
- commands: give doors key numbers and make their keys (43390b3)
- commands: print the region of the targeted spot in where (18479bb)
- converter: carry UOX3’s light script over as script_id light (70dc1da)
- converter: convert UOX3 npc lists and spawn regions (90b308c)
- decorations: add New Haven’s decoration from ServUO (2339d34)
- decorations: add the decoration and decoration_door item templates (7920cab)
- decorations: convert ModernUO’s world decoration into TOML (439556f), closes #193
- decorations: place the decoration files in the world (27f8753)
- decorations: place the lights with the light template (8ed4b7e)
- decorations: place the world decoration with .decorate and open doors from Lua (470e53d)
- decorations: read the decoration files on demand (ebefb54)
- decorations: world decoration data converted from ModernUO (4581ec7)
- doors: keep locked doors shut for players (b2940de)
- doors: open a locked door with its key (9877296)
- items: add the ground item decay queue (b807adc), closes #191
- items: delete the ground items whose decay time has passed (454cd40), closes #191
- items: ground items decay (966b89b)
- items: keep the decay queue up to date with the ground items (a460a3d), closes #191
- items: let item scripts change, move and sound an item (806577f), closes #195
- items: lights you can light and douse from Lua (37563ad)
- items: send the light shape of a light source (1d6affe)
- movement: find where a mobile can be placed at a cell (29a0847)
- movement: let a mobile template say where its mobiles move (8adb606)
- npcs: keep the spawned NPCs of wander.lua in their home area (2e79f54)
- npcs: let mobile scripts play a sound (6daaf5b)
- npcs: let water and amphibious NPCs swim (407019f)
- npcs: play a mobile’s template sounds by kind (d9a00c3)
- packets: add the weather packet (a4a261c)
- paperdoll: show the fame and karma title in the paperdoll (afdbb4b)
- regions: find the region of a place (dd19409)
- regions: follow the region each player stands in (39da79c)
- regions: know which region a player is in (aa8cb53)
- regions: tell listeners when a player changes region (2f20298)
- scripts: add the world module and a door-like integration test (20b121b), closes #195
- scripts: bring Orione and Vega, the cats of Moongate v2 (7fd14e6)
- scripts: let scripts keep values on NPCs and items across restarts (a724f77)
- scripts: let scripts read the time of day (50070fa)
- scripts: let scripts set an item’s light and ask whether a player is staff (729b3e2)
- scripts: light and douse the lights from Lua (1b2519d)
- scripts: Lua APIs to change, move and sound items (2bc4608)
- scripts: open and close the decoration doors from Lua (b17befb)
- scripts: Orione speaks English (9ab34ea)
- scripts: Vega remembers how many times you said hello (af096fc)
- scripts: Vega speaks English (b0ef77a)
- spawns: convert and load the UOX3 spawn regions (3124837)
- spawns: load the npc lists and the spawn regions (c851dc8)
- spawns: show retrying regions in .spawns and keep .spawn from putting swimmers on land (405522e)
- spawns: spawn the NPCs of the spawn regions at runtime (71d60d3)
- spawns: spawn the NPCs of the spawn regions at runtime (d0f6523)
- spawns: spawn water and amphibious mobiles on the water (9ae503d)
- templates: bring Lilly, the noble lady of Moongate v2 (8259870)
- weather: region weather with thunder and the in-building check (cc83090)
- weather: roll the weather of a profile (9aa50aa)
- weather: send the players the weather of their region (fa41203)
- world: add the day and night light cycle (55822f1)
- world: add the game clock and the light cycle settings (8454fcd)
- world: dark dungeons and dim jails (94458a5)
- world: light the town lamp posts at night (6a4faff)
- world: log at debug what a player is sent on entering a sector (b27f3af)
- world: make dungeons dark and jails dim (d1d8a16)
- world: send the players the light of their time of day (dd38f9e)
Bug Fixes
Section titled “Bug Fixes”- converter: convert spawn regions as UOX3 loads them (9cf6b93)
- converter: keep a GET child with a land body from inheriting water movement (edbf3ec)
- decorations: keep open doors, saved items and a running decoration from doubling the world (84acb6b)
- items: delete a decayed dropped item with its dropper’s save and honour an immovable template (f219b18), closes #191
- items: refuse to move an item outside its map (532d897), closes #195
- movement: refuse water under the ground’s centre as a swim spot (a84237f)
- paperdoll: do not add Lord or Lady twice (10ff181)
- scripts: keep whole numbers of script props as long and give doors their closed spot (7e6cf93)
- spawns: keep only_outside regions from spawning swimmers under a roof (dce0759)
- spawns: place swimmers only on real water and keep a call going past a missed pick (e2e204b)
- spawns: register the spawn service once and make the spawns survive failures and shutdown (17eca2f)
- weather: handle logins on the game loop and resend the weather (aa9e621)
- world: light the plain regions inside a dungeon as the dungeon (5aa14fb)
- world: send the light cycle only to characters whose login sent their light (a8ca6fd)
0.10.0 (2026-09-29)
Section titled “0.10.0 (2026-09-29)”Upgrade notes
Section titled “Upgrade notes”- Apply the new world database migrations
0007–0010(mobile deletion, slot type, mobile direction, ground item index) before starting the updated server; use the migration guide. - The gameplay settings moved under
[ultima]:[ultima.world],[ultima.characters],[ultima.items],[ultima.starting_items],[ultima.line_of_sight],[ultima.localization]and the new[ultima.npcs]. The old top-level sections are no longer read; move their values. The starting gold is an item of the common set instarting_items.toml, not a setting. Missing plugin sections are appended tomoongate.tomlwith their defaults at the first start. - Run
mgbootagain to add the item, loot and mobile templates and the example scripts that now ship with the server; existing files are preserved. A template a release renamed stays beside its new copy and stops the server on the duplicate id: delete the stale one. - Characters enter a playable world: they walk, see each other, talk, move and wear items, and meet the NPCs a game master spawns; NPCs and items run Lua scripts bound by
script_id. Combat, pathfinding AI, death and skill gain are not yet available.
Features
Section titled “Features”- boot: ship the templates and scripts with the server and mgboot (f14f2c5)
- boot: ship the templates and scripts with the server and mgboot (7eba41d), closes #187
- characters: a deleted character gives up its slot and the limit (a47df44)
- characters: add the deletion request column and delay setting (770c046)
- characters: enter the world with the chosen character (5dd63a2)
- characters: handle the delete character packet (f48f10d)
- characters: list and restore pending deletions from the console (a7b88f9)
- characters: load a character and its worn items for play (9bcd9cd)
- characters: load the backpack contents and keep them live in the world (0472feb)
- characters: publish character_entered_world (42e6f03)
- characters: request, list and restore character deletions (9d314d0)
- characters: save the character and publish character_left_world when the player leaves (942d4f7)
- commands: add .spawn and .remove for NPCs (3892f3c), closes #153
- commands: add .where to show what a target cursor picks (5232fab), closes #151
- commands: add graceful shutdown with optional delay (e49379e)
- commands: add world save and broadcast commands (54e9f78)
- commands: include elapsed time in world save messages (3f5c156)
- commands: translate the dispatcher replies, help and descriptions (51c9204), closes #173
- commands: translate the in-game command texts (c3a053f), closes #173
- config: group the gameplay settings under [ultima] (0d2545c)
- config: group the gameplay settings under [ultima] (8426ec5), closes #157
- config: register the parsed config for plugins (e5a6977), closes #159
- docs: add interactive packet reference (4938292)
- entities: mobile display name with its title (3312237), closes #127
- entities: readable ToString for items and mobiles, and an item display name (004b579), closes #127
- items: add the 0x1A and 0xF3 world item packets (9df7dae), closes #149
- items: add the item Lua module (5684d5a), closes #181
- items: add the rules for reaching and dropping on the ground (15b9092), closes #149
- items: decide where an item is worn and whether it fits (8de3a98), closes #165
- items: drop a held item into the player’s own containers (24a57ae)
- items: drop items on the ground and see them in range (8befabd)
- items: item scripts with on_use and the item module (b790fc7)
- items: keep a pool of reserved item serials (7a913ea)
- items: keep ground items aligned with the sector grid (c682963), closes #149
- items: keep the items of the characters in the world live (16ffe45)
- items: lift a whole item from the player’s own containers (3c0f830)
- items: lift, drop and merge items on the ground (1ac58aa), closes #149
- items: load and run the item scripts (c49f080), closes #181
- items: load the items on the ground at startup (2af29f2), closes #149
- items: mark two-handed weapons in item templates (6ba4993), closes #165
- items: on_equip and on_unequip for item scripts (fc6d7ac)
- items: on_pickup, on_drop and on_create for item scripts (4ab3615)
- items: open the player’s own containers with a double click (35498a1)
- items: run on_create of the items of a spawned NPC (32d546d), closes #185
- items: run on_equip and on_unequip of item scripts (bfdd727), closes #183
- items: run on_pickup and on_drop of item scripts (3dfaa1d), closes #185
- items: run on_use on double click (56ee90a), closes #181
- items: save the character’s items when it leaves and in the world save (19a2d74)
- items: show worn item changes to players in range (eff5e2b), closes #165
- items: split a stack when lifting part of it and merge stacks on drop (245bff4)
- items: split and absorb live items with tombstones for the save (c6f4373)
- localization: add the command texts in every language (03b0040), closes #173
- localization: translate the in-game command texts (63db66f)
- localization: translate the item rarities in every language (d6aad07)
- mgboot: show shared banner during root setup (b2815e2)
- mgboot: show shared banner during root setup (d93aa14)
- mobiles: add the mobile service with virtual serials for hair and beard (51fdf96)
- mobiles: delete mobiles through the world save (620f979), closes #153
- mobiles: keep the characters in the world live and move them (a70af3f)
- mobiles: keep the direction a mobile faces and take detached snapshots (8abdfc6)
- motd: add extensible variable registry (9598dc2)
- motd: load and validate MOTD templates (7ae76dc)
- motd: render built-in and plugin variables (dccaf75)
- motd: send configurable private welcome messages (b3b0185)
- movement: walk and run with sequence and speed checks (88f09ed)
- npcs: add the [ultima.npcs] sense range (0e17b97), closes #179
- npcs: add the [ultima.npcs] think interval (9f428d3), closes #175
- npcs: add the npc Lua module and overhead speech (356bc14), closes #177
- npcs: add the NPC tick service (036ab93), closes #175
- npcs: call on_spawn of a spawned NPC’s script (a13c7d9), closes #179
- npcs: drive NPC thinks with their mobile scripts (dc3aa36), closes #177
- npcs: let mobile scripts hear the players nearby (37ded83), closes #177
- npcs: let mobile scripts sense the mobiles coming within range (a5828d2), closes #179
- npcs: let npc.step run (6fa0dd8), closes #177
- npcs: load, spawn and remove NPCs in the live world (8924d45), closes #153
- npcs: Lua mobile scripts for NPCs (7ad6f2d)
- npcs: NPC tick for NPCs near players (93d311d)
- npcs: on_spawn and on_mobile_in_range for mobile scripts (5d76357)
- npcs: queue mobile script calls on the game loop (e30d85c), closes #179
- npcs: register the NPC tick and its metrics (4e3f7fe), closes #175
- npcs: ship the scripts directory with a wandering mobile script (16e72d7), closes #177
- npcs: spawn and remove NPCs in the live world (ad2c2e0)
- packets: add the delete character request and its answers (eacc26f)
- packets: add the packets that bring a character into the world (50664e1)
- packets: ignore the packets the client sends while playing (ae0913b)
- packets: open containers with 0x24 and 0x3C and read the used object from 0x06 (e574922)
- packets: read lift and drop requests and add 0x27 and 0x25 (0d64530)
- packets: read move requests and answer them with 0x22 and 0x21 (6a6ed92)
- packets: receive the play character packet (0x5D) (bd75856)
- packets: recognise the client’s first in-world packets and ignore them for now (25daaae)
- paperdoll: dress and undress from the paperdoll (1e233de)
- paperdoll: dress and undress from the paperdoll (a70a374), closes #165
- paperdoll: open the paperdoll on a double click (65852e4)
- paperdoll: open the paperdoll on a double click (0a25927), closes #162
- persistence: delete captured serials in the world save and reserve serials (d6a96c6)
- plugins: let plugins register a config section (4918de2), closes #159
- plugins: let plugins register their own config section (81cabbf)
- scripting: call a function of a global table (24bb7a3), closes #177
- scripts: greet on spawn and call out to players in the wander script (bc35b7f)
- scripts: ship a potion item script (348545a), closes #181
- sectors: wake and put to sleep the NPCs with their sectors (31741ac), closes #175
- sessions: let services react when a game session closes (3d8d9af)
- speech: decode client speech requests (9f0af66)
- speech: local say and in-game dot commands (e1b4239)
- speech: route local speech and in-game commands (0ebc858)
- speech: send Unicode speech messages (fdb582b)
- targeting: add the 0x6C target cursor packets (245bd61), closes #151
- targeting: keep one target per player and hand the result to a callback (c4e4840), closes #151
- targeting: resolve the client’s target response (6a8a17d), closes #151
- targeting: target cursor with typed results (69aff03)
- templates: add the brain of a mobile template (e2c707d), closes #177
- templates: validate the script of an item template (c1aad9f), closes #181
- titles: load fame and karma title table (8ab7780)
- titles: register title lookup and document configuration (79c7d5c)
- titles: resolve fame and karma title prefixes (69ad7c4)
- tooltips: answer tooltip requests and single clicks (b09518a), closes #171
- tooltips: AOS tooltips (0xD6/0xDC) and single click (4cc547e)
- tooltips: build the tooltip of items and mobiles (5193ae2), closes #171
- tooltips: build tooltip lines and their packets (9800867), closes #171
- tooltips: show the common rarity too (ccc338f)
- tooltips: take the tooltip texts from the message files (35f8eca)
- tooltips: tell clients the tooltip revision (0xDC) (3d4d094), closes #171
- world: add the 0x77 mobile moving packet (034e214), closes #145
- world: compute where a dropped item lands (75d217c), closes #149
- world: configurable view range, 0xC8 answer and sector queries (79c1dae)
- world: keep ground items in the sector grid (f8c5e62), closes #149
- world: keep live mobiles in 16x16 sectors per map (4638779), closes #145
- world: keep the sector grid aligned with the live mobiles (8b1f347), closes #145
- world: players see each other through map sectors (23e8502)
- world: show a mobile that comes into the world to the players in range (6d16fbc), closes #153
- world: show ground items to the players in range (dc78eae), closes #149
- world: show logins, steps and logouts to the players in range (0155c17), closes #145
- world: show players in range as they enter, move and leave (f9cf942), closes #145
- world: wake the sectors around players (43e8055)
Bug Fixes
Section titled “Bug Fixes”- bootstrap: resolve the shutdown service before the host runs (1c080ee)
- characters: allow one character per account in the world (bf19a48)
- characters: enter the world on the game loop with the session character (c63faf6)
- characters: keep a pending character’s list position empty instead of moving others into it (4ebc8e1)
- characters: save a leaving character, its items and its merged stacks in one transaction (f4ec945)
- ci: make the unwritable config test hold as root and scope the CI token (294de6e)
- commands: keep test logger constructor internal (32a410c)
- commands: resolve command service through DryIoc (450aaa8)
- commands: show an untranslated description as is (ba56816), closes #173
- config: guard plugin sections from review findings (7c11c0f), closes #159
- config: reserve the old Ultima section names and tidy usings (d9e3400), closes #159
- items: bounce a held item dropped on a paperdoll and never show others’ items (4202f9e)
- items: close the split re-login duplication and the merge loss paths (5463bb1)
- items: leave items held on a cursor alone and tidy the item module (e4bec45), closes #181
- items: queue on_equip and on_unequip after the move (d3c27ce), closes #183
- items: refuse starting amounts above one pile (991e42b)
- items: save what a character leaves on the ground and keep held items off other screens (a8a25b5), closes #149
- motd: stop delivery after resolver cancellation (875e036)
- npcs: keep the server starting with a broken mobile script and own each script’s waits (c1155da), closes #177
- npcs: never ask the wheel for a zero first delay nor throw into the sectors (6363a6e), closes #175
- npcs: run on_spawn before anything else a spawned NPC’s script gets (17440d7), closes #179
- packets: hold packets that arrive while a session’s async handler runs (a51cf69)
- paperdoll: address review findings (9cc3d77), closes #162
- paperdoll: address review findings on held and worn items (9f8aff2), closes #165
- persistence: write unworn items before worn ones (0dd6eec), closes #165
- redis: name the unreachable Redis endpoints without leaking the connection string (75bd78d)
- speech: handle encoded ASCII and protect command logs (2fd3421)
- speech: run in-game commands without holding the session’s packets (013ebb5), closes #151
- targeting: one command at a time per player and the clicked floor of a static (271a3dc), closes #151
- tooltips: address review findings (850e1f6), closes #171
- tooltips: register 0x09, 0xBF and 0xD6 as incoming packets (7b62ea6)
- world: remove an unregistered leaver from observers and stop a login whose session closed (ee3862d), closes #145
Performance Improvements
Section titled “Performance Improvements”0.9.0 (2026-09-27)
Section titled “0.9.0 (2026-09-27)”Upgrade notes
Section titled “Upgrade notes”- Apply the included world database migrations before starting the updated server; use the migration guide.
- Move custom
backpack_templateandgold_templatesettings from[starting_items]to[items]. The old keys are ignored; the shared settings now serve player characters and spawned mobiles. - Run
mgbootagain to add missing root files and compare your edited data with the shipped files; existing files are preserved. - Character creation and saved-character lists are implemented. Character selection, world entry and a playable world are not yet available.
Features
Section titled “Features”- characters: add the characters config section and the mobile slot column (c91340a)
- characters: create and save player characters with their starting items (4a190ea)
- characters: give new characters their backpack, starting items and gold (4b284fd)
- characters: handle the classic and enhanced create-character packets (aa5e6fa)
- characters: list the account’s saved characters at game login (c0eb3e7)
- characters: load starting item sets and their config (a305547)
- characters: publish character_created to Lua scripts (64a294d)
- core: add DiceSpec, a dice-notation field for templates, and its TOML converter (848ccfa)
- core: port the dice notation parser from Moongate v2 (31ade1d)
- items: add ItemQualityType for the quality prop (0840f44)
- items: create items from templates and save them with a real serial (6869274)
- items: give starting items inside a caller’s transaction (ee574da)
- items: pick a container’s layout and a random spot inside it (2563b53)
- loot: load loot tables and roll them into items (7872d68)
- mobiles: create mobiles from templates with every random value rolled once (ada8aab)
- mobiles: give spawned NPCs a backpack with their gold, loot and spare equipment (7a57893)
- mobiles: spawn dressed mobiles in one transaction with spawn events (ce101e0)
- network: configure POL client encryption profiles (4a5b969)
- network: decrypt UO connections before packet framing (6db051e)
- network: merge POL-compatible client encryption (763d4ee), closes #115
- network: port POL login and game stream ciphers (17bdd43)
- network: wire encrypted listeners and startup diagnostics (807ca9d)
- packets: add the 0x53 popup message packet (520527b)
- persistence: add the world mobiles and items tables and register them (7e3e2bc)
- persistence: store NPC fields and props on mobiles (ffb9acd)
- persistence: store the item rarity and an optional loot type (5764d7c)
- scripting: add the events module with on and off (8df6eab)
- scripting: deliver bus events to Lua handlers on the game loop (b7e7186)
- scripting: list registered event names in the Lua definitions (5884f42)
- scripting: register bus events for Lua with AddScriptEvent (8ce9dfb)
- templates: add weight, stack, layer, price, decay, loot type and tags to item templates (b13f061)
- templates: load item templates and resolve base_id at startup (a1a27ae)
- templates: load mobile templates and resolve base_id at startup (e348c5c)
- templates: mark the starting item set every character gets with common = true (2466883)
- templates: serve the item templates and load them with the game server (90fe71f)
- templates: ship UOX3 npcs as mobile templates and all twenty name lists (a0a0f73)
- ultima: add a name service that picks random names from a list (cfb1bd8)
- ultima: add ItemEntity with helpers that keep an item in one place (5782b09)
- ultima: add MobileTemplate with dice stats, appearance, equipment, loot and sounds (96cbb21)
- ultima: add names.toml with the male and female lists and its loader (d1a3b78)
- ultima: add the dice Lua module (3dd8ea3)
- ultima: add the mobile gender and notoriety types and the mobile template parts (05274fe)
- ultima: validate mobile templates, naming the template and field (d8ed3a8)
- uoxconv: add creature sounds to the npc template that sets the body (37824db)
- uoxconv: convert item blocks that inherit their graphic from one parent (afdbff8)
- uoxconv: convert newbie.dfn into starting_items.toml (9867709)
- uoxconv: convert npc equipment, colour lists and loot (1b3166a)
- uoxconv: convert npc stats, combat values, skills, notoriety and tags to dice (d4592be)
- uoxconv: convert UOX3 name lists into names.toml (ed2ce90)
- uoxconv: convert UOX3 npc blocks into mobile templates with base_id inheritance (195e3a8)
- uoxconv: keep field comments and block labels when parsing dfn files (710f7bd)
- uoxconv: merge male and female npc pairs into one random-gender template (44f8d9e)
- uoxconv: read the converted mobiles back and verify every reference and rule (441bab2)
Bug Fixes
Section titled “Bug Fixes”- characters: answer every failed create and login lookup, and read characters without the write gate (3f633d1)
- characters: check the starting gold template stacks at startup (849b549)
- characters: put a new character in the first free slot instead of refusing (5fb3c63)
- ci: accept the encryption NOTICE.md in the Network.Packets package (3bd851c)
- core: exact dice bounds, thread-safe keep rolls and a strict dice parser (7730faf)
- docs: preserve inline coverage marker examples (cbefe46)
- docs: publish without waiting for server CI (173c4f2)
- items: take the tiledata layer only for wearable graphics (cb4cf71)
- loot: roll a nested table as many times as its amount, as UOX3 does (ba1f1ab)
- mobiles: close the small gaps the spawn review left (f20903e)
- mobiles: follow the template defaults and the real event bus when spawning (3285804)
- network: validate complete encrypted login packets (ff19871)
- persistence: give the world tables the comments FreeSql expects (ae1cfe6)
- persistence: move a Serial sequence left below its entity’s range forward (a602bb4), closes #121
- persistence: provision the world schema in the Docker example and require templates (52b3cd4)
- persistence: start a generated Serial sequence at the entity’s declared range (da0d7a8), closes #121
- scripting: keep a Lua event dispatch from faulting the game loop (c4e59eb)
- scripting: warn and count Lua events dropped by a full game loop (c57481d)
- templates: give each child template its own copy of inherited tags (a9b7296)
- uoxconv: convert random NPC picks, fix gender and race slips in UOX3 data (2d47b7e)
- uoxconv: drop base_id when a block gets itself (575bf70)
- uoxconv: follow item aliases for npc equipment and leave differing pair sounds unset (61208d4)
- uoxconv: inline get= targets that have no id of their own (64d36cf)
- uoxconv: keep ids from each block’s own lines (d6d1839)
- uoxconv: leave a blank line after the header of names.toml and starting_items.toml (5e60e00)
- uoxconv: read ids, colours, numbers, empty tags and duplicates as UOX3 does (28a69f2)
Performance Improvements
Section titled “Performance Improvements”- ci: keep disposable PostgreSQL data in memory (1b53afe)
0.8.0 (2026-09-26)
Section titled “0.8.0 (2026-09-26)”Features
Section titled “Features”- boot: ship the shard data files and copy them into the root (f7a7948), closes #111
- config: add the line_of_sight section with max_distance (0e22e83)
- core: write and read every enum in TOML by name (b69527b)
- data: add offensive words to banned_names.toml (4251e44)
- data: add teleport rules to regions (09a2094)
- data: add travel zones as regions (17fd752)
- data: add weather profiles and give every region a weather (a6c6e5f)
- data: name the entries of containers.toml (8572437)
- localization: add server language with UOX3 message files (3e3a452)
- network: add ClientVersion and carry it from login to the game session (6469217)
- persistence: support custom values and collections in JSONB (7ccdccf), closes #108
- scripting: add the localization Lua module (4bd6609)
- server: let plugins register incoming packets and move Ultima packets to the plugin (dcbfeef)
- server: refuse to start when the root is the directory holding the binary (fa8f767), closes #52
- server: send starting cities and character list after game login (e12a5b8)
- templates: add visibility to item templates (fc38295)
- toml: add Point2D and Point3D converters (e39f8ff)
- toml: use corner ranges for rectangle bounds (b057fcd)
- ultima: add character creation rules and client flags (e911325)
- ultima: add HueSpec and load races with their allowed hair and beard styles (22e515f)
- ultima: add ILineOfSightService with POL’s line walk and ModernUO’s rules (78cc30f)
- ultima: add IMapService to read map terrain and statics (f020250)
- ultima: add IMovementService with the average terrain height (0fa15f0)
- ultima: add IMultiService to read multi layouts (4313e65)
- ultima: add ITileDataService to read land and item tiles (798bf5e)
- ultima: add the classic client create character packet (0xF8) (9adf2d5)
- ultima: check a straight step against terrain and statics (c0f861e)
- ultima: check diagonal steps and register IMovementService (59dab92)
- ultima: load banned name words from banned_names.toml (4366754)
- ultima: load body kinds from bodies.toml (2594fdd)
- ultima: load container gumps and add the music track ids (c783e08)
- ultima: load regions from one file per map with explicit rules (4efdd93)
- ultima: load skills and professions from data files (56dca80)
- ultima: load tiledata.mul when the server starts (3fa699c)
- ultima: store character skills as a JSONB list (c7753cb)
- ultima: store position, appearance and stats on CharacterEntity (f3ab926)
Bug Fixes
Section titled “Bug Fixes”- admin: ensure the certificates directory exists (7cb69d8)
- core: make the TOML converter registry safe under concurrent use (2bb430a)
- core: read EnumValueSpec member names as it writes them, never numbers (638dd3a)
- data: list each body once in bodies.toml (d50aba0)
- data: validate starting cities when they load (13d038e)
- persistence: keep DateTime columns in UTC (e5668ca)
- scripting: refuse [ScriptFunction] on static, non-public or generic methods (478bcdc), closes #36
- ultima: check the map bounds first and walk statics without allocating (48705c5)
- ultima: read only the low three bits of a movement direction (51b7b8e)
Performance Improvements
Section titled “Performance Improvements”- docker: streamline publication and reuse build cache (979e1c4)
- tests: add fast suite and consolidate database scenarios (b791048)
0.7.0 (2026-09-24)
Section titled “0.7.0 (2026-09-24)”Features
Section titled “Features”- login and realms: discover game servers through expiring Redis leases, filter the realm list by account level, and transfer authenticated clients with one-use
0x8C/0x91handoff tickets. - server: run Login, Game or Standalone roles with separate login and game TCP listeners and role-local PostgreSQL databases.
- administration: embed an optional gRPC plugin on port 2590 with server TLS, shared Redis sessions, bounded login throttling, account listing/creation, session revocation and server information. Ship portable protobuf contracts and C#/Python client examples.
- accounts and commands: add account persistence, account listing, console account creation and API-access provisioning, plus command discovery through
help. Administrative API access is disabled for new accounts unless explicitly granted. - boot: ship
mgbootto prepare a root directory, default configuration and bundled migrations offline. Use--generate-admin-certificateto create or reuse a server TLS identity and enable the administration API without starting the server. - packets: register asynchronous packet handlers, perform asynchronous work outside the GameLoop and return game-state changes to its owning thread.
- persistence: assign persistent serials automatically, map convention-based columns to snake_case, and generate reviewable development migrations at startup. Publish persistence readiness and shutdown events.
- events: subscribe to all published events through
SubscribeAll. - templates and tools: add item/loot template contracts, typed value specifications, data-loader registration and UOX3 conversion tooling with validated references and snake_case identifiers.
- deployment: document one Login and two independent Game processes with private Redis, PostgreSQL, Compose secrets and administration TLS.
- Preserve delivered redirect tickets when closing login connections; handle cancellation and terminal packet replies safely.
- Fence realm lease recovery, make heartbeat updates atomic and skip malformed directory entries.
- Coordinate administrative account changes with session revocation, classify dependency failures and complete operation audits.
- Preserve renamed persistence columns, detect default changes and allow indexes on newly created tables.
- Serialize PostgreSQL integration test projects to avoid contention in CI, and verify generated administration clients across languages.
- Normalize nested directory paths and improve item/loot conversion output and validation.
Architecture and operation
Section titled “Architecture and operation”- Redis provides shared realm coordination and temporary login/session state in all runtime roles, including Standalone. PostgreSQL remains the durable store, scoped to Accounts on Login and Realm on Game.
- The internal TCP API and
Moongate.Apipackage are retired. Runtime peers coordinate through Redis; the optional administration endpoint uses standard gRPC with server TLS. - Character selection, live-world editing and a playable world remain outside the implemented feature set. See the implementation-status guide for current limits.
0.6.0 (2026-09-21)
Section titled “0.6.0 (2026-09-21)”Features
Section titled “Features”- add versioned SQL migration catalog and history validation (db87b4a)
- apply PostgreSQL migrations with isolated DbUp runner (6162c53)
- persistence: simplify database config and entity registration (a7e9971)
- ship and document versioned database migration workflow (bd72582)
- validate migrations at startup and generate SQL drafts (c22019e)
Bug Fixes
Section titled “Bug Fixes”- generate third-party notices for migration runner (74530a2)
- preserve migration atomicity and align CLI defaults (c30636f)
Miscellaneous Chores
Section titled “Miscellaneous Chores”- release 0.6.0 (70dbb4d)
0.5.0 (2026-09-20)
Section titled “0.5.0 (2026-09-20)”⚠ BREAKING CHANGES
Section titled “⚠ BREAKING CHANGES”- persistence: replace binary storage with async PostgreSQL facades
Features
Section titled “Features”- api: provision certificates and simplify peer permissions (45ebc45)
- api: provision missing certificates on explicit opt-in (f913862)
- api: support wildcard operation permissions for trusted peers (9366017)
- docker: add login and two-realm Compose example (e2708cb)
- docker: add login and two-realm Compose example (4011906)
- persistence: add PostgreSQL schema foundation (cfc37a2)
- persistence: replace binary storage with async PostgreSQL facades (412e3b5)
- server: integrate PostgreSQL persistence lifecycle and schema commands (ac12088)
Bug Fixes
Section titled “Bug Fixes”- api: allow concurrent public certificate replacement on Windows (a2c91b5)
- docker: preserve PostgreSQL secret values (3aa5493)
- persistence: drain admitted captures before releasing save coordination (a17ceb8)
- persistence: isolate FreeSql entity mappings (9b8a04d)
- persistence: reject silently unmapped writable properties (b6c47c7)
- server: retain all terminal capture failures during shutdown (5300502)
Miscellaneous Chores
Section titled “Miscellaneous Chores”- release 0.5.0 (edc42a6)
0.4.1 (2026-09-20)
Section titled “0.4.1 (2026-09-20)”Features
Section titled “Features”- api: add opt-in server API configuration (ce4423c)
- api: host the configured internal API server (1bab556)
- api: start configured API listener with the server lifecycle (6672fa6)
- docs: add Starlight documentation and release publication (14987bd)
- docs: add the Starlight documentation website (3b903d5)
- docs: import existing guides and library readmes (b44dceb)
- network: restore standalone span serialization utilities (86bc49f)
- network: restore standalone span serialization utilities (14221a7)
- samples: add a plugin that registers a Lua module, a command and a metric provider (34b3e24)
- scripts: install the released server with one command on Linux (a271384)
Bug Fixes
Section titled “Bug Fixes”- api: reject unusable server certificates before startup (dd9b648)
- docs: preserve imported anchors and responsive images (9f4f7cd)
- docs: serve documentation from the configured custom domain (a519cb5)
- samples: reject undefined tones and keep host assemblies out of the bundle (20952f9)
- samples: report the metric under its local name so the diagnostics service accepts it (b248c25)
- scripts: keep the previous installation when the swap fails (45491fd)
- scripts: tell the truth when an install fails after the files are in place (ee6cded)
Miscellaneous Chores
Section titled “Miscellaneous Chores”- release 0.4.1 (0341165)
0.4.0 (2026-09-19)
Section titled “0.4.0 (2026-09-19)”⚠ BREAKING CHANGES
Section titled “⚠ BREAKING CHANGES”- packets: NetworkSession accepts and exposes INetworkConnection; ISessionService.GetOrCreate now accepts INetworkConnection. Recompile Server.Core consumers and plugins.
Features
Section titled “Features”- api: add a script that generates the private CA and leaf certificates (6ac4ccf)
- api: add authenticated internal request/reply channels (f5de84f)
- api: add versioned MessagePack framing (85b51ab)
- api: authenticate peers with mutual TLS and local policies (155caed)
- api: bound pending calls and outgoing work (0079e14)
- api: dispatch authorized requests with bounded execution (54b4e40)
- api: expose authenticated clients and servers with owned lifecycle (79ec6a2)
- api: merge internal request/reply channel into develop (f5de84f)
- api: register typed operations and freeze handler metadata (d3d2512)
- diagnostics: add AddMetricProvider container extension (97a9498)
- network: own bounded asynchronous connection setup (96583da)
- network: support configured outbound stream preparation (ddca33f)
- network: track role-local connections and owned cleanup (95e9824)
- persistence: add the AddPersistenceEntity registration (f5a87e2)
- persistence: let an entity declare its own collection (62fe55d)
- scripting: add module attributes, engine contracts and registration (3c220c0)
- scripting: add the engine, log and timer modules (1254614)
- scripting: add the Lua script engine service (00b07e8)
- scripting: add the Moongate.Scripting project on LuaCSharp 0.5.6 (1e5a126)
- scripting: bind module functions to Lua by attribute (1c10d51)
- scripting: cap the strings string.rep may build (ec34afc)
- scripting: expose module constants and enums to Lua (f58328f)
- scripting: generate editor definitions from the bound modules (6c47fa4)
- scripting: guard the loop thread and drive LuaCSharp synchronously (97f4c88)
- scripting: load script files and serve require from the scripts directory (79ff657)
- scripting: make the module binder public and document the package (84fa4b8)
- scripting: schedule coroutines on the timer wheel under an instruction budget (d43ab38)
- server: add a script metrics console command (b05035d)
- server: add flags-based server mode configuration (28e9af2)
- server: add flags-based server mode configuration (#4) (2302fb8)
- server: host the Lua script engine (56c4180)
- server: register typed API handlers through the container (6d72508)
Bug Fixes
Section titled “Bug Fixes”- api: report certificate script failures and clean up partial output (9e3eb84)
- api: retain admission until connection work completes (d700e4c)
- network: preserve the actual bound endpoint during drain (ee503f1)
- packets: distinguish requested closure from send failures (0fd415b)
- scripting: annotate enum parameters as enum or string in definitions.lua (789e6a4)
- scripting: annotate varargs as … and make definitions.lua robust to any constant (271d6a4)
- scripting: cancel script timers on shutdown and publish errors from the loop (80b3ad5)
- scripting: close the arithmetic bypass in the string cap and match Lua’s argument errors (960be94)
- scripting: close the sandbox (379a2d4)
- scripting: document the built-in modules and let a running coroutine own what it schedules (817d28e)
- scripting: follow links when containing script paths (7c283fd)
- scripting: give the logged print standard tostring semantics (860785a)
- scripting: import Interfaces.Internal in the engine service (a8a65d9)
- scripting: import Interfaces.Internal in the engine service (22614af)
- scripting: keep a failing reload or wait off the game loop’s fault path (c0b5b25)
- scripting: keep every coroutine failure inside the scheduler and scope the budget per unit (51b2fe1)
- scripting: keep one cancellation source per coroutine so the budget survives wait (e3700f0)
- scripting: let ValueTask.Result rethrow the original exception itself (1532d94)
- scripting: make the instruction budget survive an abort and cover pcall (281b162)
- scripting: name the member when a script constant getter throws (fe83b67)
- scripting: report out-of-range integers as Lua errors and document the binder (e94cc54)
- scripting: route Lua print through the server log (77a91ed)
- scripting: run the engine’s start and stop on the game loop thread (30bb64e)
- scripting: zero-pad control-character escapes in definitions.lua (fba7b33)
- server: validate the scripting section with the server config (0607e30)
Code Refactoring
Section titled “Code Refactoring”- packets: separate connection sends from game sessions (a07e1dc)
0.3.0 (2026-09-18)
Section titled “0.3.0 (2026-09-18)”Features
Section titled “Features”- core: add a packet hex formatter (d02d73d)
- core: read the assembly codename from metadata (abde51e)
- diagnostics: add typed snapshots and process metrics (80ae398)
- diagnostics: collect and publish immutable snapshots (54b8636)
- diagnostics: expose loop timer and session metrics (981504a)
- diagnostics: integrate configurable diagnostic service with bootstrap (c4f6b25)
- print the codename in the startup header, sourced from the Codename (a9da36e)
- register IUltimaDataService with UltimaDataService at priority -10 and (a9da36e)
- release: attach a SHA-256 checksum next to each release tarball. (948c746)
- server: add single-instance startup and the Ultima data service (a9da36e)
- server: write the log file as compact JSON (06395e3)
Bug Fixes
Section titled “Bug Fixes”- docker: copy Moongate.Ultima.csproj in the restore layer. The server has (948c746)
- docker: hold the server root at /data, created and owned by the runtime (6f682e2)
- docker: let the licence into the build context (01780ff)
- give UltimaConfig.UltimaPath a default instead of leaving it null. (a9da36e)
- tests: build the plugin fixtures in the requested configuration (abc6cca)
0.2.0 (2026-09-18)
Section titled “0.2.0 (2026-09-18)”Features
Section titled “Features”- config: load TOML server settings and create defaults (939246b)
- core: add entity primitives and expand utility coverage (0bb77bd)
- core: add runtime utilities and shared buffer infrastructure (e3434c2)
- core: add TOML serialization utilities (63731c3)
- core: default TOML property names to snake_case (e5ced0c)
- core: port geometry primitives from legacy Moongate (4256a4d)
- logging: log service startup and improve console layout (eac6b87)
- network: add bounded pending frame buffer (544faac)
- network: add opcode diagnostics and wire session events (035dc28)
- network: add standalone ping and login packets (0fe330a)
- network: add supported client features packet (a846be3)
- network: expose listener endpoints and scaffold network service (7faecf8)
- network: frame incoming Ultima Online packets (3e0e0fa)
- network: infer packet direction during registration (fdbb70e)
- network: port standalone TCP transport from Moonwell (d9e1f9b)
- network: request listener shutdown when network service stops (f863145)
- packets: add queued replies and initial packet handlers (349d0da)
- packets: log registered packet and handler counts at startup (0be9311)
- packets: register typed handlers and dispatch on the game loop (d51d704)
- persistence: add durable binary collection storage (f048f77)
- persistence: add saving all registered live entities (929dac3)
- persistence: add typed data access and ZLinq queries (103d407)
- persistence: add verified backup and restore (5823827)
- persistence: merge binary persistence into develop (13b88b4)
- persistence: separate world capture from durable writes (6ed72f6)
- plugins: add lifecycle event subscriptions (5cc00c3)
- server-core: add account and command enums with session account type (93990da)
- server-core: add command context and definition metadata (d70ed2d)
- server-core: add command executor contract and deferred registry (0c2063f)
- server: add bootstrap lifecycle and circular buffer coverage (d39f1c0)
- server: add command system service with source and account gates (837e604)
- server: add console host and Docker setup (0ffc583)
- server: add console input loop dispatching operator commands (f8a41ec)
- server: add dedicated game loop with bounded work queue (2ef60c5)
- server: add echo command and register the command system at startup (45b5715)
- server: add fluent bootstrap service registration (88faa8c)
- server: add pinned console prompt service with terminal seam (7c9996d)
- server: add plugins with versioned dependencies (d5fb2df)
- server: add service registration and single-file publishing (6313ba0)
- server: coordinate periodic and final world saves (7431d31)
- server: enable the interactive console prompt at startup (ef392ba)
- server: expose event bus service wrapper (54c2d73)
- server: integrate packet handling with TCP lifecycle (0b8179b)
- server: integrate persistence lifecycle (c9fe6b4)
- server: load plugin bundles before service startup (8203099)
- server: port timer wheel into the game loop (142221c)
- server: register directory configuration and refresh startup banner (d9b2f97)
- server: route serilog console output around the prompt row (4b54821)
- sessions: add separate network and game session models (29b1673)
- sessions: port session registry and register singleton service (3afd670)
- ultima: initialize asset library with SkiaSharp (00c185a)
Bug Fixes
Section titled “Bug Fixes”- ci: let each release asset build fail independently (c05fae0)
- ci: pin release-please to main and build assets from the tagged commit (06de8f8)
- ci: use release-please’s include-v-in-tag instead of tag-format (e2015a4)
- docker: include persistence in cached restore (55ff990)
- game-loop: describe the batch limit accurately in startup logs (7a84ea3)
- network: coordinate TCP listener lifecycle and cleanup (4d5d816)
- network: preserve send failures and drain connection resources (d68e8f3)
- network: reject admitted sends after logical closure (6d96037)
- network: reject empty client version frames (7cd11b7)
- network: reject whitespace versions before game-loop dispatch (876bbd9)
- persistence: close capture and disposal races (ac90bfa)
- persistence: preserve collection cleanup after owner shutdown (7dc2cfd)
- plugins: preserve metadata startup cleanup failures (6adcedd)
- plugins: publish lifecycle tasks before callback reentry (0fe5847)
- server: align persistence lifecycle namespaces (05afb42)
- server: force process termination when shutdown leaves it running (7f811cc)
- server: harden console prompt logging, input faults and row width (2ec598b)
- server: reject network startup after shutdown begins (c3e324b)
- server: reject zero-valued command source and document console authority (7e56727)
- server: stop the prompt writer retrying a failed console write (fb693c0)
- sessions: enforce terminal mutation precedence (3251161)
Performance Improvements
Section titled “Performance Improvements”- network: bound frame buffers and remove redundant receive copies (d839eec)
Reverts
Section titled “Reverts”- server: drop the forced-termination guard (186f55f)
Made with ❤️ by Tom
