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
Kamron Batman
fa0b67ec29
fix: Optimizes items to use default weights. (Part 4) ( #2243 )
2025-07-24 23:29:29 -07:00
Kamron Batman
3a0d4b171b
fix: Codegens boats ( #1625 )
2023-12-02 12:55:38 -08:00
Kamron Batman
42012538bc
fix: Fixes crafter deserialize, cleans up bandages, and codegens misc items ( #1350 )
2023-02-25 00:54:12 -08:00
Kamron Batman
0925a2d435
fix: Cleans up Point checks and removes statics ( #966 )
...
- [X] Removes static freezing/unfreezing. Use other tools for this.
- [X] Cleans up IPoint3D allocations
- [X] Removes IPoint3D constructors since the compiler may not optimize the constructor path and allow allocations.
Note: Instead of `new Point3D(m)`, do something like `new Point3D(m.Location)`. Sorry for the inconvenience. In the long run this will prevent abuse of hot paths that will cause performance issues.
2022-03-20 23:15:59 -07:00
Kamron Batman
3293ffcf06
fix: Cleanup IPoint3D calls ( #704 )
2021-08-19 09:11:48 -07:00
Kamron Batman
4d6e584b6c
Removes literal variables ( #257 )
2020-09-18 18:41:26 -07:00
Kamron Batman
8149620b0c
Fixes brace style ( #248 )
2020-09-13 21:49:46 -07:00
Kamron Batman
ad3775c4d7
Formats UO Content ( #201 )
2020-08-27 18:30:38 -07:00
Kamron Batman
1f651992d7
Updates formatting rules ( #199 )
2020-08-25 18:00:51 -07:00
Kamron Batman
8ec166bcd0
Adds assemblies config, fixes crash bugs. ( #134 )
2020-05-09 12:55:56 -07:00