Class Simulation

Namespace
TDMaker.Core
Assembly
TDMaker.Core.dll

A deterministic fixed-step world. Use commands for player actions and ClearEvents after reading output.

public sealed class Simulation
Inheritance
Simulation
Inherited Members

Constructors

Simulation(TemplateRegistry, LevelDef, SimConfig, uint)

Creates and prewarms a world; no engine APIs or background clocks are used.

public Simulation(TemplateRegistry templates, LevelDef level, SimConfig config = null, uint seed = 1)

Parameters

templates TemplateRegistry
level LevelDef
config SimConfig
seed uint

Properties

ActiveBeamCount

Unfinished budget channels, included in completion accounting.

public int ActiveBeamCount { get; }

Property Value

int

ActiveChainCount

Unfinished chain executions, included in level completion accounting.

public int ActiveChainCount { get; }

Property Value

int

Beams

Live and pending-removal budget channels in creation order.

public IReadOnlyList<BeamBinding> Beams { get; }

Property Value

IReadOnlyList<BeamBinding>

CapacityFailureCount

Number of fixed-pool saturation incidents.

public long CapacityFailureCount { get; }

Property Value

long

Config

Immutable simulation settings.

public SimConfig Config { get; }

Property Value

SimConfig

DeltaTime

Seconds per fixed step.

public float DeltaTime { get; }

Property Value

float

DroppedDamageCount

Number of damage requests rejected by the configured per-tick capacity.

public long DroppedDamageCount { get; }

Property Value

long

DroppedEventCount

Number of notifications dropped because the caller did not drain the fixed event buffer.

public long DroppedEventCount { get; }

Property Value

long

Effects

Attached effect and region lifecycle service.

public EffectService Effects { get; }

Property Value

EffectService

Entities

Runtime entity state and deferred queues.

public EntityStore Entities { get; }

Property Value

EntityStore

Events

Events retained until ClearEvents is called.

public IReadOnlyList<SimEvent> Events { get; }

Property Value

IReadOnlyList<SimEvent>

Level

Immutable baked level.

public LevelDef Level { get; }

Property Value

LevelDef

PendingRecoveryCount

Pending same-identity returns, successor preparation and body consumption. Unreserved bodies do not hold victory.

public int PendingRecoveryCount { get; }

Property Value

int

QueuedDamageCount

Current FIFO length, for allocation-free diagnostics.

public int QueuedDamageCount { get; }

Property Value

int

Random

The seeded simulation random stream.

public SimRandom Random { get; }

Property Value

SimRandom

RangeYScale

Range multiplier after applying the level override.

public float RangeYScale { get; }

Property Value

float

Remains

Neutral bodies in stable creation order, including exclusive reservations.

public IReadOnlyList<RemainsRecord> Remains { get; }

Property Value

IReadOnlyList<RemainsRecord>

ScheduledActionCount

Pending summon/strike sequences, for diagnostics.

public int ScheduledActionCount { get; }

Property Value

int

Seed

Original random seed, also stored by command recordings.

public uint Seed { get; }

Property Value

uint

SpatialRebuildCount

Enemy and friendly spatial rebuild count, excluded from deterministic state.

public long SpatialRebuildCount { get; }

Property Value

long

Spells

Spell states in Level.AvailableSpells order; unresolved legacy slots remain locked.

public IReadOnlyList<SpellState> Spells { get; }

Property Value

IReadOnlyList<SpellState>

State

Read-only global state.

public GameState State { get; }

Property Value

GameState

SystemPipeline

Read-only metadata snapshot in actual execution order. Refetch after setup-time RegisterSystem calls; unchanged during stepping.

public IReadOnlyList<SimSystemInfo> SystemPipeline { get; }

Property Value

IReadOnlyList<SimSystemInfo>

Templates

Resolved immutable template definitions.

public TemplateRegistry Templates { get; }

Property Value

TemplateRegistry

Time

Game time derived from completed fixed ticks.

public double Time { get; }

Property Value

double

Traps

Live and pending-removal deployments in creation order.

public IReadOnlyList<TrapBinding> Traps { get; }

Property Value

