Package-level declarations

Types

Link copied to clipboard

The two kinds of anchor a PathDefinition can connect (deliberately a smaller set than ElementKind).

Link copied to clipboard
@Serializable
data class AnchorRef(val kind: AnchorKind, val name: String)

A typed reference to a placement anchor — a network station or a location — used as a PathDefinition endpoint.

Link copied to clipboard

The top-level animation-layout DSL builder. See animation.

Link copied to clipboard
class AnimationCapture(model: Model, output: JsonLinesAnimationOutput, mode: AnimationCapture.Mode = Mode.MEMORY, capturedReplications: Set<Int>? = setOf(1), captureSpec: CaptureSpec = CaptureSpec(), overlays: OverlaySpec = OverlaySpec.OFF, asyncCapacity: Int = AsyncAnimationSink.DEFAULT_CAPACITY, description: String? = null, kslVersion: String? = libraryVersion) : Closeable

Captures an animation trace for a run of model and writes it to output (a .atf writer). This is the self-contained, renderer-agnostic capture mechanism of the animation core: it wires a sink onto the model, drives the sink's replication/experiment lifecycle, emits the experiment/replication marker events a renderer uses to delimit the trace, registers the automatic per-element emitters so the trace captures real activity, and cleans everything up on close.

Link copied to clipboard
annotation class AnimationDsl

Restricts implicit receivers so nested animation-DSL blocks don't capture the wrong scope.

Link copied to clipboard
@Serializable
sealed class AnimationEvent
Link copied to clipboard
@Serializable
data class AnimationInventory(val queues: List<String> = emptyList(), val queueInfos: List<QueueInfo> = emptyList(), val resources: List<String> = emptyList(), val movableResources: List<String> = emptyList(), val movableHomeBases: Map<String, String> = emptyMap(), val responses: List<String> = emptyList(), val timeWeightedResponses: List<String> = emptyList(), val counters: List<String> = emptyList(), val stations: List<String> = emptyList(), val networks: List<String> = emptyList(), val conveyors: List<String> = emptyList(), val conveyorInfos: List<ConveyorInfo> = emptyList(), val agentModels: List<String> = emptyList(), val spaces: List<SpaceInfo> = emptyList(), val locations: List<String> = emptyList(), val entityTypes: List<EntityTypeInfo> = emptyList(), val locationInfos: List<LocationInfo> = emptyList(), val guidedPaths: List<GuidedPathInfo> = emptyList(), val guidedTransporters: List<String> = emptyList(), val fleets: List<FleetInfo> = emptyList(), val notCapturedByDefault: List<String> = emptyList())

The animatable elements a model exposes (9A.3): the structural model elements, plus spatial spaces (from agent projections) and location names (from any DistancesModel). Built from a probe model — no simulation — and used to drive the editor pick-lists and author-time validation (9A.5), so capture selection and layout key off one identifier space (ElementKind).

Link copied to clipboard
@Serializable
data class AnimationLayout(val title: String? = null, val baseTimeUnit: String? = null, val width: Double = 1000.0, val height: Double = 700.0, val objectClasses: List<ObjectClassDefinition> = emptyList(), val background: List<BackgroundElement> = emptyList(), val paths: List<PathDefinition> = emptyList(), val queues: List<QueueLayoutElement> = emptyList(), val resources: List<ResourceLayoutElement> = emptyList(), val stations: List<NetworkStationLayoutElement> = emptyList(), val bars: List<BarDisplayElement> = emptyList(), val plots: List<PlotDisplayElement> = emptyList(), val clocks: List<ClockDisplayElement> = emptyList(), val spaces: List<SpatialSpaceDescriptor> = emptyList(), val values: List<ValueDisplayElement> = emptyList(), val agentStateColors: Map<String, String> = emptyMap(), val summaries: List<SummaryDisplayElement> = emptyList(), val histograms: List<HistogramDisplayElement> = emptyList(), val storages: List<StorageLayoutElement> = emptyList(), val movableResources: List<MovableResourceLayoutElement> = emptyList(), val processColors: Map<String, String> = emptyMap(), val conveyors: List<ConveyorLayoutElement> = emptyList(), val labels: List<ElementLabel> = emptyList(), val spaceGeometry: List<GridGeometrySpec> = emptyList(), val locations: List<LocationLayoutElement> = emptyList(), val guidedPaths: List<GuidedPathLayoutElement> = emptyList(), val guidedTransporters: List<GuidedTransporterLayoutElement> = emptyList())

