2026-06-13 09:15:59 +01:00
using Aetheria.State ;
using Aetheria.State.Unity ;
2026-06-13 12:04:11 +01:00
using GameCult.Aetheria.State.Unity ;
2026-06-13 16:44:24 +01:00
using GameCult.Eve.Surface ;
2026-06-14 22:26:51 +01:00
using MessagePack ;
2026-06-13 09:15:59 +01:00
var root = args . Length > 0 ? Path . GetFullPath ( args [ 0 ] ) : Directory . GetCurrentDirectory ( ) ;
var statePath = args . Length > 1
? Path . GetFullPath ( args [ 1 ] )
: AetheriaStatePaths . ResolveDefaultStatePath ( root ) ;
await using var client = await AetheriaRuntimeCatalogClient . OpenAsync ( statePath ) ;
var catalog = client . ReadCatalog ( ) ;
2026-06-13 12:24:27 +01:00
var packageCatalog = AetheriaRuntimeCatalogStore . OpenReadOnly ( statePath ) ;
2026-06-13 16:15:03 +01:00
var packageSurfaces = AetheriaRuntimeCatalogStore . ReadEveSurfaces ( statePath ) ;
2026-06-13 09:15:59 +01:00
var surface = await client . ReadCatalogSurfaceAsync ( ) ;
2026-06-13 15:27:12 +01:00
var commitSmokeDirectory = Path . Combine ( Path . GetTempPath ( ) , "aetheria-state-unity-smoke" , Guid . NewGuid ( ) . ToString ( "N" ) ) ;
var commitSmokeStatePath = Path . Combine ( commitSmokeDirectory , "aetheria-world.cc" ) ;
Directory . CreateDirectory ( commitSmokeDirectory ) ;
2026-06-13 09:15:59 +01:00
if ( catalog . Items . Count ! = 115 )
{
throw new InvalidOperationException ( $"Expected 115 runtime catalog items, found {catalog.Items.Count}." ) ;
}
2026-06-13 12:24:27 +01:00
if ( packageCatalog . Items . Count ! = catalog . Items . Count | |
packageCatalog . Corporations . Count ! = catalog . Corporations . Count | |
packageCatalog . NameFiles . Count ! = catalog . NameFiles . Count )
{
throw new InvalidOperationException (
$"Package catalog store mismatch: {packageCatalog.Items.Count}/{packageCatalog.Corporations.Count}/{packageCatalog.NameFiles.Count} " +
$"!= {catalog.Items.Count}/{catalog.Corporations.Count}/{catalog.NameFiles.Count}." ) ;
}
2026-06-13 09:15:59 +01:00
if ( catalog . TradeItems . Count = = 0 )
{
throw new InvalidOperationException ( "Runtime catalog has no trade items." ) ;
}
if ( catalog . EquipmentItems . Count = = 0 )
{
throw new InvalidOperationException ( "Runtime catalog has no equipment items." ) ;
}
2026-06-13 09:32:24 +01:00
var shaped = catalog . Items . FirstOrDefault ( item = > item . ShapeCells . Count > 0 )
? ? throw new InvalidOperationException ( "Runtime catalog has no typed shape masks." ) ;
2026-06-13 12:24:27 +01:00
var packageShaped = packageCatalog . FindItemByLegacyId ( shaped . LegacyId ) ;
if ( packageShaped = = null | |
packageShaped . Name ! = shaped . Name | |
packageShaped . ShapeCells . Count ! = shaped . ShapeCells . Count )
{
throw new InvalidOperationException ( $"Package catalog store did not read the expected typed item payload for {shaped.Name}." ) ;
}
2026-06-13 09:32:24 +01:00
if ( shaped . ShapeCells . Count ! = shaped . OccupiedCells )
{
throw new InvalidOperationException (
$"Runtime shape mask count mismatch for {shaped.Name}: cells={shaped.ShapeCells.Count}, occupied={shaped.OccupiedCells}." ) ;
}
if ( shaped . ShapeCells . Any ( cell = > cell . X < 0 | | cell . Y < 0 | | cell . X > = shaped . ShapeWidth | | cell . Y > = shaped . ShapeHeight ) )
{
throw new InvalidOperationException ( $"Runtime shape mask has out-of-bounds cells for {shaped.Name}." ) ;
}
2026-06-13 09:47:25 +01:00
var interior = catalog . Items . FirstOrDefault ( item = > item . InteriorShapeCells . Count > 0 )
? ? throw new InvalidOperationException ( "Runtime catalog has no typed interior shape masks." ) ;
if ( interior . InteriorShapeCells . Count ! = interior . InteriorOccupiedCells )
{
throw new InvalidOperationException (
$"Runtime interior shape mask count mismatch for {interior.Name}: cells={interior.InteriorShapeCells.Count}, occupied={interior.InteriorOccupiedCells}." ) ;
}
var hardpointHost = catalog . Items . FirstOrDefault ( item = > item . Hardpoints . Count > 0 )
? ? throw new InvalidOperationException ( "Runtime catalog has no typed hardpoints." ) ;
var hardpoint = hardpointHost . Hardpoints . First ( ) ;
if ( hardpoint . ShapeCells . Count ! = hardpoint . OccupiedCells )
{
throw new InvalidOperationException (
$"Runtime hardpoint shape count mismatch for {hardpointHost.Name}: cells={hardpoint.ShapeCells.Count}, occupied={hardpoint.OccupiedCells}." ) ;
}
2026-06-13 09:15:59 +01:00
var behaviorKind = catalog . Items . SelectMany ( item = > item . BehaviorKinds ) . FirstOrDefault ( )
? ? throw new InvalidOperationException ( "Runtime catalog has no behavior kind fingerprints." ) ;
if ( ! catalog . FindItemsByBehavior ( behaviorKind ) . Any ( ) )
{
throw new InvalidOperationException ( $"Runtime catalog behavior lookup failed for {behaviorKind}." ) ;
}
2026-06-13 10:01:20 +01:00
var behaviorHost = catalog . Items . FirstOrDefault ( item = > item . BehaviorPayloads . Count > 0 )
? ? throw new InvalidOperationException ( "Runtime catalog has no typed behavior payloads." ) ;
if ( ! behaviorHost . BehaviorPayloads . All ( payload = > behaviorHost . BehaviorKinds . Contains ( payload . Kind ) ) )
{
throw new InvalidOperationException (
$"Runtime behavior payload kind index mismatch for {behaviorHost.Name}." ) ;
}
var behaviorPayload = behaviorHost . BehaviorPayloads . First ( ) ;
if ( behaviorPayload . Fields . Count = = 0 )
{
throw new InvalidOperationException ( $"Runtime behavior payload has no fields for {behaviorHost.Name}." ) ;
}
2026-06-15 16:10:13 +01:00
var behaviorItemRefsMissingItemKeys = packageCatalog . Items
. SelectMany ( item = > item . BehaviorPayloads )
. Sum ( CountRequiredBehaviorItemRefsMissingItemKeys ) ;
if ( behaviorItemRefsMissingItemKeys > 0 )
{
throw new InvalidOperationException (
$"Runtime behavior payload item refs missing item-key projections: {behaviorItemRefsMissingItemKeys}." ) ;
}
2026-06-13 09:15:59 +01:00
var equipment = catalog . EquipmentItems . First ( ) ;
if ( ! catalog . FindItemsByHardpoint ( equipment . HardpointType ) . Any ( ) )
{
throw new InvalidOperationException ( $"Runtime catalog hardpoint lookup failed for {equipment.HardpointType}." ) ;
}
var manufactured = catalog . Items . FirstOrDefault ( item = > ! string . IsNullOrWhiteSpace ( item . ManufacturerLegacyId ) )
? ? throw new InvalidOperationException ( "Runtime catalog has no manufactured item." ) ;
2026-06-15 17:25:40 +01:00
if ( string . IsNullOrWhiteSpace ( manufactured . ManufacturerKey ) | |
catalog . FindCorporation ( manufactured . ManufacturerKey ) = = null | |
catalog . GetManufacturer ( manufactured ) = = null )
2026-06-13 09:15:59 +01:00
{
2026-06-15 17:25:40 +01:00
throw new InvalidOperationException ( $"Runtime catalog typed manufacturer lookup failed for {manufactured.Name}." ) ;
2026-06-13 09:15:59 +01:00
}
2026-06-13 12:24:27 +01:00
var packageCorporation = packageCatalog . Corporations . FirstOrDefault ( corporation = > ! string . IsNullOrWhiteSpace ( corporation . GeonameFileLegacyId ) ) ;
2026-06-13 13:18:03 +01:00
if ( packageCorporation = = null )
{
throw new InvalidOperationException ( "Package catalog store did not read any corporation name-file links." ) ;
}
var packageNameFile = packageCatalog . GetNameFile ( packageCorporation ) ;
2026-06-15 17:25:40 +01:00
if ( string . IsNullOrWhiteSpace ( packageCorporation . GeonameFileKey ) | |
packageCatalog . FindNameFile ( packageCorporation . GeonameFileKey ) = = null | |
packageNameFile = = null | |
string . IsNullOrWhiteSpace ( packageNameFile . NameFileKey ) | |
packageNameFile . Names . Count = = 0 | |
packageNameFile . Names . Count ! = packageNameFile . NameCount )
{
throw new InvalidOperationException ( "Package catalog store did not read typed corporation/name-file links with full names." ) ;
2026-06-13 12:24:27 +01:00
}
2026-06-13 13:18:03 +01:00
if ( packageCorporation . Allegiances . Count = = 0 | | packageCorporation . Allegiances . Count ! = packageCorporation . AllegianceCount )
{
throw new InvalidOperationException ( "Package catalog store did not read corporation allegiance edges." ) ;
}
2026-06-13 09:15:59 +01:00
if ( surface ? . Schema ! = "gamecult.eve.surface.v1" | |
surface . Surface . Id ! = AetheriaCatalogSurfaceProjector . SurfaceId )
{
throw new InvalidOperationException ( "Runtime catalog client did not read the typed Eve surface." ) ;
}
2026-06-13 16:15:03 +01:00
var packageSurface = packageSurfaces . FirstOrDefault ( candidate = > candidate . Surface . Id = = AetheriaCatalogSurfaceProjector . SurfaceId ) ;
if ( packageSurface = = null | |
packageSurface . Schema ! = "gamecult.eve.surface.v1" | |
packageSurface . ProviderId ! = "aetheria" | |
packageSurface . Surface . Root . Kind ! = "surface" | |
packageSurface . Surface . Root . Children . Count = = 0 | |
packageSurface . Commands . All ( command = > command . Command ! = "aetheria.catalog.refresh" ) )
{
throw new InvalidOperationException ( "Package runtime store did not read the typed Eve surface contract from CultCache." ) ;
}
2026-06-13 15:27:12 +01:00
try
{
var commit = AetheriaRuntimeStateCommitLog . QueuePlayerSettings (
commitSmokeStatePath ,
new AetheriaRuntimePlayerSettingsCommit
{
PlayerName = "Unity smoke" ,
TutorialPassed = true ,
ActionBarInputs = new [ ] { "<Keyboard>/1" }
} ) ;
2026-06-14 13:46:08 +01:00
AetheriaRuntimeStateCommitLog . QueueLoadoutTemplate (
commitSmokeStatePath ,
new AetheriaRuntimeLoadoutTemplateCommit
{
Name = "Unity Smoke Loadout" ,
OwnerPlayerKey = "global:aetheria.player_settings.v1" ,
RootEntity = new AetheriaRuntimeEntityLoadoutCommit
{
Name = "Unity Smoke Ship" ,
Kind = "ship" ,
2026-06-15 16:21:31 +01:00
FactionKey = "aetheria.corporation:legacy:smoke:faction" ,
2026-06-14 13:46:08 +01:00
Hull = new AetheriaRuntimeLoadoutItemCommit
{
2026-06-15 00:06:17 +01:00
ItemKey = "aetheria.item_definition:legacy:smoke:hull" ,
2026-06-14 13:46:08 +01:00
Quality = 0.7 ,
Durability = 0.6
} ,
Equipment = new [ ]
{
new AetheriaRuntimeLoadoutItemSlotCommit
{
X = 1 ,
Y = 2 ,
Item = new AetheriaRuntimeLoadoutItemCommit
{
2026-06-15 00:06:17 +01:00
ItemKey = "aetheria.item_definition:legacy:smoke:weapon" ,
2026-06-14 13:46:08 +01:00
Quality = 0.9 ,
2026-06-14 17:13:16 +01:00
Durability = 0.8 ,
2026-06-16 00:01:19 +01:00
Enabled = false ,
OverrideShutdown = true
2026-06-14 13:46:08 +01:00
}
}
} ,
CargoContents = new [ ]
{
new AetheriaRuntimeCargoBayLoadoutCommit
{
Items = new [ ]
{
new AetheriaRuntimeLoadoutItemSlotCommit
{
X = 3 ,
Y = 4 ,
Item = new AetheriaRuntimeLoadoutItemCommit
{
2026-06-15 00:06:17 +01:00
ItemKey = "aetheria.item_definition:legacy:smoke:ore" ,
2026-06-14 13:46:08 +01:00
Quantity = 5
}
}
}
}
} ,
DockingBayAssignments = new [ ] { - 1 } ,
WeaponGroups = new [ ] { new [ ] { 0 } }
}
} ) ;
2026-06-13 15:37:05 +01:00
AetheriaRuntimeStateCommitLog . QueueRunCheckpoint (
commitSmokeStatePath ,
new AetheriaRuntimeRunCheckpointCommit
{
RunId = "smoke-run" ,
2026-06-14 15:12:38 +01:00
GenerationSeed = 424242 ,
2026-06-13 15:37:05 +01:00
CurrentZoneIndex = 0 ,
CurrentZoneEntityIndex = 0 ,
DiscoveredZoneIndices = new [ ] { 0 } ,
2026-06-14 11:53:55 +01:00
ActionBarBindings = new [ ]
{
new AetheriaRuntimeActionBarBindingCommit
{
ControlPath = "<Keyboard>/1" ,
Kind = "weapon_group" ,
WeaponGroup = 0
} ,
new AetheriaRuntimeActionBarBindingCommit
{
ControlPath = "<Keyboard>/2" ,
Kind = "gear" ,
2026-06-15 00:06:17 +01:00
ItemKey = "aetheria.item_definition:legacy:smoke:weapon" ,
2026-06-14 11:53:55 +01:00
EquipmentIndex = 0 ,
BehaviorIndex = 1
}
} ,
2026-06-14 12:02:47 +01:00
FactionRelationships = new [ ]
{
new AetheriaRuntimeFactionRelationshipCommit
{
2026-06-15 16:21:31 +01:00
FactionKey = "aetheria.corporation:legacy:smoke:faction" ,
2026-06-14 12:02:47 +01:00
Relationship = "Friendly" ,
Standing = 3
}
} ,
2026-06-13 15:37:05 +01:00
Zones = new [ ]
{
new AetheriaRuntimeZoneSnapshotCommit
{
ZoneIndex = 0 ,
Name = "Unity Smoke Zone" ,
PositionX = 12.0 ,
PositionY = - 4.0 ,
AdjacentZoneIndices = new [ ] { 1 } ,
OwnerFactionIndex = 0 ,
2026-06-14 12:52:48 +01:00
Orbits = new [ ]
{
new AetheriaRuntimeOrbitSnapshotCommit
{
2026-06-15 16:27:23 +01:00
OrbitKey = "aetheria.orbit:legacy:smoke:orbit" ,
ParentOrbitKey = "aetheria.orbit:legacy:smoke:parent-orbit" ,
2026-06-14 12:52:48 +01:00
Distance = 100.0 ,
Phase = 0.25 ,
FixedPositionX = 5.0 ,
FixedPositionY = - 6.0
}
} ,
Bodies = new [ ]
{
new AetheriaRuntimeBodySnapshotCommit
{
2026-06-15 16:27:23 +01:00
BodyKey = "aetheria.body:legacy:smoke:body" ,
2026-06-14 12:52:48 +01:00
Kind = "asteroid_belt" ,
Name = "Smoke Belt" ,
2026-06-15 16:27:23 +01:00
OrbitKey = "aetheria.orbit:legacy:smoke:orbit" ,
2026-06-14 12:52:48 +01:00
Mass = 42.0 ,
Resources = new [ ]
{
new AetheriaRuntimeBodyResourceCommit
{
2026-06-15 00:06:17 +01:00
ItemKey = "aetheria.item_definition:legacy:smoke:ore" ,
2026-06-14 12:52:48 +01:00
Amount = 3.5
}
} ,
BodyRadiusMultiplier = 1.25 ,
GravityRadiusMultiplier = 2.0 ,
GravityDepthMultiplier = 0.5 ,
GravityDepthExponent = 12.0 ,
Asteroids = new [ ]
{
new AetheriaRuntimeAsteroidCommit
{
Distance = 7.0 ,
Phase = 0.75 ,
Size = 2.0 ,
2026-06-14 16:59:04 +01:00
RotationSpeed = 0.5 ,
Damage = 1.25 ,
RespawnTimer = 6.5 ,
MiningAccumulators = new [ ]
{
new AetheriaRuntimeAsteroidMiningAccumulatorCommit
{
MinerEntityIndex = 0 ,
Amount = 0.75
}
}
2026-06-14 12:52:48 +01:00
}
}
}
} ,
2026-06-13 15:37:05 +01:00
Entities = new [ ]
{
new AetheriaRuntimeEntitySnapshotCommit
{
EntityIndex = 0 ,
Name = "Unity Smoke Ship" ,
Kind = "ship" ,
PositionX = 1.0 ,
PositionY = 2.0 ,
PositionZ = 3.0 ,
DirectionX = 0.0 ,
DirectionY = 1.0 ,
2026-06-15 16:21:31 +01:00
FactionKey = "aetheria.corporation:legacy:smoke:faction" ,
2026-06-14 13:58:46 +01:00
VelocityX = 4.0 ,
VelocityY = - 2.0 ,
TargetEntityIndex = 0 ,
IsActive = true ,
HeatsinksEnabled = false ,
OverrideShutdown = true ,
TractorPower = 12.5 ,
Heatstroke = 0.25 ,
Hypothermia = 0.125 ,
2026-06-15 00:06:17 +01:00
HullItemKey = "aetheria.item_definition:legacy:smoke:hull" ,
2026-06-13 15:37:05 +01:00
Equipment = new [ ]
{
new AetheriaRuntimeLoadoutItemSlotCommit
{
X = 0 ,
Y = 0 ,
Item = new AetheriaRuntimeLoadoutItemCommit
{
2026-06-15 00:06:17 +01:00
ItemKey = "aetheria.item_definition:legacy:smoke:weapon" ,
2026-06-13 15:37:05 +01:00
Quality = 0.9 ,
2026-06-14 17:13:16 +01:00
Durability = 0.8 ,
2026-06-16 00:01:19 +01:00
Enabled = false ,
OverrideShutdown = true
2026-06-13 15:37:05 +01:00
}
}
} ,
2026-06-14 15:32:41 +01:00
CargoContents = new [ ]
{
new AetheriaRuntimeCargoBayLoadoutCommit
{
Items = new [ ]
{
new AetheriaRuntimeLoadoutItemSlotCommit
{
X = 2 ,
Y = 3 ,
Item = new AetheriaRuntimeLoadoutItemCommit
{
2026-06-15 00:06:17 +01:00
ItemKey = "aetheria.item_definition:legacy:smoke:ore" ,
2026-06-14 15:32:41 +01:00
Quantity = 7
}
}
}
}
} ,
DockingBayAssignments = new [ ] { - 1 } ,
2026-06-14 16:46:14 +01:00
Visibility = 12.75 ,
VisibilitySourceCount = 3 ,
2026-06-14 16:51:56 +01:00
Contacts = new [ ]
{
new AetheriaRuntimeEntityContactCommit
{
TargetEntityIndex = 0 ,
InfoGathered = 0.85 ,
Hostile = true ,
Visible = true
}
} ,
2026-06-14 13:03:57 +01:00
WeaponGroups = new [ ] { new [ ] { 0 } } ,
2026-06-14 13:58:46 +01:00
ActiveConsumables = new [ ]
{
new AetheriaRuntimeActiveConsumableCommit
{
2026-06-15 00:06:17 +01:00
ItemKey = "aetheria.item_definition:legacy:smoke:consumable" ,
2026-06-14 13:58:46 +01:00
Quality = 0.75 ,
RemainingDuration = 3.0 ,
Duration = 5.0
}
} ,
2026-06-14 14:08:59 +01:00
BehaviorProgress = new [ ]
{
new AetheriaRuntimeBehaviorProgressCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 0 ,
BehaviorIndex = 1 ,
BehaviorKind = "Cooldown" ,
Progress = 0.5
} ,
new AetheriaRuntimeBehaviorProgressCommit
{
OwnerKind = "active_consumable" ,
OwnerIndex = 0 ,
BehaviorIndex = 0 ,
BehaviorKind = "Shield" ,
Progress = 0.75
}
} ,
2026-06-14 14:19:21 +01:00
WeaponStates = new [ ]
{
new AetheriaRuntimeWeaponStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 0 ,
BehaviorIndex = 1 ,
BehaviorKind = "InstantWeapon" ,
Firing = true ,
Ammo = 2 ,
BurstRemaining = 3 ,
BurstTimer = 0.25 ,
BurstInterval = 0.125 ,
CooldownProgress = 0.5 ,
CoolingDown = true
} ,
new AetheriaRuntimeWeaponStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 1 ,
BehaviorIndex = 0 ,
BehaviorKind = "ChargedWeapon" ,
Ammo = 1 ,
Charging = true ,
Charged = false ,
Charge = 0.8
} ,
new AetheriaRuntimeWeaponStateCommit
{
OwnerKind = "active_consumable" ,
OwnerIndex = 0 ,
BehaviorIndex = 0 ,
BehaviorKind = "ConstantWeapon" ,
Firing = true ,
Ammo = 1 ,
Reloading = true ,
ReloadProgress = 0.4 ,
AmmoIntervalProgress = 0.6
2026-06-14 15:47:15 +01:00
} ,
new AetheriaRuntimeWeaponStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 2 ,
BehaviorIndex = 1 ,
BehaviorKind = "LockWeapon" ,
Ammo = 1 ,
LockProgress = 0.65 ,
LockTargetEntityIndex = 0
2026-06-14 14:19:21 +01:00
}
} ,
2026-06-14 14:29:04 +01:00
BehaviorStates = new [ ]
{
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 0 ,
BehaviorIndex = 2 ,
BehaviorKind = "Sensor" ,
Pinging = true ,
PingCooldown = 0.25 ,
PingLerp = 0.5 ,
PingRadius = 1200.0 ,
PingedEntityCount = 3
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 1 ,
BehaviorIndex = 0 ,
BehaviorKind = "Radiator" ,
RadiatorTemperature = 450.0 ,
Emissivity = 0.8 ,
PumpedHeat = 12.0 ,
WasteHeat = 1.5 ,
EnergyUsage = 2.25
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 2 ,
BehaviorIndex = 0 ,
BehaviorKind = "Reactor" ,
ReactorDraw = 4.5 ,
ReactorLoadRatio = 1.25
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 3 ,
BehaviorIndex = 0 ,
BehaviorKind = "Capacitor" ,
CapacitorCharge = 7.5 ,
CapacitorCapacity = 10.0 ,
CapacitorEfficiency = 0.95
2026-06-14 15:55:03 +01:00
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 4 ,
BehaviorIndex = 0 ,
BehaviorKind = "AetherDrive" ,
AetherDriveAxisX = 0.5 ,
AetherDriveAxisY = - 0.25 ,
AetherDriveAxisZ = 0.75 ,
AetherDriveThrustX = 12.0 ,
AetherDriveThrustY = 6.0 ,
AetherDriveThrustZ = 3.0 ,
AetherDriveRpmX = 1200.0 ,
AetherDriveRpmY = 900.0 ,
AetherDriveRpmZ = 450.0 ,
AetherDriveMaximumRpm = 2400.0 ,
AetherDriveThrustDirectionX = 1.5 ,
AetherDriveThrustDirectionY = - 0.5
2026-06-14 16:01:36 +01:00
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 5 ,
BehaviorIndex = 0 ,
BehaviorKind = "ResourceScanner" ,
2026-06-15 16:41:40 +01:00
ResourceScannerTargetBodyKey = "aetheria.body:legacy:smoke:body" ,
2026-06-14 16:01:36 +01:00
ResourceScannerAsteroidIndex = 2 ,
ResourceScannerScanTime = 1.25 ,
ResourceScannerRange = 500.0 ,
ResourceScannerMinimumDensity = 0.2 ,
ResourceScannerScanDuration = 3.5
2026-06-14 16:07:33 +01:00
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 6 ,
BehaviorIndex = 0 ,
BehaviorKind = "MiningTool" ,
2026-06-15 16:41:40 +01:00
MiningToolAsteroidBeltKey = "aetheria.body:legacy:smoke:body" ,
2026-06-14 16:07:33 +01:00
MiningToolAsteroidIndex = 3 ,
MiningToolRange = 275.0
2026-06-14 16:13:32 +01:00
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 7 ,
BehaviorIndex = 0 ,
BehaviorKind = "Thruster" ,
ThrusterAxis = 0.8 ,
ThrusterThrust = 125.0 ,
ThrusterTorque = - 0.4
2026-06-14 16:20:02 +01:00
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 8 ,
BehaviorIndex = 0 ,
BehaviorKind = "Shield" ,
ShieldEfficiency = 0.7 ,
ShieldEnergyUsage = 1.4
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 9 ,
BehaviorIndex = 0 ,
BehaviorKind = "VelocityLimit" ,
VelocityLimit = 42.0
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 10 ,
BehaviorIndex = 0 ,
BehaviorKind = "Thermotoggle" ,
ThermotoggleTargetTemperature = 315.5
2026-06-14 16:25:23 +01:00
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 11 ,
BehaviorIndex = 0 ,
BehaviorKind = "Switch" ,
SwitchActivated = true
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 12 ,
BehaviorIndex = 0 ,
BehaviorKind = "Trigger" ,
TriggerPulled = true
2026-06-14 16:34:40 +01:00
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 13 ,
BehaviorIndex = 0 ,
BehaviorKind = "StatModifier" ,
StatModifierApplied = true ,
StatModifierExecuted = true ,
StatModifierTargetStatCount = 2
2026-06-14 16:40:08 +01:00
} ,
new AetheriaRuntimeBehaviorStateCommit
{
OwnerKind = "equipment" ,
OwnerIndex = 14 ,
BehaviorIndex = 0 ,
BehaviorKind = "TurretController" ,
TurretControllerWeaponCount = 2 ,
TurretControllerShotSpeed = 80.0 ,
TurretControllerPredictShots = true
2026-06-14 14:29:04 +01:00
}
} ,
2026-06-14 13:03:57 +01:00
StatGrids = new [ ]
{
new AetheriaRuntimeEntityStatGridCommit
{
Name = "temperature" ,
Width = 2 ,
Height = 1 ,
Values = new [ ] { 280.0 , 281.0 }
} ,
new AetheriaRuntimeEntityStatGridCommit
{
Name = "hull_conductivity_x" ,
Width = 2 ,
Height = 1 ,
Values = new [ ] { 1.0 , 0.0 }
}
}
2026-06-13 15:37:05 +01:00
}
}
}
}
} ) ;
2026-06-13 15:27:12 +01:00
var pending = AetheriaRuntimeStateCommitLog . ReadPending ( commitSmokeStatePath ) ;
2026-06-14 13:46:08 +01:00
if ( pending . Count ! = 3 | |
2026-06-13 15:27:12 +01:00
pending [ 0 ] . Kind ! = AetheriaRuntimeCommitKind . PlayerSettings | |
pending [ 0 ] . Schema ! = AetheriaRuntimeStateCommitLog . CommitSchema | |
pending [ 0 ] . Path ! = commit . Path )
{
throw new InvalidOperationException ( "Runtime state commit log did not read the queued player settings command." ) ;
}
2026-06-14 22:26:51 +01:00
AssertPendingCultCacheEnvelope ( commit . Path , AetheriaRuntimeStateCommitDocument . SchemaId ) ;
2026-06-13 15:27:12 +01:00
2026-06-13 22:26:43 +01:00
var typedNodeApplied = false ;
await using ( var commitNode = await AetheriaStateNode . OpenAsync ( commitSmokeStatePath , "aetheria-unity-runtime-commit-smoke" ) )
{
var report = await AetheriaRuntimeCommitLogApplier . ApplyPendingAsync ( commitNode ) ;
var settings = await commitNode . GetPlayerSettingsAsync ( ) ;
2026-06-14 13:46:08 +01:00
var loadout = await commitNode . GetLoadoutTemplateAsync ( new ( "global:aetheria.loadout_template.unity-smoke-loadout.v1" ) ) ;
2026-06-13 22:26:43 +01:00
var run = await commitNode . GetRunStateAsync ( new ( "global:aetheria.run_state.smoke-run.v1" ) ) ;
var zone = await commitNode . GetZoneStateAsync ( new ( "global:aetheria.run_state.smoke-run.zone.0.v1" ) ) ;
var entity = await commitNode . GetEntitySnapshotAsync ( new ( "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" ) ) ;
typedNodeApplied = report . AppliedPlayerSettings = = 1 & &
2026-06-14 13:46:08 +01:00
report . AppliedLoadoutTemplates = = 1 & &
2026-06-13 22:26:43 +01:00
report . AppliedRunCheckpoints = = 1 & &
settings ? . PlayerName = = "Unity smoke" & &
settings . Input . ActionBarInputs . Length = = 1 & &
2026-06-14 13:46:08 +01:00
loadout ? . Name = = "Unity Smoke Loadout" & &
loadout . RootEntity . Hull . ItemKey = = "aetheria.item_definition:legacy:smoke:hull" & &
2026-06-15 16:21:31 +01:00
loadout . RootEntity . FactionKey = = "aetheria.corporation:legacy:smoke:faction" & &
2026-06-14 13:46:08 +01:00
loadout . RootEntity . Equipment . Length = = 1 & &
loadout . RootEntity . Equipment [ 0 ] . Position . X = = 1 & &
2026-06-14 17:13:16 +01:00
! loadout . RootEntity . Equipment [ 0 ] . Item . Enabled & &
2026-06-16 00:01:19 +01:00
loadout . RootEntity . Equipment [ 0 ] . Item . OverrideShutdown & &
2026-06-14 13:46:08 +01:00
loadout . RootEntity . CargoContents . Length = = 1 & &
loadout . RootEntity . CargoContents [ 0 ] . Items [ 0 ] . Item . Quantity = = 5 & &
2026-06-13 22:26:43 +01:00
run ? . ZoneKeys . Length = = 1 & &
2026-06-14 15:12:38 +01:00
run . GenerationSeed = = 424242 & &
2026-06-14 11:53:55 +01:00
run . ActionBarBindings . Length = = 2 & &
run . ActionBarBindings [ 0 ] . ControlPath = = "<Keyboard>/1" & &
run . ActionBarBindings [ 0 ] . Kind = = "weapon_group" & &
run . ActionBarBindings [ 0 ] . WeaponGroup = = 0 & &
run . ActionBarBindings [ 1 ] . ControlPath = = "<Keyboard>/2" & &
run . ActionBarBindings [ 1 ] . Kind = = "gear" & &
run . ActionBarBindings [ 1 ] . TargetKey = = "aetheria.item_definition:legacy:smoke:weapon" & &
run . ActionBarBindings [ 1 ] . EquipmentIndex = = 0 & &
run . ActionBarBindings [ 1 ] . BehaviorIndex = = 1 & &
2026-06-14 12:02:47 +01:00
run . FactionRelationships . Length = = 1 & &
run . FactionRelationships [ 0 ] . FactionKey = = "aetheria.corporation:legacy:smoke:faction" & &
run . FactionRelationships [ 0 ] . Relationship = = "Friendly" & &
run . FactionRelationships [ 0 ] . Standing = = 3 & &
2026-06-13 22:26:43 +01:00
zone ? . EntityKeys . Length = = 1 & &
2026-06-14 12:52:48 +01:00
zone . Orbits . Length = = 1 & &
2026-06-15 16:27:23 +01:00
zone . Orbits [ 0 ] . OrbitId = = "aetheria.orbit:legacy:smoke:orbit" & &
zone . Orbits [ 0 ] . ParentId = = "aetheria.orbit:legacy:smoke:parent-orbit" & &
2026-06-14 12:52:48 +01:00
zone . Orbits [ 0 ] . FixedPosition . X = = 5.0 & &
zone . Bodies . Length = = 1 & &
2026-06-15 16:27:23 +01:00
zone . Bodies [ 0 ] . BodyId = = "aetheria.body:legacy:smoke:body" & &
zone . Bodies [ 0 ] . OrbitId = = "aetheria.orbit:legacy:smoke:orbit" & &
2026-06-14 12:52:48 +01:00
zone . Bodies [ 0 ] . Kind = = "asteroid_belt" & &
zone . Bodies [ 0 ] . Resources . Length = = 1 & &
zone . Bodies [ 0 ] . Resources [ 0 ] . ItemKey = = "aetheria.item_definition:legacy:smoke:ore" & &
zone . Bodies [ 0 ] . Asteroids . Length = = 1 & &
2026-06-14 16:59:04 +01:00
zone . Bodies [ 0 ] . Asteroids [ 0 ] . Damage = = 1.25 & &
zone . Bodies [ 0 ] . Asteroids [ 0 ] . RespawnTimer = = 6.5 & &
zone . Bodies [ 0 ] . Asteroids [ 0 ] . MiningAccumulators . Length = = 1 & &
zone . Bodies [ 0 ] . Asteroids [ 0 ] . MiningAccumulators [ 0 ] . MinerEntityKey = = "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" & &
zone . Bodies [ 0 ] . Asteroids [ 0 ] . MiningAccumulators [ 0 ] . Amount = = 0.75 & &
2026-06-13 22:26:43 +01:00
entity ? . Equipment . Length = = 1 & &
2026-06-15 16:21:31 +01:00
entity . FactionKey = = "aetheria.corporation:legacy:smoke:faction" & &
2026-06-14 15:23:38 +01:00
entity . Equipment [ 0 ] . Quality = = 0.9 & &
entity . Equipment [ 0 ] . Durability = = 0.8 & &
entity . Equipment [ 0 ] . Quantity = = 1 & &
2026-06-14 17:13:16 +01:00
! entity . Equipment [ 0 ] . Enabled & &
2026-06-16 00:01:19 +01:00
entity . Equipment [ 0 ] . OverrideShutdown & &
2026-06-14 13:58:46 +01:00
entity . Velocity . X = = 4.0 & &
entity . Velocity . Y = = - 2.0 & &
entity . TargetEntityKey = = "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" & &
entity . IsActive & &
! entity . HeatsinksEnabled & &
entity . OverrideShutdown & &
entity . TractorPower = = 12.5 & &
entity . Heatstroke = = 0.25 & &
entity . Hypothermia = = 0.125 & &
entity . ActiveConsumables . Length = = 1 & &
2026-06-14 15:32:41 +01:00
entity . CargoContents . Length = = 1 & &
entity . CargoContents [ 0 ] . Items [ 0 ] . Item . Quantity = = 7 & &
entity . DockingBayAssignments . Length = = 1 & &
entity . DockingBayAssignments [ 0 ] = = - 1 & &
2026-06-14 16:46:14 +01:00
entity . Visibility = = 12.75 & &
entity . VisibilitySourceCount = = 3 & &
2026-06-14 16:51:56 +01:00
entity . Contacts . Length = = 1 & &
entity . Contacts [ 0 ] . TargetEntityKey = = "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" & &
entity . Contacts [ 0 ] . InfoGathered = = 0.85 & &
entity . Contacts [ 0 ] . Hostile & &
entity . Contacts [ 0 ] . Visible & &
2026-06-14 13:58:46 +01:00
entity . ActiveConsumables [ 0 ] . ItemKey = = "aetheria.item_definition:legacy:smoke:consumable" & &
entity . ActiveConsumables [ 0 ] . RemainingDuration = = 3.0 & &
2026-06-14 14:08:59 +01:00
entity . BehaviorProgress . Length = = 2 & &
entity . BehaviorProgress [ 0 ] . OwnerKind = = "equipment" & &
entity . BehaviorProgress [ 0 ] . BehaviorKind = = "Cooldown" & &
entity . BehaviorProgress [ 0 ] . Progress = = 0.5 & &
entity . BehaviorProgress [ 1 ] . OwnerKind = = "active_consumable" & &
entity . BehaviorProgress [ 1 ] . Progress = = 0.75 & &
2026-06-14 15:47:15 +01:00
entity . WeaponStates . Length = = 4 & &
2026-06-14 14:19:21 +01:00
entity . WeaponStates [ 0 ] . BehaviorKind = = "InstantWeapon" & &
entity . WeaponStates [ 0 ] . Firing & &
entity . WeaponStates [ 0 ] . Ammo = = 2 & &
entity . WeaponStates [ 0 ] . BurstRemaining = = 3 & &
entity . WeaponStates [ 0 ] . CooldownProgress = = 0.5 & &
entity . WeaponStates [ 0 ] . CoolingDown & &
entity . WeaponStates [ 1 ] . BehaviorKind = = "ChargedWeapon" & &
entity . WeaponStates [ 1 ] . Charging & &
entity . WeaponStates [ 1 ] . Charge = = 0.8 & &
entity . WeaponStates [ 2 ] . OwnerKind = = "active_consumable" & &
entity . WeaponStates [ 2 ] . BehaviorKind = = "ConstantWeapon" & &
entity . WeaponStates [ 2 ] . Reloading & &
entity . WeaponStates [ 2 ] . AmmoIntervalProgress = = 0.6 & &
2026-06-14 15:47:15 +01:00
entity . WeaponStates [ 3 ] . BehaviorKind = = "LockWeapon" & &
entity . WeaponStates [ 3 ] . LockProgress = = 0.65 & &
entity . WeaponStates [ 3 ] . LockTargetEntityKey = = "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" & &
2026-06-14 16:40:08 +01:00
entity . BehaviorStates . Length = = 15 & &
2026-06-14 14:29:04 +01:00
entity . BehaviorStates [ 0 ] . BehaviorKind = = "Sensor" & &
entity . BehaviorStates [ 0 ] . Pinging & &
entity . BehaviorStates [ 0 ] . PingRadius = = 1200.0 & &
entity . BehaviorStates [ 1 ] . BehaviorKind = = "Radiator" & &
entity . BehaviorStates [ 1 ] . RadiatorTemperature = = 450.0 & &
entity . BehaviorStates [ 1 ] . PumpedHeat = = 12.0 & &
entity . BehaviorStates [ 2 ] . BehaviorKind = = "Reactor" & &
entity . BehaviorStates [ 2 ] . ReactorLoadRatio = = 1.25 & &
entity . BehaviorStates [ 3 ] . BehaviorKind = = "Capacitor" & &
entity . BehaviorStates [ 3 ] . CapacitorCharge = = 7.5 & &
entity . BehaviorStates [ 3 ] . CapacitorEfficiency = = 0.95 & &
2026-06-14 15:55:03 +01:00
entity . BehaviorStates [ 4 ] . BehaviorKind = = "AetherDrive" & &
entity . BehaviorStates [ 4 ] . AetherDriveAxisX = = 0.5 & &
entity . BehaviorStates [ 4 ] . AetherDriveRpmY = = 900.0 & &
entity . BehaviorStates [ 4 ] . AetherDriveMaximumRpm = = 2400.0 & &
entity . BehaviorStates [ 4 ] . AetherDriveThrustDirectionY = = - 0.5 & &
2026-06-14 16:01:36 +01:00
entity . BehaviorStates [ 5 ] . BehaviorKind = = "ResourceScanner" & &
2026-06-15 16:41:40 +01:00
entity . BehaviorStates [ 5 ] . ResourceScannerTargetBodyId = = "aetheria.body:legacy:smoke:body" & &
2026-06-14 16:01:36 +01:00
entity . BehaviorStates [ 5 ] . ResourceScannerAsteroidIndex = = 2 & &
entity . BehaviorStates [ 5 ] . ResourceScannerScanTime = = 1.25 & &
entity . BehaviorStates [ 5 ] . ResourceScannerScanDuration = = 3.5 & &
2026-06-14 16:07:33 +01:00
entity . BehaviorStates [ 6 ] . BehaviorKind = = "MiningTool" & &
2026-06-15 16:41:40 +01:00
entity . BehaviorStates [ 6 ] . MiningToolAsteroidBeltId = = "aetheria.body:legacy:smoke:body" & &
2026-06-14 16:07:33 +01:00
entity . BehaviorStates [ 6 ] . MiningToolAsteroidIndex = = 3 & &
entity . BehaviorStates [ 6 ] . MiningToolRange = = 275.0 & &
2026-06-14 16:13:32 +01:00
entity . BehaviorStates [ 7 ] . BehaviorKind = = "Thruster" & &
entity . BehaviorStates [ 7 ] . ThrusterAxis = = 0.8 & &
entity . BehaviorStates [ 7 ] . ThrusterThrust = = 125.0 & &
entity . BehaviorStates [ 7 ] . ThrusterTorque = = - 0.4 & &
2026-06-14 16:20:02 +01:00
entity . BehaviorStates [ 8 ] . BehaviorKind = = "Shield" & &
entity . BehaviorStates [ 8 ] . ShieldEfficiency = = 0.7 & &
entity . BehaviorStates [ 8 ] . ShieldEnergyUsage = = 1.4 & &
entity . BehaviorStates [ 9 ] . BehaviorKind = = "VelocityLimit" & &
entity . BehaviorStates [ 9 ] . VelocityLimit = = 42.0 & &
entity . BehaviorStates [ 10 ] . BehaviorKind = = "Thermotoggle" & &
entity . BehaviorStates [ 10 ] . ThermotoggleTargetTemperature = = 315.5 & &
2026-06-14 16:25:23 +01:00
entity . BehaviorStates [ 11 ] . BehaviorKind = = "Switch" & &
entity . BehaviorStates [ 11 ] . SwitchActivated & &
entity . BehaviorStates [ 12 ] . BehaviorKind = = "Trigger" & &
entity . BehaviorStates [ 12 ] . TriggerPulled & &
2026-06-14 16:34:40 +01:00
entity . BehaviorStates [ 13 ] . BehaviorKind = = "StatModifier" & &
entity . BehaviorStates [ 13 ] . StatModifierApplied & &
entity . BehaviorStates [ 13 ] . StatModifierExecuted & &
entity . BehaviorStates [ 13 ] . StatModifierTargetStatCount = = 2 & &
2026-06-14 16:40:08 +01:00
entity . BehaviorStates [ 14 ] . BehaviorKind = = "TurretController" & &
entity . BehaviorStates [ 14 ] . TurretControllerWeaponCount = = 2 & &
entity . BehaviorStates [ 14 ] . TurretControllerShotSpeed = = 80.0 & &
entity . BehaviorStates [ 14 ] . TurretControllerPredictShots & &
2026-06-13 22:26:43 +01:00
entity . WeaponGroups . Length = = 1 & &
2026-06-14 13:03:57 +01:00
entity . StatGrids . Length = = 2 & &
entity . StatGrids . Any ( grid = > grid . Name = = "temperature" & & grid . Values . Length = = 2 & & grid . Values [ 1 ] = = 281.0 ) & &
entity . StatGrids . Any ( grid = > grid . Name = = "hull_conductivity_x" & & grid . Values . Length = = 2 & & grid . Values [ 0 ] = = 1.0 ) & &
2026-06-13 22:26:43 +01:00
AetheriaRuntimeStateCommitLog . ReadPending ( commitSmokeStatePath ) . Count = = 0 ;
}
var packageSettings = AetheriaRuntimeCatalogStore . ReadPlayerSettings ( commitSmokeStatePath ) ;
2026-06-14 13:46:08 +01:00
var packageLoadouts = AetheriaRuntimeCatalogStore . ReadLoadoutTemplates ( commitSmokeStatePath ) ;
2026-06-14 14:54:41 +01:00
var packageRuns = AetheriaRuntimeCatalogStore . ReadRunStates ( commitSmokeStatePath ) ;
var packageZones = AetheriaRuntimeCatalogStore . ReadZoneStates ( commitSmokeStatePath ) ;
var packageEntities = AetheriaRuntimeCatalogStore . ReadEntitySnapshots ( commitSmokeStatePath ) ;
2026-06-13 22:26:43 +01:00
if ( ! typedNodeApplied | |
packageSettings ? . PlayerName ! = "Unity smoke" | |
packageSettings . TutorialPassed ! = true | |
2026-06-14 13:46:08 +01:00
packageSettings . ActionBarInputs . Count ! = 1 | |
packageLoadouts . Count ! = 1 | |
packageLoadouts [ 0 ] . RootEntity . Hull . ItemKey ! = "aetheria.item_definition:legacy:smoke:hull" | |
2026-06-15 16:21:31 +01:00
packageLoadouts [ 0 ] . RootEntity . FactionKey ! = "aetheria.corporation:legacy:smoke:faction" | |
2026-06-14 13:46:08 +01:00
packageLoadouts [ 0 ] . RootEntity . Equipment [ 0 ] . X ! = 1 | |
2026-06-14 17:13:16 +01:00
packageLoadouts [ 0 ] . RootEntity . Equipment [ 0 ] . Item . Enabled | |
2026-06-16 00:01:19 +01:00
! packageLoadouts [ 0 ] . RootEntity . Equipment [ 0 ] . Item . OverrideShutdown | |
2026-06-14 14:54:41 +01:00
packageLoadouts [ 0 ] . RootEntity . CargoContents [ 0 ] . Items [ 0 ] . Item . Quantity ! = 5 | |
packageRuns . Count ! = 1 | |
packageRuns [ 0 ] . RunId ! = "smoke-run" | |
2026-06-14 15:12:38 +01:00
packageRuns [ 0 ] . GenerationSeed ! = 424242 | |
2026-06-14 14:54:41 +01:00
packageRuns [ 0 ] . ZoneKeys . Count ! = 1 | |
packageRuns [ 0 ] . ActionBarBindings . Count ! = 2 | |
packageRuns [ 0 ] . ActionBarBindings [ 1 ] . TargetKey ! = "aetheria.item_definition:legacy:smoke:weapon" | |
packageRuns [ 0 ] . FactionRelationships . Count ! = 1 | |
packageRuns [ 0 ] . FactionRelationships [ 0 ] . FactionKey ! = "aetheria.corporation:legacy:smoke:faction" | |
packageZones . Count ! = 1 | |
packageZones [ 0 ] . Name ! = "Unity Smoke Zone" | |
packageZones [ 0 ] . EntityKeys . Count ! = 1 | |
packageZones [ 0 ] . Orbits . Count ! = 1 | |
2026-06-15 16:27:23 +01:00
packageZones [ 0 ] . Orbits [ 0 ] . OrbitId ! = "aetheria.orbit:legacy:smoke:orbit" | |
packageZones [ 0 ] . Orbits [ 0 ] . ParentId ! = "aetheria.orbit:legacy:smoke:parent-orbit" | |
2026-06-14 14:54:41 +01:00
packageZones [ 0 ] . Orbits [ 0 ] . FixedPositionX ! = 5.0 | |
packageZones [ 0 ] . Bodies . Count ! = 1 | |
2026-06-15 16:27:23 +01:00
packageZones [ 0 ] . Bodies [ 0 ] . BodyId ! = "aetheria.body:legacy:smoke:body" | |
packageZones [ 0 ] . Bodies [ 0 ] . OrbitId ! = "aetheria.orbit:legacy:smoke:orbit" | |
2026-06-14 14:54:41 +01:00
packageZones [ 0 ] . Bodies [ 0 ] . ResourceCount ! = 1 | |
packageZones [ 0 ] . Bodies [ 0 ] . AsteroidCount ! = 1 | |
2026-06-14 16:59:04 +01:00
packageZones [ 0 ] . Bodies [ 0 ] . DamagedAsteroidCount ! = 1 | |
packageZones [ 0 ] . Bodies [ 0 ] . RespawningAsteroidCount ! = 1 | |
packageZones [ 0 ] . Bodies [ 0 ] . AsteroidMiningAccumulatorCount ! = 1 | |
2026-06-14 14:54:41 +01:00
packageEntities . Count ! = 1 | |
packageEntities [ 0 ] . Name ! = "Unity Smoke Ship" | |
2026-06-15 16:21:31 +01:00
packageEntities [ 0 ] . FactionKey ! = "aetheria.corporation:legacy:smoke:faction" | |
2026-06-14 15:23:38 +01:00
packageEntities [ 0 ] . Equipment [ 0 ] . Quality ! = 0.9 | |
packageEntities [ 0 ] . Equipment [ 0 ] . Durability ! = 0.8 | |
packageEntities [ 0 ] . Equipment [ 0 ] . Quantity ! = 1 | |
2026-06-14 17:13:16 +01:00
packageEntities [ 0 ] . Equipment [ 0 ] . Enabled | |
2026-06-16 00:01:19 +01:00
! packageEntities [ 0 ] . Equipment [ 0 ] . OverrideShutdown | |
2026-06-14 14:54:41 +01:00
packageEntities [ 0 ] . VelocityX ! = 4.0 | |
packageEntities [ 0 ] . VelocityY ! = - 2.0 | |
packageEntities [ 0 ] . TargetEntityKey ! = "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" | |
packageEntities [ 0 ] . ActiveConsumables . Count ! = 1 | |
2026-06-14 15:32:41 +01:00
packageEntities [ 0 ] . CargoContents . Count ! = 1 | |
packageEntities [ 0 ] . CargoContents [ 0 ] . Items [ 0 ] . Item . Quantity ! = 7 | |
packageEntities [ 0 ] . DockingBayAssignments . Count ! = 1 | |
packageEntities [ 0 ] . DockingBayAssignments [ 0 ] ! = - 1 | |
2026-06-14 16:46:14 +01:00
packageEntities [ 0 ] . Visibility ! = 12.75 | |
packageEntities [ 0 ] . VisibilitySourceCount ! = 3 | |
2026-06-14 16:51:56 +01:00
packageEntities [ 0 ] . Contacts . Count ! = 1 | |
packageEntities [ 0 ] . Contacts [ 0 ] . TargetEntityKey ! = "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" | |
packageEntities [ 0 ] . Contacts [ 0 ] . InfoGathered ! = 0.85 | |
! packageEntities [ 0 ] . Contacts [ 0 ] . Hostile | |
! packageEntities [ 0 ] . Contacts [ 0 ] . Visible | |
2026-06-14 14:54:41 +01:00
packageEntities [ 0 ] . ActiveConsumables [ 0 ] . ItemKey ! = "aetheria.item_definition:legacy:smoke:consumable" | |
packageEntities [ 0 ] . BehaviorProgress . Count ! = 2 | |
2026-06-14 15:47:15 +01:00
packageEntities [ 0 ] . WeaponStates . Count ! = 4 | |
2026-06-14 14:54:41 +01:00
packageEntities [ 0 ] . WeaponStates [ 2 ] . AmmoIntervalProgress ! = 0.6 | |
2026-06-14 15:47:15 +01:00
packageEntities [ 0 ] . WeaponStates [ 3 ] . LockProgress ! = 0.65 | |
packageEntities [ 0 ] . WeaponStates [ 3 ] . LockTargetEntityKey ! = "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" | |
2026-06-14 16:40:08 +01:00
packageEntities [ 0 ] . BehaviorStates . Count ! = 15 | |
2026-06-14 14:54:41 +01:00
packageEntities [ 0 ] . BehaviorStates [ 3 ] . CapacitorCharge ! = 7.5 | |
2026-06-14 15:55:03 +01:00
packageEntities [ 0 ] . BehaviorStates [ 4 ] . AetherDriveRpmY ! = 900.0 | |
packageEntities [ 0 ] . BehaviorStates [ 4 ] . AetherDriveMaximumRpm ! = 2400.0 | |
2026-06-15 16:41:40 +01:00
packageEntities [ 0 ] . BehaviorStates [ 5 ] . ResourceScannerTargetBodyId ! = "aetheria.body:legacy:smoke:body" | |
2026-06-14 16:01:36 +01:00
packageEntities [ 0 ] . BehaviorStates [ 5 ] . ResourceScannerScanDuration ! = 3.5 | |
2026-06-15 16:41:40 +01:00
packageEntities [ 0 ] . BehaviorStates [ 6 ] . MiningToolAsteroidBeltId ! = "aetheria.body:legacy:smoke:body" | |
2026-06-14 16:07:33 +01:00
packageEntities [ 0 ] . BehaviorStates [ 6 ] . MiningToolRange ! = 275.0 | |
2026-06-14 16:13:32 +01:00
packageEntities [ 0 ] . BehaviorStates [ 7 ] . ThrusterAxis ! = 0.8 | |
packageEntities [ 0 ] . BehaviorStates [ 7 ] . ThrusterThrust ! = 125.0 | |
2026-06-14 16:20:02 +01:00
packageEntities [ 0 ] . BehaviorStates [ 8 ] . ShieldEfficiency ! = 0.7 | |
packageEntities [ 0 ] . BehaviorStates [ 9 ] . VelocityLimit ! = 42.0 | |
packageEntities [ 0 ] . BehaviorStates [ 10 ] . ThermotoggleTargetTemperature ! = 315.5 | |
2026-06-14 16:25:23 +01:00
! packageEntities [ 0 ] . BehaviorStates [ 11 ] . SwitchActivated | |
! packageEntities [ 0 ] . BehaviorStates [ 12 ] . TriggerPulled | |
2026-06-14 16:34:40 +01:00
! packageEntities [ 0 ] . BehaviorStates [ 13 ] . StatModifierApplied | |
packageEntities [ 0 ] . BehaviorStates [ 13 ] . StatModifierTargetStatCount ! = 2 | |
2026-06-14 16:40:08 +01:00
packageEntities [ 0 ] . BehaviorStates [ 14 ] . TurretControllerWeaponCount ! = 2 | |
packageEntities [ 0 ] . BehaviorStates [ 14 ] . TurretControllerShotSpeed ! = 80.0 | |
! packageEntities [ 0 ] . BehaviorStates [ 14 ] . TurretControllerPredictShots | |
2026-06-14 14:54:41 +01:00
packageEntities [ 0 ] . StatGrids . Count ! = 2 | |
packageEntities [ 0 ] . StatGrids . All ( grid = > grid . Name ! = "temperature" | | grid . Values . Count ! = 2 | | grid . Values [ 1 ] ! = 281.0 ) )
2026-06-13 15:27:12 +01:00
{
2026-06-13 22:26:43 +01:00
throw new InvalidOperationException (
2026-06-14 13:46:08 +01:00
"Runtime state commit log did not apply queued settings/loadout/run snapshots through the typed state node. " +
2026-06-14 14:54:41 +01:00
$"typedNodeApplied={typedNodeApplied}, packageSettings={(packageSettings == null ? " null " : $" { packageSettings . PlayerName } / { packageSettings . TutorialPassed } / { packageSettings . ActionBarInputs . Count } ")}, packageLoadouts={packageLoadouts.Count}, packageRuns={packageRuns.Count}, packageZones={packageZones.Count}, packageEntities={packageEntities.Count}" ) ;
2026-06-13 15:27:12 +01:00
}
2026-06-13 16:44:24 +01:00
var eveCommand = AetheriaRuntimeEveCommandLog . QueueCommand (
commitSmokeStatePath ,
new EveSurfaceCommandRequest (
"aetheria" ,
"aetheria.catalog.operator" ,
"aetheria.catalog.refresh" ,
new Dictionary < string , string > { [ "source" ] = "unity-smoke" } ,
DateTimeOffset . UtcNow ,
"aetheria-state-unity-smoke" ) ) ;
var evePending = AetheriaRuntimeEveCommandLog . ReadPending ( commitSmokeStatePath ) ;
if ( evePending . Count ! = 1 | |
evePending [ 0 ] . Schema ! = AetheriaRuntimeEveCommandLog . CommandSchema | |
evePending [ 0 ] . CommandId ! = eveCommand . CommandId | |
evePending [ 0 ] . ProviderId ! = "aetheria" | |
evePending [ 0 ] . SurfaceId ! = "aetheria.catalog.operator" | |
evePending [ 0 ] . Command ! = "aetheria.catalog.refresh" | |
evePending [ 0 ] . Payload [ "source" ] ! = "unity-smoke" | |
AetheriaRuntimeStateCommitLog . ReadPending ( commitSmokeStatePath ) . Count ! = 0 )
{
throw new InvalidOperationException ( "Runtime Eve command log did not preserve typed command envelopes separately from state commits." ) ;
}
2026-06-14 22:26:51 +01:00
AssertPendingCultCacheEnvelope ( eveCommand . Path , AetheriaRuntimeEveCommandDocument . SchemaId ) ;
2026-06-13 15:27:12 +01:00
}
finally
{
2026-06-13 22:26:43 +01:00
if ( Environment . GetEnvironmentVariable ( "AETHERIA_KEEP_SMOKE_STATE" ) = = "1" )
Console . Error . WriteLine ( $"Kept smoke state: {commitSmokeDirectory}" ) ;
else
Directory . Delete ( commitSmokeDirectory , true ) ;
2026-06-13 15:27:12 +01:00
}
2026-06-13 09:15:59 +01:00
Console . WriteLine ( $"Aetheria Unity runtime catalog smoke passed: {statePath}" ) ;
Console . WriteLine ( $"Items/trade/equipment: {catalog.Items.Count}/{catalog.TradeItems.Count}/{catalog.EquipmentItems.Count}" ) ;
2026-06-13 09:32:24 +01:00
Console . WriteLine ( $"Shape mask sample: {shaped.Name} {shaped.ShapeWidth}x{shaped.ShapeHeight}/{shaped.ShapeCells.Count}" ) ;
2026-06-13 09:47:25 +01:00
Console . WriteLine ( $"Interior/hardpoint sample: {interior.Name} {interior.InteriorShapeCells.Count}; {hardpointHost.Name} {hardpoint.Type} {hardpoint.ShapeCells.Count}" ) ;
2026-06-13 10:01:20 +01:00
Console . WriteLine ( $"Behavior payload sample: {behaviorHost.Name} {behaviorPayload.Kind}/{behaviorPayload.Fields.Count}" ) ;
2026-06-13 09:15:59 +01:00
Console . WriteLine ( $"Behavior sample: {behaviorKind}" ) ;
Console . WriteLine ( $"Eve surface: {surface.Surface.Id}" ) ;
2026-06-13 16:15:03 +01:00
Console . WriteLine ( $"Package Eve surfaces: {packageSurfaces.Count}" ) ;
2026-06-14 13:46:08 +01:00
Console . WriteLine ( "Runtime state commit log smoke: settings, loadouts, action-bar bindings, faction relationships, and run zone/entity snapshots queued, applied, and cleared" ) ;
2026-06-13 16:44:24 +01:00
Console . WriteLine ( "Runtime Eve command log smoke: surface command queued separately from state commits" ) ;
2026-06-14 22:26:51 +01:00
static void AssertPendingCultCacheEnvelope ( string path , string expectedSchemaId )
{
var reader = new MessagePackReader ( File . ReadAllBytes ( path ) ) ;
var fieldCount = reader . ReadArrayHeader ( ) ;
if ( fieldCount < 3 )
{
throw new InvalidOperationException ( $"Pending file {path} is not a CultCache store snapshot." ) ;
}
var formatVersion = reader . ReadString ( ) ;
if ( formatVersion ! = "cultcache.store.v1" )
{
throw new InvalidOperationException ( $"Pending file {path} has format '{formatVersion}', not cultcache.store.v1." ) ;
}
var catalogCount = reader . ReadArrayHeader ( ) ;
var catalogHasSchema = false ;
for ( var index = 0 ; index < catalogCount ; index + + )
{
var catalogFieldCount = reader . ReadArrayHeader ( ) ;
var schemaId = catalogFieldCount > 0 ? reader . ReadString ( ) : "" ;
catalogHasSchema | = schemaId = = expectedSchemaId ;
for ( var field = 1 ; field < catalogFieldCount ; field + + )
{
reader . Skip ( ) ;
}
}
var recordCount = reader . ReadArrayHeader ( ) ;
if ( recordCount ! = 1 )
{
throw new InvalidOperationException ( $"Pending file {path} should contain one CultCache record, found {recordCount}." ) ;
}
var recordFieldCount = reader . ReadArrayHeader ( ) ;
if ( recordFieldCount < 4 )
{
throw new InvalidOperationException ( $"Pending file {path} has an incomplete CultCache record." ) ;
}
var key = reader . ReadString ( ) ;
var recordSchemaId = reader . ReadString ( ) ;
reader . Skip ( ) ;
var payload = reader . ReadBytes ( ) ;
var payloadLength = payload ? . Length ? ? 0 ;
if ( ! catalogHasSchema | | recordSchemaId ! = expectedSchemaId | | string . IsNullOrWhiteSpace ( key ) | | payloadLength = = 0 )
{
throw new InvalidOperationException ( $"Pending file {path} does not publish a typed CultCache record for {expectedSchemaId}." ) ;
}
}
2026-06-15 16:10:13 +01:00
static int CountRequiredBehaviorItemRefsMissingItemKeys ( AetheriaRuntimeBehaviorPayload payload )
{
return payload . Fields . Count ( field = >
IsBehaviorItemRefField ( payload . Kind , field . Key ) & &
IsNonEmptyLegacyRefMissingItemKey ( field . Value ) ) ;
}
static bool IsBehaviorItemRefField ( string behaviorKind , int fieldKey )
{
return ( string . Equals ( behaviorKind , "ItemUsage" , StringComparison . OrdinalIgnoreCase ) & & fieldKey = = 1 ) | |
( IsWeaponBehavior ( behaviorKind ) & & fieldKey = = 12 ) ;
}
static bool IsWeaponBehavior ( string behaviorKind )
{
return behaviorKind is "GuidedWeapon" or "InstantWeapon" or "ConstantWeapon" or "ChargedWeapon" or "AutoWeapon" or "LockWeapon" ;
}
static bool IsNonEmptyLegacyRefMissingItemKey ( AetheriaRuntimeBehaviorValue value )
{
return string . Equals ( value . Kind , "legacy-id" , StringComparison . OrdinalIgnoreCase ) & &
! IsEmptyLegacyId ( value . LegacyIdValue ) & &
string . IsNullOrWhiteSpace ( value . ItemKeyValue ) ;
}
static bool IsEmptyLegacyId ( string legacyId )
{
return string . IsNullOrWhiteSpace ( legacyId ) | |
( Guid . TryParse ( legacyId , out var parsed ) & & parsed = = Guid . Empty ) ;
}