Skip to main content

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:

PropertyTypeDefaultDescription
ItemTypeIdstringrequiredUnique identifier (e.g., sword_legendary)
NamestringrequiredDisplay name
Descriptionstring?nullOptional description
MaxStackSizeint1Maximum items per stack (1 = non-stackable)
IsTradeablebooltrueWhether items can be traded
Categorystring?nullOptional 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
}
}
OptionDefaultDescription
SeedFilePathnullPath to JSON seed file. Empty = skip seeding.
ForceSeedfalseIf true, re-seed even if registry has data (dev mode).
AllowUnknownItemTypestrueIf 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):

  1. Registry Check: Checks if ItemTypeId is registered.
    • If unknown and AllowUnknownItemTypes = false: Throws InvalidOperationException.
    • If unknown and AllowUnknownItemTypes = true: Uses defaults (MaxStackSize=1, IsTradeable=true).
  2. Stack Size: Enforces MaxStackSize defined in registry.
    • If quantity > MaxStackSize: Throws InvalidOperationException.

Trading Validation

  • Non-tradeable items cannot be added to trades (IsTradeable = false).