Summary
Create EF Core entity mappings, migrations, and seed data initializers for all Castle Siege data types. This includes the model builder extensions for new entities and the Season 6 data initialization for Castle Siege configuration, NPC definitions, upgrade tables, and map setup.
Prerequisites
Background
OpenMU persistence patterns:
- Source generators (
Persistence.SourceGenerator) auto-generate EF Core model classes and basic model classes from DataModel types annotated with [Cloneable] or [AggregateRoot].
- Model builder extensions in
Persistence/EntityFramework/Extensions/ModelBuilder/ configure EF Core mappings (keys, navigation, JSON columns, etc.). See examples like GameConfigurationExtensions.cs, MonsterExtensions.cs.
EntityDataContext.cs
- Data initialization uses
InitializerBase subclasses in version-specific folders. See BloodCastleInitializer.cs and ValleyOfLoren.cs.
- Update plug-ins in
Persistence/Initialization/Updates/ add new data to existing databases.
Requirements
1. Model Builder Extensions — New file: Persistence/EntityFramework/Extensions/ModelBuilder/CastleSiegeExtensions.cs
Configure EF Core mappings for:
CastleSiegeConfiguration — map all properties, configure navigation properties to GameMapDefinition, ItemDefinition, collections of sub-types.
CastleSiegeStateScheduleEntry — owned by CastleSiegeConfiguration.
CastleSiegeNpcDefinition — owned by CastleSiegeConfiguration, with FK to MonsterDefinition.
CastleSiegeUpgradeDefinition — owned by the various upgrade collections.
CastleSiegeZoneDefinition — owned by zone collections or stored as JSON.
CastleSiegeData — standalone entity, FK to Guild for OwnerGuildId.
CastleSiegeNpcState — owned by CastleSiegeData.
CastleSiegeGuildRegistration — standalone entity.
Follow patterns from GameConfigurationExtensions.cs:
public static class CastleSiegeExtensions
{
public static void ApplyCastleSiegeConfiguration(this ModelBuilder modelBuilder)
{
// Entity configurations here
}
}
Register in ModelBuilderExtensions.cs.
2. EntityDataContext Updates — Modify: Persistence/EntityFramework/EntityDataContext.cs
Add DbSet properties for standalone entities:
public DbSet<CastleSiegeData> CastleSiegeData => this.Set<CastleSiegeData>();
public DbSet<CastleSiegeGuildRegistration> CastleSiegeGuildRegistrations => this.Set<CastleSiegeGuildRegistration>();
3. EF Core Migration
Generate a new migration for the Castle Siege tables:
dotnet ef migrations add AddCastleSiege
This creates:
CastleSiegeData table (single-row).
CastleSiegeNpcState table (FK to CastleSiegeData).
CastleSiegeGuildRegistration table.
- Additional columns/tables for configuration types (depending on whether they're stored as JSON or normalized).
4. Data Initialization — New file: Persistence/Initialization/VersionSeasonSix/Events/CastleSiegeInitializer.cs
Create seed data for Season 6:
State Schedule
Default weekly schedule (example — can be adjusted):
Idle1: Sunday 00:00
RegisterGuild: Monday 00:00
Idle2: Tuesday 00:00
RegisterMark: Wednesday 00:00
Idle3: Thursday 00:00
Notify: Friday 00:00
Ready: Saturday 18:00
Start: Saturday 20:00
End: Saturday 22:00
EndCycle: Saturday 22:05
NPC Definitions
Based on the Valley of Loren map (ValleyOfLoren.cs) existing spawns and the C++ reference:
Ensure MonsterDefinition entries exist for:
| ID |
Name |
Notes |
| 216 |
Crown |
Already in ValleyOfLoren.cs as NPC |
| 217 |
Crown Switch 1 |
Already in ValleyOfLoren.cs |
| 218 |
Crown Switch 2 |
Already in ValleyOfLoren.cs |
| 219 |
Castle Siege Crown |
May need separate CS-specific definition |
| 220 |
Guard |
Already in ValleyOfLoren.cs |
| 221 |
Attack Machine |
May need to be created |
| 222 |
Defense Machine |
May need to be created |
| 223 |
Sinior (Castle Senior NPC) |
Already in ValleyOfLoren.cs |
| 224 |
Guardsman |
Already in ValleyOfLoren.cs |
| 277 |
Castle Gate |
Needs to be created |
| 283 |
Guardian Statue |
Needs to be created |
Create CastleSiegeNpcDefinition entries for each gate, statue, crown, switch, lever, and machine position.
Upgrade Tables
Initialize GateDefenseUpgrades, GateLifeUpgrades, StatueDefenseUpgrades, StatueLifeUpgrades, StatueRegenUpgrades with level 0–3 entries with appropriate costs and values from the C++ reference.
Machine Zone Coordinates
Initialize AttackMachineZones and DefenseMachineZones with the hex values from the C++ reference (converted to decimal).
Respawn Areas
- Defense: (74, 144) to (115, 154)
- Attack: (35, 11) to (144, 48)
Castle Siege Data (initial state)
IsOccupied = false
OwnerGuildId = null
- All taxes = 0
TributeMoney = 0
5. Update Plug-In — New file: Persistence/Initialization/Updates/AddCastleSiegeDataUpdatePlugIn.cs
For databases created before Castle Siege was added. Follows the pattern of AddDuelConfigurationPlugIn.cs:
[PlugIn(nameof(AddCastleSiegeDataUpdatePlugIn), "Adds Castle Siege configuration")]
[Guid("...")]
public class AddCastleSiegeDataUpdatePlugIn : UpdatePlugInBase
{
public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id;
public override UpdateVersion Version => ...;
public override string Name => "Add Castle Siege";
protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration)
{
// Create CastleSiegeConfiguration on gameConfiguration
// Create initial CastleSiegeData
}
}
6. Persistence Context Extensions
Ensure IPersistenceContextProvider can create contexts for loading/saving CastleSiegeData and CastleSiegeGuildRegistration. May need to add methods or use existing generic patterns.
Files to Create
| File |
Description |
Persistence/EntityFramework/Extensions/ModelBuilder/CastleSiegeExtensions.cs |
EF Core entity configuration |
Persistence/Initialization/VersionSeasonSix/Events/CastleSiegeInitializer.cs |
Seed data |
Persistence/Initialization/Updates/AddCastleSiegeDataUpdatePlugIn.cs |
Database update plug-in |
Persistence/EntityFramework/Migrations/...AddCastleSiege.cs |
EF Migration |
Files to Modify
| File |
Changes |
Persistence/EntityFramework/EntityDataContext.cs |
Add DbSet properties |
Persistence/EntityFramework/Extensions/ModelBuilderExtensions.cs |
Register CS extensions |
Persistence/Initialization/VersionSeasonSix/VersionSeasonSixDataInitialization.cs |
Call CS initializer |
Acceptance Criteria
Summary
Create EF Core entity mappings, migrations, and seed data initializers for all Castle Siege data types. This includes the model builder extensions for new entities and the Season 6 data initialization for Castle Siege configuration, NPC definitions, upgrade tables, and map setup.
Prerequisites
Background
OpenMU persistence patterns:
Persistence.SourceGenerator) auto-generate EF Core model classes and basic model classes fromDataModeltypes annotated with[Cloneable]or[AggregateRoot].Persistence/EntityFramework/Extensions/ModelBuilder/configure EF Core mappings (keys, navigation, JSON columns, etc.). See examples likeGameConfigurationExtensions.cs,MonsterExtensions.cs.EntityDataContext.csInitializerBasesubclasses in version-specific folders. SeeBloodCastleInitializer.csandValleyOfLoren.cs.Persistence/Initialization/Updates/add new data to existing databases.Requirements
1. Model Builder Extensions — New file:
Persistence/EntityFramework/Extensions/ModelBuilder/CastleSiegeExtensions.csConfigure EF Core mappings for:
CastleSiegeConfiguration— map all properties, configure navigation properties toGameMapDefinition,ItemDefinition, collections of sub-types.CastleSiegeStateScheduleEntry— owned byCastleSiegeConfiguration.CastleSiegeNpcDefinition— owned byCastleSiegeConfiguration, with FK toMonsterDefinition.CastleSiegeUpgradeDefinition— owned by the various upgrade collections.CastleSiegeZoneDefinition— owned by zone collections or stored as JSON.CastleSiegeData— standalone entity, FK to Guild forOwnerGuildId.CastleSiegeNpcState— owned byCastleSiegeData.CastleSiegeGuildRegistration— standalone entity.Follow patterns from
GameConfigurationExtensions.cs:Register in
ModelBuilderExtensions.cs.2.
EntityDataContextUpdates — Modify:Persistence/EntityFramework/EntityDataContext.csAdd
DbSetproperties for standalone entities:3. EF Core Migration
Generate a new migration for the Castle Siege tables:
This creates:
CastleSiegeDatatable (single-row).CastleSiegeNpcStatetable (FK toCastleSiegeData).CastleSiegeGuildRegistrationtable.4. Data Initialization — New file:
Persistence/Initialization/VersionSeasonSix/Events/CastleSiegeInitializer.csCreate seed data for Season 6:
State Schedule
Default weekly schedule (example — can be adjusted):
NPC Definitions
Based on the Valley of Loren map (
ValleyOfLoren.cs) existing spawns and the C++ reference:Ensure
MonsterDefinitionentries exist for:ValleyOfLoren.csas NPCValleyOfLoren.csValleyOfLoren.csValleyOfLoren.csValleyOfLoren.csValleyOfLoren.csCreate
CastleSiegeNpcDefinitionentries for each gate, statue, crown, switch, lever, and machine position.Upgrade Tables
Initialize
GateDefenseUpgrades,GateLifeUpgrades,StatueDefenseUpgrades,StatueLifeUpgrades,StatueRegenUpgradeswith level 0–3 entries with appropriate costs and values from the C++ reference.Machine Zone Coordinates
Initialize
AttackMachineZonesandDefenseMachineZoneswith the hex values from the C++ reference (converted to decimal).Respawn Areas
Castle Siege Data (initial state)
IsOccupied = falseOwnerGuildId = nullTributeMoney = 05. Update Plug-In — New file:
Persistence/Initialization/Updates/AddCastleSiegeDataUpdatePlugIn.csFor databases created before Castle Siege was added. Follows the pattern of
AddDuelConfigurationPlugIn.cs:6. Persistence Context Extensions
Ensure
IPersistenceContextProvidercan create contexts for loading/savingCastleSiegeDataandCastleSiegeGuildRegistration. May need to add methods or use existing generic patterns.Files to Create
Persistence/EntityFramework/Extensions/ModelBuilder/CastleSiegeExtensions.csPersistence/Initialization/VersionSeasonSix/Events/CastleSiegeInitializer.csPersistence/Initialization/Updates/AddCastleSiegeDataUpdatePlugIn.csPersistence/EntityFramework/Migrations/...AddCastleSiege.csFiles to Modify
Persistence/EntityFramework/EntityDataContext.csPersistence/EntityFramework/Extensions/ModelBuilderExtensions.csPersistence/Initialization/VersionSeasonSix/VersionSeasonSixDataInitialization.csAcceptance Criteria
CastleSiegeConfigurationwith all sub-objects.CastleSiegeDatais created (unoccupied).CastleSiegeDataround-trips correctly through EF Core.