Highly Performant & Scalable Ultima Online Server Emulator https://www.modernuo.com
Find a file
Kamron Batman 114dbba6e2
fix: a stop order silently cancelled a standing follow order (#2616)
## The bug

Pet is set to follow. It gets attacked and defends itself (the order flips to `Attack`), or the player tells it to `come`. The player then says `stop`. The pet quietly stops following and starts idle-wandering — the player has to re-issue the order to get it back.

`ResolveStop` clears `ControlTarget`, since the transient order that is ending owns it, and then resumes the standing order. Nothing restores a target, so the resumed `Follow` has none. `DoOrderFollow` checks for a target before anything else, finds none on the very next think, says "I have no one to follow" and cancels the order to `None`:

```
follow standing        order=Follow  target=set  persist=Follow  cur=0.2 => move=0.3
attacked (defends)     order=Attack  target=set  persist=Follow  cur=0.2 => move=0.3
stop issued            order=Follow  target=null persist=Follow  cur=0.2 => move=0.3
  next think           order=None    target=null persist=Follow  cur=0.4 => move=0.9
```

Two things go wrong at once:

- `PersistentOrder` still reads `Follow` while `ControlOrder` is `None`, so the pet never recovers on its own.
- The pace falls from the active clock to the passive one. A shard that tunes `SetMoveSpeed(active, passive)` sees a following pet drop from its active move speed to its passive one for no visible reason — which is how this surfaced.

Era-independent. Guard is unaffected: `DoOrderGuard` works off `ControlMaster`, not `ControlTarget`.

## The fix

A standing `Follow` does not always mean "follow the master" — a pet friend can point it elsewhere with `all follow me` / `*follow me` (0x163, 0x16C) or `*follow` plus a target pick. So `SetPersistentOrder` remembers the target the standing order was given, and `ResumePersistentOrder` restores it, falling back to the master only when that target is gone. The field is runtime-only, like `PersistentOrder` itself.

Doing this in `ResumePersistentOrder` rather than `ResolveStop` also covers the Friend/Unfriend/Transfer resumes, where `ControlTarget` points at a third party and the pet would otherwise have resumed its follow on *them*. It matches what `HandleInvalidControlTarget` already does before its own resume.

## Tests

`Stop_WhileAttacking_FallsBackToPersistentFollow` already existed and passed, because it asserted the resumed order without checking for a target or driving a think tick. Three tests added alongside it:

- `Stop_WhileAttacking_ResumedFollowTargetsTheMaster`
- `Stop_WhileAttacking_ResumedFollowKeepsAPetFriendAsItsTarget` — a friend's follow order is not hijacked back to the owner
- `Stop_WhileAttacking_ResumedFollowSurvivesTheNextThink` — the one that catches the cancellation

Each was confirmed to fail without the change (`Expected: Follow, Actual: None`; wrong target). Full suites green: 782 UOContent, 869 Server.
2026-09-07 08:51:10 -07:00
.config fix: Fixes dirty-tracking gaps in generated content: setters, sub-object owners, BaseVendor (#2609) 2026-09-06 09:43:44 -07:00
.github fix: Require only runtime packages on Linux, and check ICU and tzdata the way the runtime does (#2561) 2026-08-07 15:03:08 -07:00
branding feat(build-tool): add application icon and refresh MUO.ico (#2487) 2026-06-14 11:59:54 -07:00
dev-docs refactor: Changes BaseCreature to the SerializationGenerator (delta save requirement) (#2611) 2026-09-06 14:11:51 -07:00
Distribution/Data feat: Adds independent think/move clocks for creature AI to fix speed (#2591) 2026-08-23 10:19:59 -07:00
Projects fix: a stop order silently cancelled a standing follow order (#2616) 2026-09-07 08:51:10 -07:00
tools feat(network): allowlist false-positive IPs, escalate on behavior (#2556) 2026-07-30 23:12:17 -07:00
.cursorrules chore: Adds AI instructions and SKILLs for ModernUO codebase (#2347) 2026-03-01 11:42:19 -08:00
.editorconfig chore(docs): Adds UnmanagedDataReader & BinaryFileReader documentation (#1968) 2024-10-01 17:07:51 -07:00
.gitattributes fix: Adds migration checks to CICD, updates dependencies, adds Fedora 37, alpine 3.17 support (#1309) 2022-12-22 12:12:47 -08:00
.gitignore perf: Sleep the event loop when idle. Fixes networking micro-stalls. Adds event loop instrumentation. (#2559) 2026-08-09 13:24:59 -07:00
AGENTS.md chore: Adds AI instructions and SKILLs for ModernUO codebase (#2347) 2026-03-01 11:42:19 -08:00
azure-pipelines.yml chore: Cleans workflows for NodeJS 24 (#2394) 2026-03-28 21:55:29 -07:00
CLAUDE.md docs: update serialization docs and skills for generator v4 (#2588) 2026-08-22 18:29:27 -07:00
CODE_OF_CONDUCT.md Create CODE_OF_CONDUCT.md 2020-05-05 08:51:39 -07:00
CONTRIBUTING.md chore(license): Removes CLA requirement. All contributors moving forward will retain copyright. (#2038) 2024-12-31 02:52:58 -08:00
Directory.Build.props feat: Bumps dependencies. Introduces Serialization Generator v3 (#2584) 2026-08-22 15:48:53 -07:00
FAQ.md docs: Updates FAQ for time zone issues. (#1368) 2023-03-10 00:18:36 -08:00
GEMINI.md chore: Adds AI instructions and SKILLs for ModernUO codebase (#2347) 2026-03-01 11:42:19 -08:00
global.json feat: Adds Build Tool for Publishing/Setup (#2392) 2026-03-28 21:21:50 -07:00
LICENSE Fixes more line ending issues (#267) 2020-09-27 13:54:56 -07:00
ModernUO.slnx feat: Adds Build Tool for Publishing/Setup (#2392) 2026-03-28 21:21:50 -07:00
publish.cmd feat: Adds Build Tool for Publishing/Setup (#2392) 2026-03-28 21:21:50 -07:00
publish.ps1 fix: Adds stamp check for build tool versioning (#2400) 2026-04-06 16:18:02 -06:00
publish.sh fix: Adds stamp check for build tool versioning (#2400) 2026-04-06 16:18:02 -06:00
README.md chore: Simplify server requirements section in README (#2582) 2026-08-21 19:22:04 -07:00
rider-settings.zip Cleanup/Housekeeping (#242) 2020-09-12 15:31:21 -07:00
Rules.ruleset chore(docs): Adds UnmanagedDataReader & BinaryFileReader documentation (#1968) 2024-10-01 17:07:51 -07:00
SPONSORS.md chore: Updates readme files (#2247) 2025-07-27 11:04:32 -07:00
stylecop.json Updates formatting rules (#199) 2020-08-25 18:00:51 -07:00
THIRD-PARTY-NOTICES docs: Adds RunUO-Encryption notice attribution to DarkStorm (#2369) 2026-03-12 23:35:47 -07:00
version.json feat: Adds Build Tool for Publishing/Setup (#2392) 2026-03-28 21:21:50 -07:00

ModernUO - Ultima Online Server Emulator for the modern era!

ModernUO Discord Subreddit subscribers Twitter Follow

Ultima Online Server Emulator for the modern era!

GitHub license GitHub stars GitHub issues
GitHub build Azure Pipelines build

Requirements

Supported Operating Systems

Windows 10/11/2012 R2/2016/2019/2022/2025 MacOS 14+ Debian 12+ Ubuntu 22+ LTS
Alpine 3.22+ Fedora 42+ RedHat 9+ CentOS Stream 9+ AlmaLinux 10 openSUSE 15.6+ SUSE Enterprise 15 SP6 Linux Mint 21+ Arch

Required Frameworks

All Operating Systems

.NET

Windows

VC++ Redistributable v14

Hardware

Use vCPU RAM Storage
Development / test 2 dedicated 2 GB SSD
Small live shard (< 50 concurrent) 4 dedicated 4 GB NVMe
Medium (50200) 48 8 GB NVMe
Large (200+) 8+, high clock 16 GB+ NVMe

See dev-docs/server-requirements.md for more information.

Development

git .NET

Supported IDEs

Jetbrains Rider 2025.3+ space VSCode space Visual Studio 2026

Getting Started

  • Install prerequisite requirements
  • Clone this repository (or download the latest):
    • git clone https://github.com/modernuo/ModernUO.git
  • Open ModernUO.sln to start developing

Building/Publishing

Run ./publish.cmd (Windows) or ./publish.sh (Linux/macOS) with no arguments to launch the guided build tool. It will:

  • Check prerequisites (.NET SDK, native libraries)
  • Walk you through configuration and platform selection
  • Build and publish the server to the Distribution directory
  • Show deployment instructions for cross-compiled builds

Command Line

./publish.cmd [release|debug] [os] [arch]

Linux Prerequisites

Fedora, CentOS, RHEL, AlmaLinux, Rocky, etc

dnf upgrade --refresh -y
# RHEL-family distributions (CentOS Stream, AlmaLinux, Rocky, RHEL) need CRB and EPEL enabled.
# Fedora skips this block.
dnf install -y dnf-plugins-core
dnf config-manager --set-enabled crb
dnf install -y epel-release
# Prerequisites
dnf install -y findutils libicu libdeflate libargon2 tzdata

Ubuntu, Debian, etc

apt-get update -y
# The ICU runtime package carries the ABI version in its name (libicu74, libicu76, …) and has no
# stable alias, so match it by pattern rather than pinning a release-specific name.
apt-get install -y '^libicu[0-9]+$' libdeflate0 libargon2-1 tzdata

Only the runtime libraries are needed — the -dev/-devel packages are not. Run ./build-tool --check-prereqs to check the current machine and print the exact packages your release needs.

zstd is not listed because ZstdNet bundles libzstd for every platform, and liburing is not listed because IORingGroup issues io_uring syscalls directly.

If the shard's configured time zone is a legacy alias such as US/Eastern, Debian 12 and Ubuntu 24.04 also need tzdata-legacy. See Platform Prerequisites for what each dependency is for and what breaks without it.

OSX Requirements

brew install icu4c libdeflate argon2

Running the Server

  • Follow the publish instructions
  • The Distribution directory is portable — copy it to your production server for deployment
  • Run ModernUO.exe or dotnet ModernUO.dll from the Distribution directory
  • On first run, the server will prompt you to configure game data file locations

Troubleshooting / FAQ

Want to sponsor?

Thank you for supporting us! You can find out how by visiting the sponsors page.

Collaborators

Kamron Batman Mark1145

Thanks

  • RunUO Team & Community
  • Voxpire, the ServUO Team & Community
  • Karasho, Jaedan and the ClassicUO Community



Development Tools & Plugins provided with ♥ by

JetBrains
Material Theme

Code Signing Policy

Free code signing provided by SignPath.io, certificate by SignPath Foundation.

This program will not transfer any information to other networked systems unless specifically requested by the user or the person installing or operating it

Teams & Roles

Approvers & Committers: Development Team