IReadOnlyList<TrapBinding>

UpgradeFingerprint

Stable setup fingerprint of the permanent-upgrade snapshot and applied definitions; zero identifies legacy setup.

public ulong UpgradeFingerprint { get; }

Property Value

ulong

Methods

AddHeroExperience(int, double)

Queues nonnegative raw hero experience for the progression stage.

public bool AddHeroExperience(int entityId, double amount)

Parameters

entityId int
amount double

Returns

bool

CancelBeam(int)

Cancels a channel at the next mechanism stage.

public bool CancelBeam(int beamId)

Parameters

beamId int

Returns

bool

ClearEvents()

Clears consumed events while retaining their backing capacity.

public void ClearEvents()

ComputeStateHash()

Hashes authoritative runtime state at a tick boundary, including pending work and RNG. Events and render-clock backlog are excluded.

public ulong ComputeStateHash()

Returns

ulong

Examples

ulong checkpoint = sim.ComputeStateHash();

Remarks

Use identical definitions, extension registration and seed. Extensions must contribute their mutable state via IStateHashContributor. Exact floating-point bits diagnose same-runtime divergence; this is not a cross-platform numeric determinism guarantee.

ConfigureSpatialIndex(float, bool)

Configures horizontal grid cell size before stepping. Disabling it selects the Id-ordered linear backend for profiling.

public void ConfigureSpatialIndex(float cellSize = 4, bool enabled = true)

Parameters

cellSize float
enabled bool

Examples

sim.ConfigureSpatialIndex(cellSize: 4);

Deploy(DeploymentPlanDef, int)

Atomically reserves one seeded path-node site and one trap slot. Zero means no candidate, invalid producer, quota or capacity.

public int Deploy(DeploymentPlanDef plan, int sourceId)

Parameters

plan DeploymentPlanDef
sourceId int

Returns

int

Enqueue(ICommand)

Queues an immutable command for the next tick; input allocation is outside Step.

public void Enqueue(ICommand command)

Parameters

command ICommand

FindDefaultTarget(in TargetQuery)

Uses the built-in priority scoring and Id tie-breaks without invoking the custom selector. Safe to call from ITargetSelector.Select.

public Entity FindDefaultTarget(in TargetQuery query)

Parameters

query TargetQuery

Returns

Entity

Examples

return simulation.FindDefaultTarget(query);

Remarks

Uses separate reusable storage and leaves the custom selector's candidate buffer unchanged.

FindTarget(in TargetQuery)

Finds a ranged target using the registered selector or the original scoring and Id tie-breaks.

public Entity FindTarget(in TargetQuery query)

Parameters

query TargetQuery

Returns

Entity

GetTowerAtSlot(int)

Reads a reserved or committed tower at a construction slot, or zero.

public int GetTowerAtSlot(int slotIndex)

Parameters

slotIndex int

Returns

int

IsEligibleTarget(Entity, in TargetQuery)

Checks membership, lifecycle, faction, flight filters and the query's elliptical range.

public bool IsEligibleTarget(Entity target, in TargetQuery query)

Parameters

target Entity
query TargetQuery

Returns

bool

PlaceTrap(TrapDef, Vec2, int)

Places a validated deployment without allocating. Returns zero on invalid placement/source, population limit or pool exhaustion.

public int PlaceTrap(TrapDef definition, Vec2 desired, int sourceId = 0)

Parameters

definition TrapDef
desired Vec2
sourceId int

Returns

int

PredictTargetPosition(int, float)

Predicts fixed-course aim by traversing path segments from the current position at observed movement speed. Blocked or stationary targets are not led.

public Vec2 PredictTargetPosition(int entityId, float seconds)

Parameters

entityId int
seconds float

Returns

Vec2

Remarks

Uses continuous world distance, including connection gaps, rather than rounding to an authored node. Does not anticipate later control changes.

PreviewEarlyCallReward()

Previews the next manual wave call at current fixed time, including its gold and shared spell time credit.

public EarlyCallRewardPreview PreviewEarlyCallReward()

Returns

EarlyCallRewardPreview

Examples

