Kamron Batman
4b392079e9
fix: Fixes exploits with bank box deposits. Makes stacking more efficient ( #2337 )
...
### Summary
- Fix AccountGold gold duplication exploit: When AccountGold.Enabled was true, double-clicking a BankCheck deposited
the full value to the account but then continued creating physical gold piles for the same amount, duplicating the
value
- Fix Deposit/DepositUpTo partial deposit exploit: Both methods created new max-size gold piles and checks without
first filling existing partial stacks, wasting container slots and causing premature "bank full" failures that could
be leveraged to manipulate gold distribution
- Fix BagOfSending bank stacking: Gold and BankCheck items sent via BagOfSending now use Banker.Deposit for efficient
stacking instead of naive TryDropItem, which could fail on a full bank even when existing piles had room
- Improve gold/check deposit efficiency: Banker.Deposit and Banker.DepositUpTo now top off existing gold piles (up to
60k) and bank checks (up to 1M) before creating new items, maximizing use of available container slots
2026-02-13 20:34:35 -08:00
Kamron Batman
7fe9712593
fix: Fixes NPC acquire on being attacked ( #2334 )
2026-02-11 00:49:29 -08:00
Kamron Batman
d625ea5ba4
fix: Fixes punching while pacified ( #2332 )
2026-02-09 14:35:07 -08:00
Kamron Batman
b191498569
feat: Adds Feature Flag System ( #2328 )
...
## Feature Flag System
A runtime feature flag system for dynamically enabling/disabling game systems and blocking specific game elements
without server restarts.
### Overview
Two types of controls:
1. Feature Flags - Named boolean flags that gate entire systems (trading, PvP, vendors, housing, etc.)
2. Dynamic Blocks - Block specific gumps, items, skills, or spells by type
All changes are persisted to JSON, broadcast to online staff, and bypass-able by administrators.
### Predefined Flags
```
┌─────────────────┬──────────┬─────────────────────────────────────┐
│ Flag │ Category │ Description │
├─────────────────┼──────────┼─────────────────────────────────────┤
│ player_trading │ Economy │ Allow secure trades between players │
├─────────────────┼──────────┼─────────────────────────────────────┤
│ vendor_purchase │ Economy │ Allow purchasing from NPC vendors │
├─────────────────┼──────────┼─────────────────────────────────────┤
│ vendor_sell │ Economy │ Allow selling to NPC vendors │
├─────────────────┼──────────┼─────────────────────────────────────┤
│ player_vendors │ Economy │ Allow player vendor interactions │
├─────────────────┼──────────┼─────────────────────────────────────┤
│ bank_access │ Economy │ Allow bank box access │
├─────────────────┼──────────┼─────────────────────────────────────┤
│ house_placement │ Housing │ Allow new house placements │
├─────────────────┼──────────┼─────────────────────────────────────┤
│ boat_placement │ Housing │ Allow new boat placements │
├─────────────────┼──────────┼─────────────────────────────────────┤
│ bulk_orders │ Crafting │ Allow bulk order deeds │
├─────────────────┼──────────┼─────────────────────────────────────┤
│ pvp_combat │ Combat │ Allow player vs player combat │
└─────────────────┴──────────┴─────────────────────────────────────┘
```
### Commands
#### Feature Flags
```
┌────────────────────────────────────────────────────┬───────────────────────┐
│ Command │ Description │
├────────────────────────────────────────────────────┼───────────────────────┤
│ [FeatureFlag <key> on|off|toggle|info │ Manage a feature flag │
├────────────────────────────────────────────────────┼───────────────────────┤
│ [FF <key> on|off │ Shorthand alias │
├────────────────────────────────────────────────────┼───────────────────────┤
│ [FeatureFlag <key> create <category> <desc> │ Create a custom flag │
├────────────────────────────────────────────────────┼───────────────────────┤
│ [FeatureFlag <key> delete │ Delete a custom flag │
├────────────────────────────────────────────────────┼───────────────────────┤
│ [FeatureList [flags|gumps|items|skills|spells|all] │ List all flags/blocks │
├────────────────────────────────────────────────────┼───────────────────────┤
│ [FeatureAdmin │ Open the admin gump │
└────────────────────────────────────────────────────┴───────────────────────┘
```
#### Gump Blocks
```
┌────────────────────────────────┬──────────────────────────────────────────────────────┐
│ Command │ Description │
├────────────────────────────────┼──────────────────────────────────────────────────────┤
│ [BlockGump <typeName> [reason] │ Block a gump type from displaying │
├────────────────────────────────┼──────────────────────────────────────────────────────┤
│ [UnblockGump <typeName> │ Remove a gump block │
├────────────────────────────────┼──────────────────────────────────────────────────────┤
│ [ListGumps [self] │ List open gumps on a player (for finding type names) │
└────────────────────────────────┴──────────────────────────────────────────────────────┘
```
#### Item Blocks
```
┌────────────────────────────────────────────────┬───────────────────────────────┐
│ Command │ Description │
├────────────────────────────────────────────────┼───────────────────────────────┤
│ [BlockItemUse <typeName|target> [reason] │ Block item use │
├────────────────────────────────────────────────┼───────────────────────────────┤
│ [BlockItemEquip <typeName|target> [reason] │ Block item equipping │
├────────────────────────────────────────────────┼───────────────────────────────┤
│ [BlockItemContainer <typeName|target> [reason] │ Block container access │
├────────────────────────────────────────────────┼───────────────────────────────┤
│ [UnblockItemUse <typeName> │ Remove use block │
├────────────────────────────────────────────────┼───────────────────────────────┤
│ [UnblockItemEquip <typeName> │ Remove equip block │
├────────────────────────────────────────────────┼───────────────────────────────┤
│ [UnblockItemContainer <typeName> │ Remove container access block │
└────────────────────────────────────────────────┴───────────────────────────────┘
```
Item block commands create an entry if one doesn't exist, or flip the relevant flag on an existing entry. Unblock
commands only clear their specific flag -- the entry is removed when all flags (use/equip/container) are off.
#### Skill & Spell Blocks
```
┌──────────────────────────────────────┬──────────────────────┐
│ Command │ Description │
├──────────────────────────────────────┼──────────────────────┤
│ [BlockSkill <SkillName> [reason] │ Block a skill │
├──────────────────────────────────────┼──────────────────────┤
│ [UnblockSkill <SkillName> │ Remove a skill block │
├──────────────────────────────────────┼──────────────────────┤
│ [BlockSpell <SpellTypeName> [reason] │ Block a spell │
├──────────────────────────────────────┼──────────────────────┤
│ [UnblockSpell <SpellTypeName> │ Remove a spell block │
└──────────────────────────────────────┴──────────────────────┘
```
### Architecture
- Static bool classes for hot-path checks (no dictionary lookups): ServerFeatureFlags (Server project) and
ContentFeatureFlags (UOContent)
- Synced automatically by FeatureFlagManager.SyncStaticFlag() when flags change
- Predefined flags loaded from Distribution/Configuration/FeatureFlags/default-flags.json
- Runtime state persisted to Configuration/FeatureFlags/*.json (flags, gump-blocks, item-blocks, skill-blocks,
spell-blocks)
- Admin gump with tabbed UI for managing all block types, per-entry PropertiesGump editing, and pagination
- All staff at AccessLevel.GameMaster+ bypass dynamic blocks; AccessLevel.Administrator+ bypass feature flags
### Hook Points
Hook: Player trading
Location: Mobile.OpenTrade
Mechanism: ServerFeatureFlags.PlayerTrading
────────────────────────────────────────
Hook: PvP combat
Location: Mobile.CanBeHarmful
Mechanism: ServerFeatureFlags.PvPCombat
────────────────────────────────────────
Hook: Bank access
Location: BankBox.Open()
Mechanism: ServerFeatureFlags.BankAccess
────────────────────────────────────────
Hook: Vendor buy/sell
Location: BaseVendor
Mechanism: ContentFeatureFlags.VendorPurchase/Sell
────────────────────────────────────────
Hook: Player vendors
Location: PlayerVendor
Mechanism: ContentFeatureFlags.PlayerVendors
────────────────────────────────────────
Hook: House placement
Location: HousePlacement.Check()
Mechanism: ContentFeatureFlags.HousePlacement (returns BadRegionTemp)
────────────────────────────────────────
Hook: Boat placement
Location: BaseBoatDeed.OnDoubleClick/OnPlacement
Mechanism: ContentFeatureFlags.BoatPlacement
────────────────────────────────────────
Hook: Bulk orders
Location: SmallBOD/LargeBOD
Mechanism: ContentFeatureFlags.BulkOrders
────────────────────────────────────────
Hook: Gump display
Location: GumpSystem.SendGump
Mechanism: FeatureFlagManager.IsGumpBlocked
────────────────────────────────────────
Hook: Item use
Location: PlayerMobile.AllowItemUse
Mechanism: FeatureFlagManager.IsItemUseBlocked
────────────────────────────────────────
Hook: Item equip
Location: PlayerMobile.CheckEquip
Mechanism: FeatureFlagManager.IsItemEquipBlocked
────────────────────────────────────────
Hook: Container access
Location: BaseContainer.DisplayTo
Mechanism: FeatureFlagManager.IsContainerAccessBlocked
────────────────────────────────────────
Hook: Skill use
Location: PlayerMobile.AllowSkillUse
Mechanism: FeatureFlagManager.IsSkillBlocked
────────────────────────────────────────
Hook: Spell casting
Location: Spell.Cast / Spellbook.CastSpellRequest
Mechanism: FeatureFlagManager.IsSpellBlocked
2026-02-07 12:02:57 -08:00
Bohica
e4178bb495
fix: pets will now fallback to follow/stay/guard after combat ( #2325 )
2026-02-05 15:38:39 -08:00
Kamron Batman
06bb2f552e
fix: Moves PlayerBarkeeper to Serialization Generator ( #2323 )
2026-02-01 17:01:39 -08:00
Kamron Batman
ee2cd1d18d
feat: Adds new decay system and SkipSerialization ( #2311 )
...
## Summary
- Replaces scan-based decay checking during world saves with an event-driven timer wheel scheduler
- Removes virtual property checks from serialization hot path, achieving 6-8x faster world saves
## Changes
### DecayScheduler (new):
- Timer wheel with 12 HashSet buckets (5-min intervals) + PriorityQueue for active processing
- O(1) register/unregister vs O(n) scan of all items
- Auto start/stop when items exist/empty
- Configurable tick interval with jitter to prevent system synchronization
### Item.cs:
- Added ScheduledDecayTime computed property
- Added UpdateDecayRegistration() called from SetLastMoved(), property setters, AddItem()/RemoveItem()
- Hooks in Visible, Movable, Spawner setters and Delete()
### World.cs:
- Removed _decayQueue, EnqueueForDecay(), ProcessDecay()
- ItemPersistence.Serialize() now tight loop without virtual calls
## Performance
| Metric | Before | After | Improvement |
|---------------|------------|-----------|-------------|
| Items (230K) | 245K ticks | 34K ticks | 8x faster |
| Mobiles (43K) | 56K ticks | 6K ticks | 9x faster |
| Total | 302K ticks | 40K ticks | 7.5x faster |
## Configuration
decay.maxItemsPerTick = 250 # Items processed per tick
decay.tickInterval = 256ms # Base processing interval
decay.bucketInterval = 5min # Timer wheel bucket size
decay.jitterMaxMs = 25 # ±25ms tick jitter
2026-01-08 11:43:51 -08:00
Kamron Batman
c14f361de1
fix: Moves containers/bods/traps/etc to serialization generator ( #2310 )
2026-01-07 21:55:55 -08:00
Kamron Batman
c4c8b45b79
fix: Fixes BaseVendor IsInvuln configuration ( #2309 )
2026-01-05 09:19:48 -08:00
Kamron Batman
3e8d548f38
feat: Add spawn position caching and spiral scan optimization ( #2295 )
...
### Summary
Adds spawn position caching and optimization for constrained spawners (e.g., those near houses, water, or blocked terrain).
### Key features:
- Sector-based bitmap cache (32 bytes per 16x16 sector) stores valid spawn positions
- Spiral scan progressively discovers positions from spawner center outward
- Automatic mode detects constrained spawners after 5+ non-transient failures
- Prevents mob spawning inside private houses (allows public AoS buildings)
- Deduplicates sector lookups for multi-bounds spawners (RegionSpawner)
- Cache invalidation on house placement/demolition
- Moves SpawnBounds to Spawner
### New spawner properties:
- SpawnPositionMode: Automatic (default), Enabled, Disabled, Abandoned
- MaxSpawnAttempts: Configurable attempts before optimization engages (default: 5)
2025-12-28 02:40:21 -08:00
Kamron Batman
6d51b33cf8
feat: Add CanSpawnMobile overload with props Z-range support. ( #2293 )
...
### Summary
- Adds CanSpawnMobile(x, y, minZ, maxZ, canSwim, cantWalk, out spawnZ) overload for finding spawn surfaces within a Z range
- Adds CanSpawnItem(x, y, minZ, maxZ, out spawnZ) for item spawning with Surface+Impassable support (tables, furniture)
- Uses bitmask optimization inspired by Item.DropToWorld's m_OpenSlots pattern for O(1) surface/blocker checks
- HomeRange spawners now use surface detection to set proper Z bounds
### Key Changes
Map.cs:
- CanSpawnMobile with Z-range finds lowest valid surface for mobiles
- CanSpawnItem with Z-range finds lowest valid surface for items (including tables)
- CanFitItem for point-check item placement on Surface+Impassable tiles
- Bitmask approach eliminates nested loops and stackalloc arrays
Spawners:
- Simplified GetSpawnPosition using new Z-range methods
- HomeRange setter detects surface below spawner for proper Z bounds
- Consistent handling for mobiles and items
### Bug Fixes
- Water tiles (Impassable | Wet) no longer block swimming mobs
- Items can now spawn on tables/furniture (Surface+Impassable)
### Test Plan
- Run dotnet test - 631 tests pass
- Manual testing: multi-story spawning, water mobs, item spawning on tables
- Verify HomeRange spawner movement shifts bounds correctly
2025-12-27 17:01:15 -08:00
Kamron Batman
ebaf104935
chore: Use var everywhere ( #2294 )
2025-12-27 16:47:28 -08:00
Quick
0b34cc4417
feat: Changes Spawner HomeRange to SpawnBounds ( #2290 )
...
### Summary
This PR transitions the spawner system from a simple radius-based model to a flexible 3D boundary system.
### Core Changes
* **Replaced `HomeRange` with `SpawnBounds`**: Spawners now use a `Rectangle3D` to define spawn areas instead of a circular integer range.
* **Backward Compatibility**:
* The `HomeRange` property remains as a helper that generates square `SpawnBounds` centered on the spawner.
* Included a migration path (v10 to v11) that automatically converts old range data into new bounds during deserialization.
* **Dynamic Bounds Shifting**: If a spawner is moved, its `SpawnBounds` will automatically shift with it, provided the bounds are currently configured as a centered square.
* **New Spawn Logic**: Added `SpawnLocationIsHome` toggle. If enabled, spawned mobiles treat their exact spawn coordinates as their "Home" rather than the spawner's location.
### Implementation Details
* **Interface Updates**: Updated `ISpawner` to include `WalkingRange`, `SpawnBounds`, and `IsInSpawnBounds()`.
* **UI Enhancements**: The Spawner Controller Gump now displays "Custom" for complex bounds and allows copying of the new boundary properties between spawners.
* **Refactored Constructors**: Streamlined `BaseSpawner`, `ProximitySpawner`, and `RegionSpawner` constructors to support the new data types.
2025-12-26 18:07:26 -08:00
Bohica
99d8a3db41
fix: Fixes transfer pet spam ( #2291 )
2025-12-20 09:52:34 -08:00
Bohica
0d25f83de5
fix: Fixes pet guard order ( #2287 )
2025-12-06 16:18:26 -08:00
Kamron Batman
7bd5a853a3
feat: Adds size/style support to gump builders, optimizes EscapeHtml ( #2257 )
...
> [!IMPORTANT]
> **Developer Note**
> THIS IS A BREAKING CHANGE TO THE NEW API GUMP.
> Please give us feedback in [discord ](https://muo.gg/discord ) if you have issues, need help, or have ideas for a better API change!
### Summary
* Adds support for size/style to dynamic/static builder.
* Drastically simplifies the dynamic/static builder api for AddHtml.
* Cleans up some legacy gump files.
2025-11-23 11:35:31 -08:00
Kamron Batman
4836bff5eb
fix: Eliminates List allocations in various places. ( #2158 )
2025-11-16 18:33:53 -08:00
Bohica
ee1a40bb51
fix: Fixes movement pathing while in combat ( #2271 )
2025-11-16 10:14:06 -08:00
Bohica
051f22ff93
fix: Fixes vendor look spam ( #2269 )
2025-11-16 10:12:12 -08:00
Bohica
6cabac5a4f
fix: Fixes pets from attacking themselves (Again) ( #2267 )
2025-11-15 14:21:18 -08:00
Bohica
5667017874
fix: Fixes pets from attacking themselves ( #2265 )
...
### Summary
Stops pets from attacking themselves.
2025-11-15 10:15:10 -08:00
Bohica
6938735113
fix: fixes movement jitter for non-AOS ( #2245 )
2025-07-26 10:21:36 -07:00
Bohica
f59605190c
fix: fixes mobiles pathing home after combat ( #2246 )
2025-07-26 10:11:31 -07:00
Kamron Batman
fa0b67ec29
fix: Optimizes items to use default weights. (Part 4) ( #2243 )
2025-07-24 23:29:29 -07:00
Kamron Batman
1e2f4b1171
fix: Fixes tentacles not getting removed from harrower's list ( #2239 )
2025-07-24 14:18:16 -07:00
Bohica
173037ae77
fix: Prevents recursion in BaseCreature.DoHarmful() ( #2202 )
2025-07-22 16:01:56 -07:00
Kamron Batman
aab731ed96
feat: Overhauls AI (Speech/Movement) ( #2232 )
...
### Summary
* Refactors AI so it is easier to read and maintain
* Fixes NPC speed issues
* Fixes pet sector AI issue that was causing stuttering
* Fixes direction snapping for Melee/Mage AI
* Refactors pet orders
* Refactors speech commands
* Removes scale speed by dex for HS+ (it was a stupid feature anyways)
2025-07-18 22:39:57 -07:00
Kamron Batman
f89150735e
fix: Consolidates debug check messages for AI and adds debounce ( #2235 )
2025-07-18 18:08:03 -07:00
Kamron Batman
8f88de68a7
fix: Standardizes the variables for AI ( #2234 )
2025-07-18 17:50:32 -07:00
Kamron Batman
416e1be735
fix: Adds GetDistanceToSqrt for Point3D and centralizes all the calls ( #2233 )
2025-07-18 09:24:41 -07:00
Bohica
2086e9b292
fix: Fixes direction snapping when pathing to combatant for MeleeAI ( #2187 )
...
* fix: Fixes direction snapping when pathing to combatant
* Fixes speed when exiting out of flee action
2025-07-16 21:55:47 -07:00
Bohica
c2c486c06e
fix: Adds body parts to headless one loot ( #2225 )
2025-07-07 18:54:18 -07:00
Bohica
8997130e57
fix: fixes death explosion trigger on death ( #2228 )
2025-07-03 09:47:52 -07:00
mdodkins
f83fc94b05
fix: Do not add an extraneous Open Paperdoll context menu entry ( #2224 )
2025-06-28 17:30:18 -07:00
Felipe Maya Muniz
aadcd6db70
fix: Withdraw should have positive amount to work ( #2221 )
2025-06-28 11:42:43 -07:00
Kamron Batman
a37481ea93
fix: Fixes control target not reset when giving pet order from context menu ( #2220 )
2025-06-25 23:31:51 -07:00
Kamron Batman
7d748491d0
fix: Fixes empty/missing bank box prevent withdraw from account gold ( #2219 )
2025-06-24 10:37:59 -07:00
Bohica
7695174bcc
fix: Adds null-conditional checks when stopping timers for TownCrier ( #2206 )
2025-06-01 10:33:09 -10:00
Kamron Batman
31dc9ffac4
fix: Fixes player vendors not reattaching to their house on deserialization ( #2195 )
2025-05-24 12:00:53 -07:00
Kamron Batman
c1d8606167
fix: Refactors Custom Hairstylist ( #2188 )
2025-05-17 03:30:07 -07:00
Kamron Batman
e468f79e18
feat: Adds SpecialAttack monster ability trigger. Fixes fanning fire. ( #2186 )
2025-05-15 22:14:52 -07:00
Kamron Batman
91b2912ee4
fix: Cleans up potential memory leak in monster abilities. ( #2185 )
2025-05-15 19:42:54 -07:00
Kamron Batman
990e86b983
fix: Fixes guard infinite loop, and streamlines call methods ( #2175 )
2025-05-06 23:54:13 -07:00
Kamron Batman
da517f56c4
chore: Fixes variable types for possible performance issues ( #2172 )
2025-05-01 21:54:41 -07:00
Kamron Batman
4e25c74cdf
fix: Fixes magical barrier NPE and an edge case ( #2162 )
2025-04-22 17:52:09 -07:00
Kamron Batman
a94814a7ef
fix: Fixes and optimizes NameVerification and ProfanityProtection ( #2153 )
...
### Summary
Significantly improves the performance of NameVerification & ProfanityProtection:
```cs
| Method | Mean | Error | StdDev |
|--------------- |----------:|----------:|----------:|
| ValidateName | 728.34 ns | 13.244 ns | 11.059 ns |
| ValidateNameSV | 26.62 ns | 0.233 ns | 0.207 ns |
```
2025-04-12 02:26:10 -07:00
Kamron Batman
2c6f1854fa
fix: Fixes guards attacking mobs ( #2145 )
...
### Summary
- Fixes infinite teleport from guard refactor for spawners
- Fixes guards not attacking Always Murderer creatures
- Fixes crash when calling guards due to map modification while enumeration
2025-03-12 16:45:39 -07:00
Kamron Batman
47da961a37
fix: Fixes spawning guards. Adds back non-lethal with config ( #2140 )
2025-03-12 13:08:14 -07:00
Kamron Batman
bcab91255a
fix: Fixes EVs/BSs attacking players in Pre-AOS ( #2132 )
2025-02-26 18:43:49 -08:00
Kamron Batman
2e08eda8cb
feat: Standardizes South/East selection gumps ( #1839 )
2025-02-14 00:15:14 -08:00