Skip to main content

Configuration

ModernUO is self-configuring. On first launch, the server walks you through an interactive setup and generates all required configuration files. After that, settings take effect on the next server restart (unless otherwise noted).

All configuration files live in the Configuration/ folder inside your Distribution directory.

Configuration Files

FilePurpose
modernuo.jsonMain server settings -- listeners, data paths, and all settings key-value pairs
expansion.jsonTarget expansion, enabled maps, and feature/client flags
antimacro.jsonAnti-macro skill gain rules (per-skill toggle, area size, cooldowns)
email-settings.jsonSMTP and crash report email configuration
server-access.jsonProtected accounts that auto-reset to Owner access on login
throttles.jsonPer-packet throttle delays in milliseconds
tip

If you ever want to re-run the first-launch setup wizard, delete modernuo.json and expansion.json, then restart the server.

modernuo.json Structure

The main configuration file has four top-level keys:

{
"assemblyDirectories": ["./Assemblies"],
"dataDirectories": ["/path/to/uo/game/files"],
"listeners": ["0.0.0.0:2593"],
"settings": {
"accountHandler.maxAccountsPerIP": "1",
"autosave.enabled": "true",
"autosave.saveDelay": "00:05:00"
}
}
KeyTypeDescription
assemblyDirectoriesstring arrayDirectories to search for additional plugin assemblies
dataDirectoriesstring arrayPaths to Ultima Online game files (.mul / .uop)
listenersstring arrayIP:port endpoints the server binds to
settingskey-value mapAll configurable settings (string keys and string values)
note

All values in the settings map are stored as strings. The server parses them to the appropriate type (bool, int, TimeSpan, etc.) at startup. Unrecognized keys are silently ignored.

Feature Flags

ModernUO includes a runtime feature flag system for toggling game mechanics without restarting the server. Feature flags are managed by the FeatureFlagManager and stored in the Configuration/FeatureFlags/ directory.

Built-in Flags

These boolean flags are optimized for hot-path checks and are synchronized from UOContent:

Server-level flags (checked in the core engine):

Flag KeyDefaultDescription
player_tradingtrueAllow players to trade items
pvp_combattrueAllow player-vs-player combat
bank_accesstrueAllow bank box access
speedhack_detectionfalseEnable speed-hack detection via movement analysis

Content-level flags (checked in UOContent game logic):

Flag KeyDefaultDescription
vendor_purchasetrueAllow buying from NPC vendors
vendor_selltrueAllow selling to NPC vendors
player_vendorstrueAllow player vendor usage
house_placementtrueAllow placing new houses
boat_placementtrueAllow placing new boats
bulk_orderstrueAllow bulk order deed system
passive_detect_hiddentrueAllow passive detect hidden skill

Additional Blocking

Beyond boolean flags, the feature flag system also supports blocking specific:

  • Gumps -- prevent specific UI dialogs from opening
  • Items -- block use, equip, or container access for specific item types
  • Skills -- disable individual skills with a custom message
  • Spells -- disable individual spells with a custom message

These are managed through in-game admin commands and the feature flag admin gump, and are persisted as JSON files in Configuration/FeatureFlags/.

Settings Reference

The tables below document every setting key available in the settings section of modernuo.json. Default values marked with an expansion name (e.g., Core.AOS) mean the default depends on your configured expansion.

Movement

KeyDefaultDescription
movement.delay.runFoot200Run speed on foot (ms)
movement.delay.runMount100Run speed while mounted (ms)
movement.delay.walkFoot400Walk speed on foot (ms)
movement.delay.walkMount200Walk speed while mounted (ms)
movement.delay.turn0Delay for turning in place (ms)
movement.delay.npcMinIdle15Minimum idle time for NPCs (seconds)
movement.delay.npcMaxIdle25Maximum idle time for NPCs (seconds)

Movement Throttling

The movement throttle system uses RTT-based credit buffering to absorb network jitter while detecting speed hacks through movement rate analysis.