The static layout that, together with a .atf trace, lets a renderer draw an animation. Written once (before simulate()) to a .lay.json file. The format is self-describing (NF6): a renderer can produce a basic animation from only the layout and the trace.

Link copied to clipboard
interface AnimationSink

The destination for AnimationEvents produced during a simulation run.

Link copied to clipboard
class AnimationStateSnapshotter(parent: ModelElement, captureSpec: CaptureSpec, keyframeTime: Double, name: String? = null) : ModelElement

Emits a single opening-frame keyframe at keyframeTime (a capture window's startTime, 9A.2/9B): a comprehensive re-statement of the model's current animation state, so a windowed trace whose window begins mid-run is replayable from its first frame. Without it, a renderer joining at startTime would see only the deltas that happen after startTime and would not know what already exists.

Link copied to clipboard
@Serializable
data class AnimationTraceHeader(val formatVersion: Int = AnimationEvent.FORMAT_VERSION, val baseTimeUnit: String? = null, val kslVersion: String? = null, val description: String? = null)

The first record of every animation trace (.atf) file. It identifies the format generation and records run-level context the renderer needs before it begins interpreting AnimationEvent records.

Link copied to clipboard
class AsyncAnimationSink(capacity: Int = DEFAULT_CAPACITY, overflowPolicy: AsyncAnimationSink.OverflowPolicy = OverflowPolicy.BLOCK, consume: (AnimationEvent) -> Unit) : AnimationSink

An AnimationSink that hands events to a dedicated background writer thread through a bounded queue, so serialization and disk I/O happen off the simulation thread. This is the sink for watching a long run as it executes, where buffering the whole run in memory (as MemoryBufferedAnimationSink does) is not viable.

Link copied to clipboard
@Serializable
data class BackgroundElement(val kind: BackgroundKind, val points: List<LayoutPoint> = emptyList(), val text: String? = null, val color: String = "#000000", val strokeWidth: Double = 1.0, val imageRef: String? = null, val fontSize: Double = 12.0, val fontFamily: String? = null)

A static background element (lines, rectangles, text, images).

Link copied to clipboard

Kinds of static background geometry.

Link copied to clipboard
class BarBuilder(responseName: String, position: LayoutPoint)

Sub-builder for a BarDisplayElement.

Link copied to clipboard
@Serializable
data class BarDisplayElement(val responseName: String, val position: LayoutPoint, val width: Double = 120.0, val height: Double = 20.0, val maxValue: Double = 100.0, val color: String = "#1f77b4", val label: String? = null)

A live bar bound to a response/counter (by responseName).

Link copied to clipboard

Whether the animation trace captures all animatable elements (the default, today's behavior) or only a selected subset (the include/exclude lists of a CaptureSpec). Part of Phase 9's capture/presentation split: this is the what to capture control, separate from the layout.

Link copied to clipboard
@Serializable
data class CaptureSpec(val mode: CaptureMode = CaptureMode.ALL, val include: List<ElementSelector> = emptyList(), val exclude: List<ElementSelector> = emptyList(), val captureWindow: CaptureWindow? = null)

The animation capture configuration (Phase 9): what and when to record, separate from the presentation/layout. Two axes:

Link copied to clipboard
@Serializable
data class CaptureWindow(val startTime: Double, val endTime: Double)

The simulated-time interval [startTime, endTime] during which the animation trace records events (the modeler's "start at X, stop at Y"). Enforced at capture time by the WindowedAnimationSink; a full-state keyframe is emitted at startTime so the window's opening frame is correct (Phase 9B). null (no window) means the whole run is captured.

Link copied to clipboard
@Serializable
data class ClockDisplayElement(val position: LayoutPoint, val format: String = "0.0", val label: String? = "Time", val fontSize: Double = 12.0)

A clock display showing the current simulated time.

Link copied to clipboard
@Serializable
data class ConveyorInfo(val name: String, val cellSize: Int, val accumulating: Boolean, val segments: List<SegmentInfo> = emptyList())

A conveyor's structure exposed pre-run from the built ksl.modeling.entity.Conveyor (10.5a): its cellSize, whether it is accumulating, and its ordered, chained segments. Lets the editor route the belt against the stations/locations its segments connect before any run.

Link copied to clipboard
@Serializable
data class ConveyorLayoutElement(val conveyorName: String, val segments: List<SegmentRoute> = emptyList(), val width: Double = 8.0, val color: String = "#888888", val showDirection: Boolean = true, val label: String? = null)

Author-controlled drawing of a conveyor (10.5, §6.7). Keyed by conveyorName; its segments route the belt (chained entry→waypoints→exit). width/color style the belt and showDirection draws travel arrows. When absent the renderer falls back to straight anchor-to-anchor interpolation.

Link copied to clipboard

The kinds of animatable model elements a CaptureSpec can select and an animation inventory can enumerate. Shared vocabulary between the capture configuration (CaptureSpec) and the renderer's element bindings, so selection and layout key off one identifier space. (SPACE is an agent projection's spatial space; station resources are reported as RESOURCE.) GUIDED_PATH is a guide path space (named by the space element, which is unique), GUIDED_TRANSPORTER a transporter on one, and FLEET a fleet system, whose assignments are its own events.

Link copied to clipboard
@Serializable
data class ElementLabel(val kind: ElementKind, val name: String, val text: String? = null, val dx: Double = 0.0, val dy: Double = -12.0, val visible: Boolean = true, val valueDx: Double = 0.0, val valueDy: Double = 14.0, val valueVisible: Boolean = true)

Per-element text overrides for the element identified by kind + name (10.8/C3, batch 4). An element has two independent text annotations: the name label (text retitles it; dx/dy offset it from the glyph in screen px; visible hides it) and the live value/state (e.g. a queue's count) with its own valueDx/valueDy/valueVisible. Either can be moved, retitled (the name), or hidden independently.

Link copied to clipboard
@Serializable
data class ElementSelector(val kind: ElementKind, val name: String)

Identifies one animatable element by its kind and trace name (the name it emits under). Used in a CaptureSpec's include/exclude lists to select what enters the trace.

Link copied to clipboard
class EntityCaptureFilteringSink(downstream: AnimationSink, excludedTypes: Set<String>, excludedProcesses: Set<String>) : AnimationSink

A filtering AnimationSink that drops an entity's events when its type or its current process is excluded from capture (Phase 10.1d). A decorator in the same family as WindowedAnimationSink: it wraps a downstream sink and removes events without the producers (or that sink) knowing anything about it.

Link copied to clipboard
@Serializable
data class EntityTypeInfo(val typeName: String, val processes: List<ProcessInfo> = emptyList(), val include: Boolean = true, val isAgent: Boolean = false)

An animatable entity/agent type (10.1b): its typeName (the class simpleName, matching EntityCreated.entityType) and the processes declared on it (from @KSLAnimatedProcess, or — when none are annotated — a best-effort list of its KSLProcess-valued properties, keyed by property name).

Link copied to clipboard
@Serializable
data class FleetInfo(val name: String, val kind: String, val networkName: String? = null, val vehicles: List<FleetVehicleInfo> = emptyList(), val dispatcherAgentName: String? = null)

A fleet system known before a run. kind is AGV for a guided-path fleet and FREE_PATH for one that moves over a spatial model; networkName names the guide path an AGV fleet runs on.

Link copied to clipboard
@Serializable
data class FleetVehicleInfo(val name: String, val bodyName: String? = null, val agentName: String? = null, val loadCapacity: Int = 1)

A fleet vehicle: bodyName is what moves (the name movement events carry), agentName its controller.

Link copied to clipboard
@Serializable
data class FlowCell(val col: Int, val row: Int, val distance: Double)

One cell of a AnimationEvent.FlowFieldDefined heatmap: grid (col,row) with its distance to the nearest source/goal (G11).

Link copied to clipboard
@Serializable
data class GuidedPathInfo(val networkName: String, val spaceName: String, val intersections: List<GuidedPathIntersectionDef> = emptyList(), val links: List<GuidedPathLinkDef> = emptyList(), val transporters: List<GuidedTransporterDef> = emptyList())

A guide path known before a run: its network, laid out (intersections always have coordinates once the network is built), its links and its transporters, in the same vocabulary the trace uses so a preview, a capture selection and a layout check all name the same things.

Link copied to clipboard
@Serializable
data class GuidedPathIntersectionDef(val name: String, val x: Double, val y: Double, val z: Double = 0.0, val aliases: List<String> = emptyList())

An intersection of a AnimationEvent.GuidedPathDefined: name at world position (x,y,z). Coordinates come from the guide path itself, which carries them for exactly this purpose.

Link copied to clipboard
@Serializable
data class GuidedPathLayoutElement(val spaceName: String, val offset: LayoutPoint = LayoutPoint(0.0, 0.0), val scale: Double = 1.0, val floorOffsetPerZ: LayoutPoint? = null, val linkColor: String = "#7f7f7f", val linkWidth: Double = 2.0, val showZones: Boolean = true, val showIntersections: Boolean = true, val closureColor: String = "#d62728", val label: String? = null)

How a guide path is drawn (V13). Keyed by spaceName, the owning guide path space's unique name. The trace supplies the path's geometry; this places and styles it: offset and scale map the network's coordinates into the layout, floorOffsetPerZ separates floors by shifting each point by that vector times its height (so a multi-floor building does not draw its floors on top of each other), and the rest style links, zone ticks, intersections and closures. A network point (x, y, z) is drawn at offset + scale × (x, y) + z × floorOffsetPerZ.

Link copied to clipboard
@Serializable
data class GuidedPathLinkDef(val name: String, val from: String, val to: String, val numZones: Int, val bidirectional: Boolean = false, val spur: Boolean = false, val length: Double = Double.NaN)

A link of a AnimationEvent.GuidedPathDefined, running from intersection from to to and divided into numZones equal zones, named <link name>.Zone1 to <link name>.Zone<numZones> from the from end. bidirectional and spur say which of the two features that most affect congestion this link has. length is the travel length, which can differ from the straight line between the two intersections; NaN when unknown.

Link copied to clipboard
@Serializable
data class GuidedTransporterDef(val name: String, val lengthInZones: Int = 1, val loadCapacity: Int = 1, val physicalLength: Double = Double.NaN, val homeBase: String? = null, val vehicleName: String? = null)

A transporter on a AnimationEvent.GuidedPathDefined: lengthInZones zones long when fully on the path, carrying up to loadCapacity loads. vehicleName is the owning fleet vehicle's name when the transporter is an AGV's body (the name its assignments carry); null otherwise.

Link copied to clipboard
@Serializable
data class GuidedTransporterLayoutElement(val name: String, val shape: LayoutShape = LayoutShape.SQUARE, val size: Double = 14.0, val color: String = "#1f77b4", val loadedColor: String? = null, val blockedColor: String? = null, val haltedColor: String? = null, val imageRef: String? = null, val label: String? = null)

How a guided transporter is drawn (V13). Keyed by name, the transporter's name. loadedColor, blockedColor and haltedColor distinguish the stillnesses a viewer most needs to tell apart; each falls back to color when null.

Link copied to clipboard
class HistogramBuilder(responseName: String, position: LayoutPoint, bins: Int, discrete: Boolean)

Sub-builder for a HistogramDisplayElement.

Link copied to clipboard
@Serializable
data class HistogramDisplayElement(val responseName: String, val position: LayoutPoint, val width: Double = 220.0, val height: Double = 120.0, val bins: Int = 10, val discrete: Boolean = false, val color: String = "#1f77b4", val label: String? = null)

A live histogram / frequency chart of a response's observed values, computed in the viewer from the raw value stream (decision D12 — not emitted as bin snapshots). When discrete is true it tallies by integer value (an integer-frequency chart); otherwise it bins the observed range into bins equal-width bins. Bound by responseName (8D.1).

Link copied to clipboard

Writes an animation trace in the JSON Lines (.atf) format: an AnimationTraceHeader on the first line, then one AnimationEvent per line. Each line is independently valid JSON, so the file is streamable and inspectable with standard tools (a text editor, jq, Python).

Link copied to clipboard
annotation class KSLAnimatedEntity(val include: Boolean = true)

Marks a ProcessModel.Entity subclass as animatable, mirroring the @KSLControl idiom (Phase 10.1b).

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.PROPERTY])
annotation class KSLAnimatedProcess(val name: String = "", val include: Boolean = true)

Marks a process-valued property of a ProcessModel.Entity subclass as animatable, mirroring the @KSLControl idiom (Phase 10.1b). Applied to the val that holds a process("…"){ } result:

Link copied to clipboard
@Serializable
data class LayoutPoint(val x: Double, val y: Double, val z: Double = 0.0)

A 2D/3D point used by layout elements (z defaults to 0 for 2D layouts).

Link copied to clipboard

A drawing primitive for an entity/agent class.

Link copied to clipboard
@Serializable
data class LocationInfo(val name: String, val x: Double? = null, val y: Double? = null)

A named spatial location (landmark / point of interest) an agent context declared via Context.location(...) (G1): its name and, when the coordinates are known, its (x, y) — so auto-layout can place it. A coordinate-free location (e.g. a DistancesModel name) has null x/y and is positioned later (MDS).

Link copied to clipboard
@Serializable
data class LocationLayoutElement(val locationName: String, val position: LayoutPoint? = null, val label: String? = null)

The animation of a spatial LocationIfc — a named place entities and movers travel between (move endpoints, conveyor anchors, agent points-of-interest). position is nullable: unknown until placed or MDS-proposed (mirrors MovableResourceLayoutElement). Distinct from a flow-network station; the renderer draws it with its own glyph. Keyed by locationName.

Link copied to clipboard
class MemoryBufferedAnimationSink(flush: (replicationNumber: Int, events: List<AnimationEvent>) -> Unit) : AnimationSink

An AnimationSink that holds every emitted event in memory for the duration of a replication, then hands the whole batch to flush when the replication ends.

Link copied to clipboard

Sub-builder for a MovableResourceLayoutElement (8K.5).

Link copied to clipboard
@Serializable
data class MovableResourceLayoutElement(val name: String, val shape: LayoutShape = LayoutShape.SQUARE, val color: String = "#8c564b", val size: Double = 16.0, val imageRef: String? = null, val label: String? = null, val position: LayoutPoint? = null, val busyColor: String? = null, val idleImage: String? = null, val busyImage: String? = null, val homeBase: String? = null)

A movable/transport resource drawn as a glyph at its interpolated position while moving (8K.5). When at rest it is drawn at the layout position of its homeBase station when known (so the editor preview matches what the replay shows for a coordinate-free spatial model such as a DistancesModel), otherwise at its optional position (home/parked anchor; null ⇒ only shown while moving). busyColor/busyImage style it while transporting, idleImage when at rest/empty (10.8/C4). Keyed by name.

Link copied to clipboard
@Serializable
enum MoverMode : Enum<MoverMode>

Why a movable/transport resource is moving (10.8/C2): repositioning empty, carrying an entity, or going home.

Link copied to clipboard
@Serializable
data class NetworkEdge(val from: String, val to: String, val weight: Double = 1.0)

A weighted edge between two NetworkNodes.

Link copied to clipboard
@Serializable
data class NetworkEdgeDef(val from: String, val to: String, val weight: Double = 1.0)

A weighted edge in a AnimationEvent.NetworkDefined, referencing node ids from and to — G7.

Link copied to clipboard
@Serializable
data class NetworkNode(val id: String, val position: LayoutPoint)

A node of a network spatial space (e.g. an agent NetworkProjection).

Link copied to clipboard
@Serializable
data class NetworkNodeDef(val id: String, val x: Double, val y: Double)

A laid-out node in a AnimationEvent.NetworkDefined: an agent id at world position (x,y) — G7.

Link copied to clipboard
Link copied to clipboard
@Serializable
data class NetworkStationLayoutElement(val stationName: String, val position: LayoutPoint, val label: String? = null)

Where to draw a network station — the animation of a ksl.modeling.station.Station (a flow-network node), distinct from a spatial LocationLayoutElement. Keyed by stationName.

Link copied to clipboard

Implemented by a model element that owns statistics not worth animating unless someone asks for them: bookkeeping a viewer would not plot, which nonetheless changes often enough to fill a trace. A capture of everything leaves the statistics named in notCapturedByDefault out, and including one by name (in either capture mode) puts it back. Excluding is unaffected.

Link copied to clipboard

The no-op sink used whenever animation is disabled. isActive is always false, emit does nothing, and the lifecycle callbacks are inherited no-ops.

Link copied to clipboard
class ObjectClassBuilder(typeName: String)

Sub-builder for an ObjectClassDefinition.

Link copied to clipboard
@Serializable
data class ObjectClassDefinition(val typeName: String, val shape: LayoutShape = LayoutShape.CIRCLE, val color: String = "#1f77b4", val size: Double = 10.0, val imageRef: String? = null, val label: String? = null)

The visual template for an entity or agent class, keyed by typeName (which matches EntityCreated.entityType / AgentRegistered.agentType in the trace).

Link copied to clipboard
@Serializable
data class OverlaySpec(val velocities: Boolean = false, val forces: Boolean = false, val flowField: Boolean = false, val plannedPaths: Boolean = false, val markerPulses: Boolean = false, val vectorSampleInterval: Double? = null, val agentSubset: List<String> = emptyList())

Opt-in "agent debugging / teaching" overlays (G10–G12): they record internal computation that drives agent behavior — velocity/force vectors, the flow-field gradient, and planned routes — rather than the observable state the base animation already shows. All flags default off, so a normal run pays zero cost. These are the capture gates (whether the trace contains the data); the viewer has its own display toggles (whether it draws the data), so a captured overlay can be shown/hidden without re-running.

Link copied to clipboard
@Serializable
data class PathDefinition(val name: String, val points: List<LayoutPoint>, val from: AnchorRef? = null, val to: AnchorRef? = null, val bidirectional: Boolean = true)

A named path (poly-line) entities/movers can be shown moving along. When from and to anchors are set the path is functional: points are the intermediate waypoints and a move between those two anchors follows the polyline (fromPos, then points, then toPos), arc-length-parameterized over the move's time window; with the anchors null it is decorative (legacy) and points is the whole poly-line. bidirectional lets a reverse move (to → from) follow the same waypoints reversed. The anchor fields are appended + defaulted, so old layouts load.

Link copied to clipboard
@Serializable
data class PathPoint(val x: Double, val y: Double)

One world-coordinate vertex of a AnimationEvent.PlannedPath route polyline (G12).

Link copied to clipboard
class PlotBuilder(responseName: String, position: LayoutPoint)

Sub-builder for a PlotDisplayElement.

Link copied to clipboard
@Serializable
data class PlotDisplayElement(val responseName: String, val position: LayoutPoint, val width: Double = 220.0, val height: Double = 110.0, val windowDuration: Double? = null, val color: String = "#1f77b4", val label: String? = null)

A live time-series plot bound to a response/counter (by responseName).

Link copied to clipboard
@Serializable
data class ProcessInfo(val name: String, val include: Boolean = true)

An animatable process of an entity type (10.1b): its trace name and whether it is animated/captured.

Link copied to clipboard
class QueueBuilder(name: String, position: LayoutPoint)

Sub-builder for a QueueLayoutElement.

Link copied to clipboard
@Serializable
data class QueueInfo(val name: String, val reporting: Boolean = true, val waitTimeStats: Boolean = true)

A queue's reporting intent (P5/C1), read pre-run from the model's ksl.modeling.queue.Queue. reporting mirrors defaultReportingOption and waitTimeStats mirrors waitTimeStatOption. The editor uses these as a hint: non-reporting queues (e.g. a movable resource's internal :HomeBaseQ) are captured but not auto-placed.

Link copied to clipboard
@Serializable
data class QueueLayoutElement(val queueName: String, val position: LayoutPoint, val growthDegrees: Double = 0.0, val spacing: Double = 12.0, val maxShown: Int = 10)

Where and how to draw a queue's waiting members. Keyed by queueName from the trace. position is the head (front of the line, nearest service); members extend away from it along growthDegrees (0° = right, increasing clockwise on screen: 90° = down, 180° = left, 270° = up). Member i is drawn at head + i·spacing·(cos θ, sin θ) (8I.6).

Link copied to clipboard
class ReplicationSelectingSink(delegate: AnimationSink, capturedReplications: Set<Int>) : AnimationSink

A filtering AnimationSink that forwards events and lifecycle callbacks to delegate only during the replications named in capturedReplications.

Link copied to clipboard
class ResourceBuilder(name: String, position: LayoutPoint)

Sub-builder for a ResourceLayoutElement.

Link copied to clipboard
@Serializable
data class ResourceLayoutElement(val resourceName: String, val position: LayoutPoint, val size: Double = 20.0, val idleColor: String = "#2ca02c", val busyColor: String = "#d62728", val failedColor: String = "#7f7f7f", val inactiveColor: String = "#cccccc", val idleImage: String? = null, val busyImage: String? = null, val failedImage: String? = null, val inactiveImage: String? = null, val showValue: Boolean = false)

Where to draw a resource and the colors for its states. Keyed by resourceName. Each state may also carry an optional image (idleImage/busyImage/failedImage/inactiveImage); when present the renderer draws the image for that state and the matching color is the fallback (10.7).

Link copied to clipboard
@Serializable
data class SegmentInfo(val entryLocation: String, val exitLocation: String, val lengthCells: Int)

One chained segment of a conveyor (10.5a): its named entryLocation→exitLocation anchors and cell length.

Link copied to clipboard
@Serializable
data class SegmentRoute(val entryLocation: String, val exitLocation: String, val waypoints: List<LayoutPoint> = emptyList())

One conveyor segment's authored route (10.5, §6.7): the belt from entryLocation to exitLocation runs straight through any waypoints in order. Anchors resolve to placed station/location positions; an empty waypoints list ⇒ a straight entry→exit belt (today's behavior).

Link copied to clipboard
@Serializable
data class SpaceInfo(val name: String, val kind: SpaceInfo.SpaceKind, val cols: Int? = null, val rows: Int? = null, val xMin: Double? = null, val xMax: Double? = null, val yMin: Double? = null, val yMax: Double? = null, val torus: Boolean = false, val geometry: GridGeometrySpec? = null)

A spatial space derived from an agent projection (its name + dimensions), for the layout side (9A.3).

Link copied to clipboard
@Serializable
sealed class SpatialSpaceDescriptor

Describes a spatial space (an agent projection or a station network) so the renderer can draw its background. The initial set covers continuous, grid, and network spaces (decision D8); voxel/flow-field spaces can be added without breaking the format.

Link copied to clipboard

Renamed to NetworkStationLayoutElement (Phase 7); kept one cycle. Wire-compatible: the layout field stays stations and the element's properties are unchanged, so serialized layouts are unaffected.

Link copied to clipboard
class StorageBuilder(suspensionName: String, position: LayoutPoint)

Sub-builder for a StorageLayoutElement (8K.4).

Link copied to clipboard
@Serializable
data class StorageLayoutElement(val suspensionName: String, val position: LayoutPoint, val style: StorageStyle = StorageStyle.PROGRESS_BELT, val width: Double = 160.0, val height: Double = 48.0, val growthDegrees: Double = 0.0, val spacing: Double = 14.0, val capacity: Int = 0, val maxShown: Int = 30, val byType: Boolean = true, val label: String? = null)

A holding area showing the entities currently in a named delay (8K.4). suspensionName matches a delay's suspensionName; when a delay is unnamed the renderer keys it by the entity's type name (a stable, shared default), so a storage can bind to either. position anchors the element (entry of the belt / corner of the box); style chooses the arrangement. Beyond maxShown members the element degrades to a count badge + capacity gauge (driven by capacity; 0 = unbounded).

Link copied to clipboard

How a StorageLayoutElement arranges the entities currently delaying in it (8K.4). A storage is unordered, so position carries no rank. PROGRESS_BELT drifts each entity from entry to exit as its delay elapses (needs a known duration; falls back to PACKED_REGION otherwise); PACKED_REGION grid-packs into a box; LINE is queue-like along the growth angle; PILE is a jittered cluster; COUNT is an aggregate badge.

Link copied to clipboard
@Serializable
data class SummaryDisplayElement(val responseName: String, val position: LayoutPoint, val label: String? = null, val decimals: Int = 2)

A within-replication statistics summary (count, mean, min, max) for a response — the engine emits the statistics (D11), this just shows them. Bound by responseName (8A.4).

Link copied to clipboard

Reads a JSON Lines (.atf) trace produced by JsonLinesAnimationOutput: readHeader consumes the first line; events streams the remaining lines as AnimationEvents lazily, so a large trace is never fully held in memory.

Link copied to clipboard
data class ValidationIssue(val kind: ValidationIssue.Kind, val name: String, val message: String)

One problem found by validateAgainst: a layout binding whose name is not present in the model (8K.2). Because the layout keys to the trace by name string, an unmatched binding renders nothing with no runtime error — this surfaces those silent mismatches at author time.

Link copied to clipboard
data class ValidationReport(val issues: List<ValidationIssue>)

The result of validating an AnimationLayout against a Model (8K.2).

Link copied to clipboard
@Serializable
data class ValueDisplayElement(val responseName: String, val position: LayoutPoint, val label: String? = null, val decimals: Int = 1)

A labeled numeric readout of a response/counter's value (no geometry) — the display primitive that BarDisplayElement composes (a bar = a value readout + a value-proportional rectangle). Bound to a response by responseName; rendered as "label: value".

Link copied to clipboard
class WindowedAnimationSink(delegate: AnimationSink, startTime: Double, endTime: Double, currentTime: () -> Double) : AnimationSink

A filtering AnimationSink that forwards events to delegate only while the simulated clock lies within the closed time window [startTime, endTime].

Functions

Link copied to clipboard

The model's elements in parent-child order, for animation emitter registration (e.g. the trace attachment). A public, animation-scoped view over the engine-internal element list, so a downstream module can register emitters without Model.getModelElements() itself becoming public API.

Link copied to clipboard

Authors an AnimationLayout for this model with a DSL:

Link copied to clipboard
fun CaptureSpec.capturesStatistic(kind: ElementKind, name: String, offByDefault: Set<String>): Boolean

Whether the response or counter name of kind is captured: as CaptureSpec.captures says, except that a statistic in offByDefault is captured only when it is included by name.

Link copied to clipboard

The ElementKind of a structural model element (the single source of truth shared by the inventory extractor and the trace attachment's selective emitter registration, so they can't drift). Returns null for elements that aren't directly selectable here — e.g. Response/Counter, which are taken from the model's curated lists. MovableResource is matched before Resource (it is a Resource).

Link copied to clipboard

Every statistic the model's elements name as not captured by default; see NotCapturedByDefaultIfc.

Link copied to clipboard
fun DistancesModel.proposeCoordinates(width: Double = 800.0, height: Double = 500.0, margin: Double = 60.0): Map<String, LayoutPoint>

Proposes 2-D coordinates for the named locations of this DistancesModel via classical (Torgerson) multidimensional scaling (8K.6b) — so a coordinate-free distance model can be placed in a layout without hand-picking coordinates that honor the distance matrix. The directed matrix is symmetrized and, for a sparse model (one that defines only some pairs, e.g. a tandem line), completed by shortest paths; coordinates are uniformly scaled (shape-preserving) and centered to fit a width × height box with margin padding. MDS is rotation/reflection-invariant, so orientation is arbitrary.

Link copied to clipboard
fun Model.scaffoldLayout(title: String = name, width: Double = 1000.0, height: Double = 700.0, originX: Double = 80.0, originY: Double = 80.0, columnGap: Double = 240.0, rowGap: Double = 70.0): AnimationLayout

Builds a starter AnimationLayout for this model with the resources, queues and stations auto-placed on a simple grid (8K.2c), so authoring begins from a populated, self-consistent file instead of a blank one. Responses and counters are deliberately not placed — a model can expose dozens, which overwhelm the starter layout; the author adds the stats they want (value/bar/plot displays). Movable/transport resources are placed as movableResource(...) glyphs (not static boxes), and when the model moves them over a DistancesModel its named locations are placed as station anchors (via placeStations) so the transporters animate between them. The placement is deliberately rough — the author then drags elements into their final positions. No objectClass styling is emitted (entity/agent types are runtime; the renderer falls back to defaults). By construction scaffoldLayout().validateAgainst(model).isValid.

Link copied to clipboard

Validates this layout against inventory: every queue/resource/movableResource/response binding is checked against the names the model exposes (the same element kinds the animation emitters attach to), and unmatched names are reported with a nearest-name "did you mean?" hint (8K.2a). Response-style bindings (bar/plot/value/summary/histogram) match against responses ∪ counters (both emit response values).

Validates this layout against model by delegating to the AnimationInventory path (validateAgainst(inventory)) — the inventory is the single identifier space (9A.3/9A.5) that both capture selection and layout binding key off, so validation can't drift from what the emitters expose.

Validates this capture spec against inventory (9A.5): every include/exclude ElementSelector must name an element the inventory actually exposes for its ElementKind. A selector that names a non-existent element (or names one of the wrong kind) silently captures nothing, so this surfaces the typo at author time with a nearest-name hint drawn from that kind's names.

Link copied to clipboard

Cross-checks a produced trace against this manifest (10.1f) — the trace-side validation the inventory doc defers (8K.2b). Walks events, collecting every entity type (EntityCreated.entityType) and every process (ProcessActivated, keyed by the composite "Type.process" via the entityId → type join), and reports each that the manifest does not declare. These are nudges, not errors: capture defaults to all, so an undeclared type/process still animates — the warning simply tells the author to declare it (entityType<T>() / @KSLAnimatedEntity, @KSLAnimatedProcess) so it appears in the editor before a run.

Link copied to clipboard

Separates scaffold-placed glyphs that landed on top of each other — e.g. a resource-column position that coincides with an MDS-placed DistancesModel station, which made the resource impossible to find (item 5). Stations keep their positions (they anchor agent/transporter rendering); colliding resources and queues are nudged out along a golden-angle spiral until clear.