Summary
Create all data model classes, configuration types, entity types, and enumerations needed by Castle Siege. This phase establishes the persistent foundation that all subsequent phases build upon.
Prerequisites
Background
OpenMU uses a [Cloneable] attribute (processed by a source generator) for configuration types that need deep-copy support, and [AggregateRoot] for top-level persistent entities. Configuration is nested under GameConfiguration. Entities are persisted via EF Core with auto-generated model classes through Persistence.SourceGenerator.
Key reference types:
DataModel/Configuration/GameConfiguration.cs — root config with [MemberOfAggregate] collections.
DataModel/Configuration/MiniGameDefinition.cs — example of a [Cloneable] event config.
DataModel/Entities/Guild.cs — example of an [AggregateRoot] entity.
DataModel/Configuration/GameMapDefinition.cs — map config example.
Requirements
1. Enumerations — New files in DataModel/Configuration/
CastleSiegeState.cs
public enum CastleSiegeState : byte
{
Idle1 = 0,
RegisterGuild = 1,
Idle2 = 2,
RegisterMark = 3,
Idle3 = 4,
Notify = 5,
Ready = 6,
Start = 7,
End = 8,
EndCycle = 9,
}
CastleSiegeJoinSide.cs
public enum CastleSiegeJoinSide : byte
{
None = 0,
Defense = 1,
Attack1 = 2,
Attack2 = 3,
Attack3 = 4,
}
CastleSiegeUpgradeType.cs
public enum CastleSiegeUpgradeType : byte
{
Defense = 1,
Regen = 2,
Life = 3,
}
2. Configuration Classes — New files in DataModel/Configuration/
All should have [Cloneable] and be partial class.
CastleSiegeConfiguration.cs
Main configuration aggregated under GameConfiguration:
| Property |
Type |
Description |
Enabled |
bool |
Master toggle |
CrownHoldTimeSeconds |
int |
Seconds to hold the crown to capture (default 30) |
RegisterMinLevel |
int |
Minimum guild master combined level to register (default 200) |
RegisterMinMembers |
int |
Minimum guild member count to register (default 20) |
ParticipantRewardMinSeconds |
int |
Minimum seconds in battle for reward eligibility |
MaxAttackingGuilds |
int |
Number of attacking alliance slots (default 3) |
GuildScoreCastleSiege |
int |
Score awarded to winning guild |
GuildScoreCastleSiegeMembers |
int |
Score awarded to winning alliance member guilds |
GateBuyPrice |
int |
Zen cost to re-purchase a destroyed gate |
StatueBuyPrice |
int |
Zen cost to re-purchase a destroyed statue |
CastleSiegeMapDefinition |
GameMapDefinition? |
Reference to Valley of Loren (map 30) |
LandOfTrialsMapDefinition |
GameMapDefinition? |
Reference to Land of Trials (map 31) |
RewardItemDefinition |
ItemDefinition? |
Participant reward item |
StateSchedule |
ICollection<CastleSiegeStateScheduleEntry> |
[MemberOfAggregate] |
NpcDefinitions |
ICollection<CastleSiegeNpcDefinition> |
[MemberOfAggregate] |
GateDefenseUpgrades |
ICollection<CastleSiegeUpgradeDefinition> |
[MemberOfAggregate] |
GateLifeUpgrades |
ICollection<CastleSiegeUpgradeDefinition> |
[MemberOfAggregate] |
StatueDefenseUpgrades |
ICollection<CastleSiegeUpgradeDefinition> |
[MemberOfAggregate] |
StatueLifeUpgrades |
ICollection<CastleSiegeUpgradeDefinition> |
[MemberOfAggregate] |
StatueRegenUpgrades |
ICollection<CastleSiegeUpgradeDefinition> |
[MemberOfAggregate] |
AttackMachineZones |
ICollection<CastleSiegeZoneDefinition> |
[MemberOfAggregate] |
DefenseMachineZones |
ICollection<CastleSiegeZoneDefinition> |
[MemberOfAggregate] |
DefenseRespawnArea |
CastleSiegeZoneDefinition? |
[MemberOfAggregate] |
AttackRespawnArea |
CastleSiegeZoneDefinition? |
[MemberOfAggregate] |
CastleSiegeStateScheduleEntry.cs
| Property |
Type |
Description |
State |
CastleSiegeState |
Which state |
DayOfWeek |
DayOfWeek |
Day of the week (0=Sunday) |
Hour |
byte |
Hour (0–23) |
Minute |
byte |
Minute (0–59) |
CastleSiegeNpcDefinition.cs
| Property |
Type |
Description |
MonsterDefinition |
MonsterDefinition? |
Reference to the monster template |
InstanceId |
byte |
Unique instance ID within its type |
IsPersistedToDatabase |
bool |
Whether state is saved between sieges |
DefaultSide |
CastleSiegeJoinSide |
Default join side |
SpawnX |
short |
Spawn X coordinate |
SpawnY |
short |
Spawn Y coordinate |
Direction |
Direction |
Facing direction (use existing Direction enum) |
CastleSiegeUpgradeDefinition.cs
| Property |
Type |
Description |
Level |
byte |
Upgrade level (0–3) |
RequiredJewelOfGuardianCount |
int |
Number of Jewels of Guardian required |
RequiredZen |
int |
Zen cost |
Value |
int |
Result value (defense stat or max HP) |
CastleSiegeZoneDefinition.cs
| Property |
Type |
Description |
X1 |
byte |
Top-left X |
Y1 |
byte |
Top-left Y |
X2 |
byte |
Bottom-right X |
Y2 |
byte |
Bottom-right Y |
3. Entity Classes — New files in DataModel/Entities/
CastleSiegeData.cs
Persistent state of the current siege. Single-row entity. [AggregateRoot].
| Property |
Type |
Description |
Id |
Guid |
PK |
OwnerGuildId |
Guid? |
FK to Guild (persistent Guid) |
IsOccupied |
bool |
Whether any guild owns the castle |
TaxChaos |
byte |
Chaos tax rate (0–3) |
TaxStore |
byte |
Store tax rate (0–3) |
TaxHunt |
int |
Hunt zone entry fee (0–300000) |
IsHuntZoneEnabled |
bool |
Whether hunt zone is open |
TributeMoney |
long |
Accumulated tribute money |
NpcStates |
ICollection<CastleSiegeNpcState> |
[MemberOfAggregate] |
CastleSiegeNpcState.cs
Persistent state of a single castle NPC.
| Property |
Type |
Description |
Id |
Guid |
PK |
MonsterNumber |
short |
Monster definition number |
InstanceId |
byte |
Instance ID matching CastleSiegeNpcDefinition.InstanceId |
DefenseLevel |
byte |
Defense upgrade level (0–3) |
RegenLevel |
byte |
Regen upgrade level (0–3) |
LifeLevel |
byte |
Life upgrade level (0–3) |
CurrentHp |
int |
Current HP (0 = dead) |
CastleSiegeGuildRegistration.cs
Per-cycle registration data. [AggregateRoot].
| Property |
Type |
Description |
Id |
Guid |
PK |
GuildId |
Guid |
FK to Guild |
GuildName |
string |
Denormalized for convenience |
Marks |
int |
Number of Emblems of Lord registered |
RegistrationOrder |
int |
Insertion order (for tie-breaking) |
4. GameConfiguration Integration (DataModel/Configuration/GameConfiguration.cs)
Add:
[MemberOfAggregate]
public virtual CastleSiegeConfiguration? CastleSiegeConfiguration { get; set; }
5. NpcWindow Extension (DataModel/Configuration/MonsterDefinition.cs)
Verify NpcWindow.CastleSeniorNPC already exists (it does). May need to add additional window types for siege NPCs if not present:
CastleSiegeGateNpc
CastleSiegeLeverNpc
Files to Create
| File |
Description |
DataModel/Configuration/CastleSiegeState.cs |
State enum |
DataModel/Configuration/CastleSiegeJoinSide.cs |
Join side enum |
DataModel/Configuration/CastleSiegeUpgradeType.cs |
Upgrade type enum |
DataModel/Configuration/CastleSiegeConfiguration.cs |
Main CS config |
DataModel/Configuration/CastleSiegeStateScheduleEntry.cs |
State schedule entry |
DataModel/Configuration/CastleSiegeNpcDefinition.cs |
NPC definition |
DataModel/Configuration/CastleSiegeUpgradeDefinition.cs |
Upgrade definition |
DataModel/Configuration/CastleSiegeZoneDefinition.cs |
Zone rectangle |
DataModel/Entities/CastleSiegeData.cs |
Persistent siege state |
DataModel/Entities/CastleSiegeNpcState.cs |
Persistent NPC state |
DataModel/Entities/CastleSiegeGuildRegistration.cs |
Per-cycle registration |
Files to Modify
| File |
Changes |
DataModel/Configuration/GameConfiguration.cs |
Add CastleSiegeConfiguration property |
Acceptance Criteria
Summary
Create all data model classes, configuration types, entity types, and enumerations needed by Castle Siege. This phase establishes the persistent foundation that all subsequent phases build upon.
Prerequisites
GuildPosition.AssistantMasterand alliance concepts.Background
OpenMU uses a
[Cloneable]attribute (processed by a source generator) for configuration types that need deep-copy support, and[AggregateRoot]for top-level persistent entities. Configuration is nested underGameConfiguration. Entities are persisted via EF Core with auto-generated model classes throughPersistence.SourceGenerator.Key reference types:
DataModel/Configuration/GameConfiguration.cs— root config with[MemberOfAggregate]collections.DataModel/Configuration/MiniGameDefinition.cs— example of a[Cloneable]event config.DataModel/Entities/Guild.cs— example of an[AggregateRoot]entity.DataModel/Configuration/GameMapDefinition.cs— map config example.Requirements
1. Enumerations — New files in
DataModel/Configuration/CastleSiegeState.csCastleSiegeJoinSide.csCastleSiegeUpgradeType.cs2. Configuration Classes — New files in
DataModel/Configuration/All should have
[Cloneable]and bepartial class.CastleSiegeConfiguration.csMain configuration aggregated under
GameConfiguration:EnabledboolCrownHoldTimeSecondsintRegisterMinLevelintRegisterMinMembersintParticipantRewardMinSecondsintMaxAttackingGuildsintGuildScoreCastleSiegeintGuildScoreCastleSiegeMembersintGateBuyPriceintStatueBuyPriceintCastleSiegeMapDefinitionGameMapDefinition?LandOfTrialsMapDefinitionGameMapDefinition?RewardItemDefinitionItemDefinition?StateScheduleICollection<CastleSiegeStateScheduleEntry>[MemberOfAggregate]NpcDefinitionsICollection<CastleSiegeNpcDefinition>[MemberOfAggregate]GateDefenseUpgradesICollection<CastleSiegeUpgradeDefinition>[MemberOfAggregate]GateLifeUpgradesICollection<CastleSiegeUpgradeDefinition>[MemberOfAggregate]StatueDefenseUpgradesICollection<CastleSiegeUpgradeDefinition>[MemberOfAggregate]StatueLifeUpgradesICollection<CastleSiegeUpgradeDefinition>[MemberOfAggregate]StatueRegenUpgradesICollection<CastleSiegeUpgradeDefinition>[MemberOfAggregate]AttackMachineZonesICollection<CastleSiegeZoneDefinition>[MemberOfAggregate]DefenseMachineZonesICollection<CastleSiegeZoneDefinition>[MemberOfAggregate]DefenseRespawnAreaCastleSiegeZoneDefinition?[MemberOfAggregate]AttackRespawnAreaCastleSiegeZoneDefinition?[MemberOfAggregate]CastleSiegeStateScheduleEntry.csStateCastleSiegeStateDayOfWeekDayOfWeekHourbyteMinutebyteCastleSiegeNpcDefinition.csMonsterDefinitionMonsterDefinition?InstanceIdbyteIsPersistedToDatabaseboolDefaultSideCastleSiegeJoinSideSpawnXshortSpawnYshortDirectionDirectionDirectionenum)CastleSiegeUpgradeDefinition.csLevelbyteRequiredJewelOfGuardianCountintRequiredZenintValueintCastleSiegeZoneDefinition.csX1byteY1byteX2byteY2byte3. Entity Classes — New files in
DataModel/Entities/CastleSiegeData.csPersistent state of the current siege. Single-row entity.
[AggregateRoot].IdGuidOwnerGuildIdGuid?IsOccupiedboolTaxChaosbyteTaxStorebyteTaxHuntintIsHuntZoneEnabledboolTributeMoneylongNpcStatesICollection<CastleSiegeNpcState>[MemberOfAggregate]CastleSiegeNpcState.csPersistent state of a single castle NPC.
IdGuidMonsterNumbershortInstanceIdbyteCastleSiegeNpcDefinition.InstanceIdDefenseLevelbyteRegenLevelbyteLifeLevelbyteCurrentHpintCastleSiegeGuildRegistration.csPer-cycle registration data.
[AggregateRoot].IdGuidGuildIdGuidGuildNamestringMarksintRegistrationOrderint4.
GameConfigurationIntegration (DataModel/Configuration/GameConfiguration.cs)Add:
5.
NpcWindowExtension (DataModel/Configuration/MonsterDefinition.cs)Verify
NpcWindow.CastleSeniorNPCalready exists (it does). May need to add additional window types for siege NPCs if not present:CastleSiegeGateNpcCastleSiegeLeverNpcFiles to Create
DataModel/Configuration/CastleSiegeState.csDataModel/Configuration/CastleSiegeJoinSide.csDataModel/Configuration/CastleSiegeUpgradeType.csDataModel/Configuration/CastleSiegeConfiguration.csDataModel/Configuration/CastleSiegeStateScheduleEntry.csDataModel/Configuration/CastleSiegeNpcDefinition.csDataModel/Configuration/CastleSiegeUpgradeDefinition.csDataModel/Configuration/CastleSiegeZoneDefinition.csDataModel/Entities/CastleSiegeData.csDataModel/Entities/CastleSiegeNpcState.csDataModel/Entities/CastleSiegeGuildRegistration.csFiles to Modify
DataModel/Configuration/GameConfiguration.csCastleSiegeConfigurationpropertyAcceptance Criteria
[Cloneable](config) or[AggregateRoot](entity) as appropriate.GameConfiguration.CastleSiegeConfigurationis correctly navigable.[MemberOfAggregate]for proper ownership.