EarlyCallRewardPreview reward = sim.PreviewEarlyCallReward();

PreviewEarlyCallSpellCooldownCut(int)

Previews the exact reduction of one spell's remaining cooldown if the next wave is called now.

public float PreviewEarlyCallSpellCooldownCut(int spellIndex)

Parameters

spellIndex int

Returns

float

PreviewSellRefund(int)

Returns the same nominal refund reported by TowerSold, before wallet saturation. Invalid, removing or non-tower entities return zero.

public int PreviewSellRefund(int towerId)

Parameters

towerId int

Returns

int

Examples

int refund = sim.PreviewSellRefund(tower.Id);

PublishEvent(SimEvent)

Publishes an event in the reserved custom range. Uses the normal fixed-capacity event buffer.

public void PublishEvent(SimEvent value)

Parameters

value SimEvent

Examples

sim.PublishEvent(new SimEvent((SimEventKind)((int)SimEventKind.CustomStart + 1), actor.Id));

QueryEnemies(Vec2, float, SpatialQueryBuffer)

Queries active enemies using the shared ellipse. Results are ascending Id; the caller owns and reuses its buffer.

public void QueryEnemies(Vec2 center, float range, SpatialQueryBuffer results)

Parameters

center Vec2
range float
results SpatialQueryBuffer

Examples

sim.QueryEnemies(center, 3, cachedBuffer);

RaiseRemains(RaiseRemainsDef, int)

Reserves closest eligible bodies, breaking ties by body Id. Returns accepted count; capacity and population include existing reservations.

public int RaiseRemains(RaiseRemainsDef definition, int actorId)

Parameters

definition RaiseRemainsDef
actorId int

Returns

int

RangeDistanceSquared(Vec2, Vec2)

Elliptical distance squared using the product's vertical radius ratio.

public float RangeDistanceSquared(Vec2 a, Vec2 b)

Parameters

a Vec2
b Vec2

Returns

float

RegisterCommandHandler<T>(ICommandHandler<T>)

Registers an exact custom command type; built-in commands retain their original handlers.

public void RegisterCommandHandler<T>(ICommandHandler<T> handler) where T : class, ICommand

Parameters

handler ICommandHandler<T>

Type Parameters

T

Examples

sim.RegisterCommandHandler<SetStance>(new SetStanceHandler());

RegisterComponent<T>(Func<T>)

Prewarms one unique component instance for every pool bundle. Factories run only here; Reset runs on spawn.

public void RegisterComponent<T>(Func<T> factory) where T : class, ICustomComponent

Parameters

factory Func<T>

Type Parameters

T

Examples

sim.RegisterComponent(() => new ShieldState());

RegisterDamageHook(IDamageHook)

Adds a damage hook in deterministic registration order.

public void RegisterDamageHook(IDamageHook hook)

Parameters

hook IDamageHook

Examples

sim.RegisterDamageHook(new ShieldDamageHook());

RegisterStateHashContributor(IStateHashContributor)

Includes external extension state in ComputeStateHash, in registration order.

public void RegisterStateHashContributor(IStateHashContributor contributor)

Parameters

contributor IStateHashContributor

Examples

sim.RegisterStateHashContributor(weatherState);

RegisterSystem(ISimSystem, SimStage, bool)

Inserts a system before or after a built-in stage. Registrations at the same location run in registration order.

public void RegisterSystem(ISimSystem system, SimStage anchor, bool after = true)

Parameters

system ISimSystem
anchor SimStage
after bool

Examples

sim.RegisterSystem(new WeatherSystem(), SimStage.Damage, after: false);

RegisterTargetSelector(ITargetSelector)

Registers the optional world-wide ranged selector. Candidate and definition data can distinguish actor types.

public void RegisterTargetSelector(ITargetSelector selector)

Parameters

selector ITargetSelector

Examples

sim.RegisterTargetSelector(new LowestShieldSelector());

RemoveTrap(int)

Marks a deployment for removal in the next mechanism stage.

public bool RemoveTrap(int trapId)

Parameters

trapId int

Returns

bool

RepositionCompanions(int, Vec2)

