Summary
- Adds CLAUDE.md at repo root with 14 terse code audit rules (always loaded, low token cost)
- Adds pointer files for other AI tools: AGENTS.md (Codex), GEMINI.md, .github/COPILOT-INSTRUCTIONS.md (Copilot), .cursorrules (Cursor) — all redirect to CLAUDE.md as single source of truth
- Gitignores /.claude so personal AI config isn't distributed
- Moves Claude skills to dev-docs/claude-skills/ (opt-in, not auto-loaded)
- Adds 14 dev-docs covering codebase conventions
Code Audit Rules (in CLAUDE.md)
1. LINQ tiered rules (Tier 1 free, Tier 2 warm, Tier 3 forbidden)
2. No Console.WriteLine — use LogFactory.GetLogger()
3. No concurrency primitives in game code
4. No World.Mobiles/World.Items iteration
5. Clean up refs in OnDelete()/OnAfterDelete()
6. Cancel timers in OnDelete()/OnAfterDelete()
7. STArrayPool<T>.Shared not ArrayPool<T>.Shared
8. PooledRefList<T> not new List<T>() on hot paths
9. Serialization: partial class, [Constructible], no serialized TimerExecutionToken
10. No Task.Run/new Thread() in game code
11. Never assume era — ask which expansion
12. _camelCase fields, PascalCase properties/methods
13. No empty gumps — use DisplayTo() pattern
14. PropertyList string literals must be {} holes, cliloc-as-argument uses :#
5.5 KiB
5.5 KiB
| name | description |
|---|---|
| modernuo-configuration | Trigger when adding server settings, reading config values, or working with modernuo.json or JsonConfig. |
ModernUO Configuration System
When This Activates
- Adding new server settings
- Reading config values with
ServerConfiguration - Using
JsonConfig.Serialize/Deserialize<T> - Working with
modernuo.jsonor custom config files
Key Rules
- Read settings in
Configure()static method - Use
GetOrUpdateSetting()when you want the setting created with a default if missing - Use
GetSetting()for read-only access (won't write default to file) - Custom config files use
JsonConfig.Serialize/Deserialize<T>() - Config path base:
Distribution/Configuration/
ServerConfiguration
GetOrUpdateSetting (Creates Default If Missing)
// In Configure() method:
var maxAccounts = ServerConfiguration.GetOrUpdateSetting("accountHandler.maxAccountsPerIP", 1);
var saveDelay = ServerConfiguration.GetOrUpdateSetting("autosave.saveDelay", TimeSpan.FromMinutes(5));
var enabled = ServerConfiguration.GetOrUpdateSetting("mySystem.enabled", true);
If the key doesn't exist in modernuo.json, it writes the default value and returns it.
GetSetting (Read-Only)
var statMax = ServerConfiguration.GetSetting("stats.statMax", 100);
var usePub45 = ServerConfiguration.GetSetting("stats.usePub45StatGain", false);
Returns the default if key is missing but does NOT write to the config file.
Supported Types
ServerConfiguration.GetSetting(string key, int defaultValue)
ServerConfiguration.GetSetting(string key, bool defaultValue)
ServerConfiguration.GetSetting(string key, double defaultValue)
ServerConfiguration.GetSetting(string key, TimeSpan defaultValue)
ServerConfiguration.GetSetting<T>(string key, T defaultValue) where T : struct, Enum
SetSetting
ServerConfiguration.SetSetting("mySystem.customValue", "42");
// Immediately persisted to modernuo.json
Configuration Pattern
namespace Server.Custom;
public static class MySystem
{
private static bool _enabled;
private static int _maxItems;
private static TimeSpan _cooldown;
public static void Configure()
{
_enabled = ServerConfiguration.GetOrUpdateSetting("mySystem.enabled", true);
_maxItems = ServerConfiguration.GetOrUpdateSetting("mySystem.maxItems", 100);
_cooldown = ServerConfiguration.GetOrUpdateSetting("mySystem.cooldown", TimeSpan.FromMinutes(5));
}
// System logic uses _enabled, _maxItems, _cooldown...
}
Custom Config Files with JsonConfig
For complex configuration that doesn't fit in modernuo.json:
using Server.Json;
public static class MyComplexSystem
{
private static MyConfig _config;
private static readonly string ConfigPath =
Path.Combine(Core.BaseDirectory, "Configuration/MySystem/config.json");
public static void Configure()
{
_config = JsonConfig.Deserialize<MyConfig>(ConfigPath)
?? new MyConfig();
}
public static void SaveConfig()
{
JsonConfig.Serialize(ConfigPath, _config);
}
}
public class MyConfig
{
public bool Enabled { get; set; } = true;
public int MaxItems { get; set; } = 100;
public List<string> BlockedNames { get; set; } = new();
public Dictionary<string, int> Scores { get; set; } = new();
}
JsonConfig Options
- Pretty-printed (WriteIndented = true)
- Comments allowed (ReadCommentHandling = Skip)
- Trailing commas allowed
- Null values omitted (WhenWritingNull)
- Enums serialized as strings (JsonStringEnumConverter)
- Built-in converters for:
ClientVersion,Guid,Map,Point3D,Rectangle3D,TimeSpan,IPEndPoint,Type,WorldLocation,TextDefinition
modernuo.json Structure
Location: Distribution/Configuration/modernuo.json
{
"assemblyDirectories": ["./Assemblies"],
"dataDirectories": ["C:\\Ultima Online Classic"],
"listeners": ["0.0.0.0:2593"],
"settings": {
"accountHandler.enableAutoAccountCreation": "True",
"accountHandler.maxAccountsPerIP": "1",
"autosave.enabled": "True",
"autosave.saveDelay": "00:05:00",
"world.savePath": "Saves",
"stats.statMax": "100",
"timer.initialPoolCapacity": "1024",
"mySystem.enabled": "True"
}
}
All settings are stored as strings in the settings dictionary.
Naming Convention for Keys
Use dot-separated hierarchical keys:
systemName.settingName
systemName.subSystem.settingName
Examples:
accountHandler.maxAccountsPerIPstats.statMaxmovement.delay.walkFootautosave.saveDelay
Anti-Patterns
- Reading config in constructors: Use
Configure()static method instead - Hardcoding values: Use
ServerConfiguration.GetOrUpdateSetting()for tunable values - Complex objects in modernuo.json: Use
JsonConfigwith separate files instead - Not providing defaults: Always pass a sensible default value
Real Examples
- ServerConfiguration:
Projects/Server/Configuration/ServerConfiguration.cs - JsonConfig:
Projects/Server/Json/JsonConfig.cs - Config usage:
Projects/UOContent/Skills/SkillCheck.cs(Configure method) - Timer pool config:
Projects/Server/Timer/Timer.Pool.cs - Main config:
Distribution/Configuration/modernuo.json
See Also
dev-docs/configuration.md- Complete configuration documentationdev-docs/claude-skills/modernuo-era-expansion.md- Expansion configurationdev-docs/claude-skills/modernuo-events.md- Configure() pattern