KeyDefaultDescription
movementThrottle.debugLoggingfalseEnable debug logging for movement throttle decisions
movementThrottle.maxCredit200Maximum credit buffer for timing jitter (ms)
movementThrottle.hardQueueLimit10Reject and clear movement queue at this depth
movementThrottle.movementHistorySize20Circular buffer size for rate analysis
movementThrottle.minSamplesForRate8Minimum movements before calculating speed
movementThrottle.suspiciousRateThreshold1.05Flag as suspicious at 5% over expected speed
movementThrottle.definiteRateThreshold1.10Flag as definite hack at 10% over expected speed
note

Most movement throttle settings are auto-tuned and rarely need manual adjustment. The debugLogging flag is useful for diagnosing false positives.

Client Verification

KeyDefaultDescription
clientVerification.enabletrueEnable client version verification
clientVerification.ageLeniency10.00:00:00 (10 days)Grace period for new accounts before enforcing version checks
clientVerification.gameTimeLeniency1.01:00:00Grace period based on game time played
clientVerification.invalidClientResponseKickAction on invalid client: Kick, LenientKick, Annoy, or None
clientVerification.kickDelay00:00:20 (20s)Delay before kicking an invalid client
clientVerification.minRequirednullMinimum allowed client version (e.g., 7.0.0.0)
clientVerification.maxRequirednullMaximum allowed client version
clientVerification.allowedClientTypesClassic | SAAllowed client types bitmask
clientData.clientVersionnullOverride the expected client version

Accounts and Security

KeyDefaultDescription
accountHandler.enableAutoAccountCreationtrueCreate accounts automatically on first login
accountHandler.enablePlayerPasswordCommandfalseAllow players to change password via in-game command
accountHandler.maxAccountsPerIP1Maximum accounts allowed per IP address
accountSecurity.encryptionAlgorithmArgon2Password hashing algorithm (SHA2, PBKDF2, or Argon2)
note

Algorithms below SHA2 (such as MD5, SHA1, None) are rejected at startup. They exist only for automatic password migration from legacy RunUO/ServUO databases.

World Saves

KeyDefaultDescription
world.savePathSavesDirectory for world save files (relative to Distribution)
world.tempSavePathtempTemporary directory during save operations
world.useMultithreadedSavestrueUse background threads for serialization during saves
world.enableAutoRestartfalseAutomatically restart the server after a crash or shutdown
autosave.enabledtrueEnable automatic world saves
autosave.saveDelay00:05:00 (5 min)Interval between automatic saves
autosave.warningDelay00:00:00 (0)Broadcast a warning this long before each save (0 = no warning)

Archives and Backups

KeyDefaultDescription
autoArchive.archiveLocallytrueArchive saves to a local directory
autoArchive.archivePathArchivesDirectory for compressed save archives
autoArchive.backupPathBackupsDirectory for backup copies
autoArchive.compressionLevel3Zstd compression level (1-19)
autoArchive.enableArchivePruningtrueAutomatically prune old archives based on retention policy
autoArchive.verifyArchivestrueVerify archive integrity after creation
autoArchive.retryCount3Number of retries on archive failure
autoArchive.retryDelayMs500Delay between retries (ms)
autoArchive.backupMaxAge30Maximum age of backup files in days
autoArchive.hourlyRetention24Number of hourly archives to keep
autoArchive.dailyRetention30Number of daily archives to keep
autoArchive.monthlyRetention12Number of monthly archives to keep

Crash Guard

KeyDefaultDescription
crashGuard.enabledtrueEnable the crash guard system
crashGuard.saveBackuptrueSave a backup on crash
crashGuard.restartServertrueAttempt to restart after a crash
crashGuard.generateReporttrueGenerate a crash report file

Stats and Stamina

Stat Gain:

KeyDefaultDescription
stats.statMaxCore.LBR ? 125 : 100Maximum value for a single stat
stats.gainChanceMultiplier1.0Multiplier for stat gain chance
stats.primaryStatGainChance0.75Chance to gain in the primary stat
stats.gainDelayCore.ML ? 0.05m : 10mCooldown between stat gain checks
stats.petGainDelay5mCooldown between pet stat gain checks
stats.usePub45StatGainCore.MLUse Publish 45 stat gain system

Stamina System:

