Skip to content

Castle Siege Persistence & Data Initialization #732

@sven-n

Description

@sven-n

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

  • EF Core migration creates all required tables and columns.
  • Seed data initializer creates a complete CastleSiegeConfiguration with all sub-objects.
  • Monster definitions exist for all Castle Siege NPC types.
  • NPC definitions reference correct monster templates and spawn positions.
  • Upgrade tables have level 0–3 entries with costs and values.
  • Initial CastleSiegeData is created (unoccupied).
  • Update plug-in can add Castle Siege data to an existing database.
  • Loading and saving CastleSiegeData round-trips correctly through EF Core.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions