Item Type Registry
The Item Type Registry is a centralized catalogue of all valid item types in the game. It defines item properties like stack sizes and tradeability.
Overview
- Singleton grain (
IItemTypeRegistryGrain) with key"default" - Persisted to OrleansStorage (YugabyteDB in production)
- Seeded from JSON file on startup (optional)
- Admin API for runtime management
- Real-time updates via SignalR
Item Type Definition
Each item type has these properties:
| Property | Type | Default | Description |
|---|---|---|---|
ItemTypeId | string | required | Unique identifier (e.g., sword_legendary) |
Name | string | required | Display name |
Description | string? | null | Optional description |
MaxStackSize | int | 1 | Maximum items per stack (1 = non-stackable) |
IsTradeable | bool | true | Whether items can be traded |
Category | string? | null | Optional category (e.g., weapon, consumable) |
Usage
Registering Item Types
var registry = grainFactory.GetGrain<IItemTypeRegistryGrain>("default");
// Single registration
await registry.RegisterAsync(new ItemTypeDefinition
{
ItemTypeId = "sword_legendary",
Name = "Legendary Sword",
MaxStackSize = 1,
IsTradeable = true
});
// Batch registration
await registry.RegisterManyAsync(new[]
{
new ItemTypeDefinition { ItemTypeId = "potion_health", Name = "Health Potion", MaxStackSize = 99 },
new ItemTypeDefinition { ItemTypeId = "gem_soul", Name = "Soul Gem", IsTradeable = false }
});
Querying
// Get definition
var definition = await registry.GetAsync("sword_legendary");
// Check existence
bool exists = await registry.ExistsAsync("unknown_item");
// Get specific properties
int stackSize = await registry.GetMaxStackSizeAsync("potion_health"); // 99
bool tradeable = await registry.IsTradeableAsync("gem_soul"); // false
Admin Management
Admins can manage item types at runtime using the ItemTypeHub.
SignalR Events
The ItemTypeHub broadcasts events when registry changes occur.
Hub Endpoint: /itemTypeHub
Events:
ItemTypeCreated(ItemTypeDefinition)ItemTypeUpdated(ItemTypeDefinition)ItemTypeDeleted(string itemTypeId)
Configuration
// appsettings.json
{
"ItemRegistry": {
"SeedFilePath": "data/item-types.json",
"ForceSeed": false,
"AllowUnknownItemTypes": true
}
}
| Option | Default | Description |
|---|---|---|
SeedFilePath | null | Path to JSON seed file. Empty = skip seeding. |
ForceSeed | false | If true, re-seed even if registry has data (dev mode). |
AllowUnknownItemTypes | true | If true, InventoryGrain allows adding items with unregistered types (permissive for dev). if false, throws error. |
Seed File Format
[
{
"ItemTypeId": "sword_legendary",
"Name": "Legendary Sword",
"MaxStackSize": 1,
"IsTradeable": true,
"Category": "weapon"
}
]
Integration with Gameplay
Inventory Validation
When adding items to inventory (InventoryGrain.AddItemAsync):
- Registry Check: Checks if
ItemTypeIdis registered.- If unknown and
AllowUnknownItemTypes = false: ThrowsInvalidOperationException. - If unknown and
AllowUnknownItemTypes = true: Uses defaults (MaxStackSize=1,IsTradeable=true).
- If unknown and
- Stack Size: Enforces
MaxStackSizedefined in registry.- If quantity > MaxStackSize: Throws
InvalidOperationException.
- If quantity > MaxStackSize: Throws
Trading Validation
- Non-tradeable items cannot be added to trades (
IsTradeable = false).