KeyDefaultDescription
stamina.cannotRunWhenFatigued!Core.AOSPrevent running at zero stamina
stamina.cannotWalkWhenFatiguedfalsePrevent walking at zero stamina
stamina.stonesPerOverweightLoss25Stones of weight per stamina loss tick
stamina.stonesOverweightAllowance4Extra stones allowed before overweight penalty
stamina.baseOverweightLoss5Base stamina loss per overweight tick
stamina.additionalLossWhenBelow0.10Extra loss rate when stamina is below this fraction
stamina.enableMountStaminatrueEnable stamina drain while mounted
stamina.useMountStaminaOnlyWhenOverloadedCore.SAOnly drain mount stamina when overloaded
stamina.globalEtherealMountStaminaCore.MLApply stamina drain to ethereal mounts

Combat and Systems

KeyDefaultDescription
melee.enableInstaHit!Core.UOREnable instant first melee hit on target switch
spellCasting.disableCastParalyzetruePrevent casting while paralyzed
actionDelayCore.AOS ? 1000 : 500Global action delay in milliseconds
visibleDamageCore.AOSShow damage numbers above targets
insurance.enableCore.AOSEnable the item insurance system

Player Systems

Murder System:

KeyDefaultDescription
murderSystem.shortTermMurderDuration8hDuration of a short-term murder count
murderSystem.longTermMurderDuration40hDuration of a long-term murder count
murderSystem.bountiesEnabled!Core.LBREnable the bounty system
murderSystem.recentlyReportedDelay10mCooldown before a victim can report the same murderer
murderSystem.bountyExpiry14dTime before an uncollected bounty expires

Stealing:

KeyDefaultDescription
stealing.classicMode!Core.AOSUse classic (pre-AOS) stealing mechanics
stealing.suspendOnMurder!Core.AOSSuspend stealing perma-flag on murder
stealing.canStealContainers!Core.AOSAllow stealing entire containers
stealing.maxWeightToSteal10Maximum weight of an item that can be stolen (stones)

Taming:

KeyDefaultDescription
taming.enableBondingCore.LBREnable pet bonding

Game Systems

KeyDefaultDescription
opl.enableCore.AOSEnable Object Property Lists (item tooltips)
opl.enableForVendorBuytrueShow property lists in vendor buy menus
vendor.isInvulnerableCore.LBRMake NPC vendors invulnerable
guards.instantKilltrueGuards instantly kill criminals (vs. fighting them)
factions.enabledfalseEnable the factions system
ethics.enablefalseEnable the ethics (Hero/Evil) system
questSystem.enableMLQuestsCore.MLEnable Mondain's Legacy quest system
vetRewards.enabletrueEnable veteran rewards
vetRewards.skillCapRewardstrueEnable skill cap increase rewards
vetRewards.rewardInterval30dTime between reward tiers
testCenter.enablefalseEnable test center mode (free skills, items, etc.)
chat.enabledfalseEnable the built-in chat system
buffIcons.enableCore.MLEnable buff/debuff icons on the client UI
houseDecay.enabletrueEnable house decay over time
pathfinding.enabletrueEnable NPC pathfinding

Network

KeyDefaultDescription
pingServer.enabledtrueEnable the UDP ping server (used by server browsers)
pingServer.port12000UDP port for the ping server
pingServer.maxConnections2048Maximum queued ping connections
network.encryptionModeBothEncryption mode: None, Login, Game, or Both
network.encryptionDebugfalseEnable debug logging for encryption negotiation
netstate.packetLoggingPathPacketsDirectory for per-client packet logs
uogateway.enabledtrueEnable the UO Gateway protocol
assistants.enableNegotiationfalseEnable Razor-style assistant protocol negotiation

Server Listing

KeyDefaultDescription
serverListing.serverNameModernUOServer name shown in the server list
serverListing.addressnullPublic IP address override for the server list
serverListing.autoDetecttrueAuto-detect public IP via external service

Maps and Client Data