Reassigns ground escorts around an approved owner destination. MoveHero and SetRallyPoint call this automatically.

public void RepositionCompanions(int ownerId, Vec2 destination)

Parameters

ownerId int
destination Vec2

RequestDamage(DamageContext)

Queues custom raw damage through the same hooks, FIFO, defenses, effects and experience path.

public bool RequestDamage(DamageContext request)

Parameters

request DamageContext

Returns

bool

Examples

sim.RequestDamage(new DamageContext(actor.Id, target.Id, 10, damage));

SetEntityPosition(int, Vec2, bool)

Changes position without advancing a path cursor; invalidates spatial queries immediately.

public bool SetEntityPosition(int entityId, Vec2 position, bool resetInterpolation = false)

Parameters

entityId int
position Vec2
resetInterpolation bool

Returns

bool

SetProfiler(ISimProfiler)

Installs or clears observational hooks before the first Step.

public void SetProfiler(ISimProfiler value)

Parameters

value ISimProfiler

Examples

simulation.SetProfiler(new MyPreallocatedProfiler());

SpawnEnemy(string, int, int)

Queues an enemy at a validated path entry. Its first action is after the next Flush.

public Entity SpawnEnemy(string templateId, int pathIndex, int laneIndex = 0)

Parameters

templateId string
pathIndex int
laneIndex int

Returns

Entity

SpawnHero(string, Vec2)

Queues an available independent hero at a validated finite starting position; returns null on pool saturation.

public Entity SpawnHero(string templateId, Vec2 position)

Parameters

templateId string
position Vec2

Returns

Entity

StartRecording(CommandLog)

Begins fixed-capacity recording before the first Step. Only successfully queued external commands are recorded.

public void StartRecording(CommandLog log)

Parameters

log CommandLog

StartReplay(CommandLog)

Injects recorded commands at their original ticks. Configure the same initial world and seed; live external input is rejected.

public void StartReplay(CommandLog log)

Parameters

log CommandLog

Examples

var replay = new Simulation(templates, level, config, log.Seed); replay.StartReplay(log);

Step()

Advances one fixed tick: damage precedes exits, outcomes precede Flush, new entities act next tick.

public void Step()

StopRecording()

Seals and detaches the current recording between ticks; does nothing when not recording.

public void StopRecording()

TryResolvePoint(PointRuleDef, Vec2, out Vec2)

Uses the shared point policy for previews, hero destinations, and spell approvals.

public bool TryResolvePoint(PointRuleDef rule, Vec2 candidate, out Vec2 accepted)

Parameters

rule PointRuleDef
candidate Vec2
accepted Vec2

Returns

bool

TryResolveRallyPoint(int, Vec2, out Vec2)

Validates a barracks rally point using the same range, finite-coordinate and lane projection rules as SetRallyPoint.

public bool TryResolveRallyPoint(int towerId, Vec2 desired, out Vec2 resolved)

Parameters

towerId int
desired Vec2
resolved Vec2

Returns

bool

Examples

bool valid = sim.TryResolveRallyPoint(tower.Id, cursor, out Vec2 preview);

TryTransferToPath(int, PathDestinationDef, int)

Atomically changes path/lane/cursor/position, clears interception and refreshes the spatial index. Invalid geometry changes nothing.

public bool TryTransferToPath(int entityId, PathDestinationDef destination, int sourceId = 0)

Parameters

entityId int
destination PathDestinationDef
sourceId int

Returns

bool

TryTransferToPath(int, PathDestinationDef, int, string)

Transfers a unit and includes the supplied mechanism identity in PathTransferred.Key. Null preserves the legacy unkeyed notification.

public bool TryTransferToPath(int entityId, PathDestinationDef destination, int sourceId, string mechanismKey)

Parameters

entityId int
destination PathDestinationDef
sourceId int
mechanismKey string

Returns

bool

TryValidateSpellPoint(int, Vec2, out Vec2)

Validates spell placement for UI previews without consuming cooldown or randomness.

public bool TryValidateSpellPoint(int spellIndex, Vec2 position, out Vec2 accepted)

Parameters

spellIndex int
position Vec2
accepted Vec2

Returns

bool