KeyDefaultDescription
maps.enablePre6000TrammelfalseUse pre-client-6000 Trammel map format
maps.enableMapDiffPatchesautoEnable map diff patches
maps.enableStaticsDiffPatchesautoEnable statics diff patches
maps.enablePostHSMultiComponentFormatautoUse post-High Seas multi component format
expansion.forceOldAnimationsfalseForce pre-expansion animation set

Miscellaneous

KeyDefaultDescription
commandsystem.prefix[Command prefix character (e.g., [ for [command)
profanityProtection.enabledfalseEnable profanity filter
profanityProtection.actionDisallowProfanity action: Disallow, Criminal, None
system.localTimeZonesystem defaultOverride the server's time zone (IANA or Windows ID)
pages.discordWebhookUrlnullDiscord webhook URL for GM page notifications
guildClickMessage!Core.AOSShow guild abbreviation on single-click
asciiClickMessage!Core.AOSUse ASCII (not Unicode) for single-click messages
bulletinboards.creationTimeDelay2mCooldown between creating bulletin board threads
bulletinboards.expireDuration6hTime before bulletin board threads expire
bulletinboards.replyDelay30sCooldown between bulletin board replies

Other Configuration Files

expansion.json

Controls which expansion the server emulates and which maps are active.

{
"id": 7,
"name": "Mondain\u0027s Legacy",
"mapSelectionFlags": "Felucca, Trammel, Ilshenar, Malas, Tokuno"
}

The id corresponds to the Expansion enum (0 = None, 1 = T2A, 2 = UOR, 3 = UOTD, 4 = LBR, 5 = AOS, 6 = SE, 7 = ML, 8 = SA, 9 = HS, 10 = TOL, 11 = EJ). The mapSelectionFlags field controls which maps are loaded.

antimacro.json

Configures per-skill anti-macro rules to prevent automated skill gain.

{
"allowance": 3,
"locationSize": 5,
"enabled": true,
"skillTriggers": {
"Anatomy": true,
"AnimalLore": true,
"Blacksmith": false,
"Magery": true
},
"expire": "00:05:00"
}
FieldDescription
allowanceNumber of allowed skill uses per location before throttling
locationSizeTile radius that defines a "location" for anti-macro purposes
enabledMaster toggle for the anti-macro system
skillTriggersPer-skill toggle (true = anti-macro enforced for this skill)
expireHow long before location-based counters reset

email-settings.json

SMTP configuration for crash reports and support emails. Created with defaults on first launch if not present.

{
"enabled": false,
"fromAddress": "[email protected]",
"fromName": "ModernUO Team",
"crashAddress": "[email protected]",
"crashName": "Crash Log",
"speechLogPageAddress": "[email protected]",
"speechLogPageName": "GM Support Conversation",
"emailServer": "smtp.gmail.com",
"emailPort": 465,
"emailUsername": "[email protected]",
"emailPassword": "your-app-password",
"emailSendRetryCount": 5,
"emailSendRetryDelay": 3
}
tip

Set "enabled": true and configure your SMTP credentials to receive crash reports by email. For Gmail, use an App Password.

server-access.json

Defines protected accounts that cannot be permanently locked out. If a protected account is banned or has its access level lowered, it automatically resets to Owner on the next successful login.

{
"protectedAccounts": ["admin", "owner"]
}
note

Account names are case-insensitive. This is a safety net for server owners -- it ensures you can always regain access to your server even if another admin modifies your account.

throttles.json

Maps packet IDs to throttle delays in milliseconds. Packets sent faster than the configured delay are dropped for players (staff is exempt).

{
"0x03": 25,
"0x12": 25,
"0x75": 500,
"0xAD": 25
}
PacketDelayPurpose
0x0325msSpeech
0xAD25msUnicode speech
0x1225msText commands
0x75500msRename request

You can modify throttles at runtime using the [SetThrottle and [GetThrottle admin commands.

Custom Configuration

Developers can create custom JSON configuration files using the JsonConfig utility:

var mySettings = JsonConfig.Deserialize<MySettings>(
Path.Combine(Core.BaseDirectory, "Configuration/my-settings.json")
);

Files are read from the Configuration/ directory and support comments, trailing commas, and all standard JSON converters (enums, TimeSpan, IPEndPoint, etc.) automatically.