Package-level declarations

Types

Link copied to clipboard
interface AgentLike

The minimal contract a Statechart needs from its owner. Both AgentModel.Agent and AgentResource implement this interface, so a statechart can govern either kind of actor without the statechart runtime having to know which it is.

Link copied to clipboard
sealed class AgentMessage

Base type for messages exchanged between agents.

Link copied to clipboard
open class AgentModel(parent: ModelElement, name: String? = null) : ProcessModel

Container for an agent-based modeling layer that runs alongside KSL's process view. Following the precedent of ksl.modeling.entity.TaskProcessingSystem, an AgentModel ships two kinds of agent — transient and permanent — plus the supporting machinery (a shared message bus, inner-class Statechart and AgentMailbox) that lets both kinds work uniformly.

Link copied to clipboard
open class AgentResource @JvmOverloads constructor(agentModel: AgentModel, name: String? = null, capacity: Int = Defaults.capacity, queue: RequestQ? = null) : ResourceWithQ, AgentLike

A resource that is also an agent. Behaves like an ordinary ResourceWithQ from the seizing entity's perspective — entities pass it to seize / release from inside a process — and on top of that exposes the agent capabilities the user might want for a forklift, repair worker, or nurse:

Link copied to clipboard
class AgentSignal(val name: String = "AgentSignal")

A broadcast trigger that statecharts can listen for. Unlike AgentMessage (point-to-point) and onCondition (a predicate tested in the C-phase), a signal is an explicit notification fired by user code — typically at the end of a transition, a phase change, or an externally-driven schedule event.

Link copied to clipboard
data class Cell(val col: Int, val row: Int)

A discrete cell in a GridProjection addressed by integer column / row coordinates.

Link copied to clipboard
class ContinuousProjection<A : AgentLike> @JvmOverloads constructor(val context: AgentModel.Context<A>, val xRange: ClosedRange<Double>, val yRange: ClosedRange<Double>, val torus: Boolean = false, val cellSize: Double = run { val xSize = xRange.endInclusive - xRange.start val ySize = yRange.endInclusive - yRange.start val smaller = minOf(xSize, ySize) if (smaller > 0.0) smaller / Defaults.cellSizeDivisor else 1.0 }, val name: String = "continuous") : Projection<A>

A 2D Euclidean projection: each agent in the context has an optional Point2D position. The projection tracks positions in a map keyed by agent reference; positions are set explicitly via placeAt / moveTo from user code.

Link copied to clipboard
class ContinuousVolume<A : AgentLike> @JvmOverloads constructor(val context: AgentModel.Context<A>, val xRange: ClosedRange<Double>, val yRange: ClosedRange<Double>, val zRange: ClosedRange<Double>, val torus: Boolean = false, val cellSize: Double = run { val xs = xRange.endInclusive - xRange.start val ys = yRange.endInclusive - yRange.start val zs = zRange.endInclusive - zRange.start val smallest = minOf(xs, ys, zs) if (smallest > 0.0) smallest / Defaults.cellSizeDivisor else 1.0 }, val name: String = "continuousVolume") : Projection<A>

A 3D Euclidean projection — the volumetric analog of ContinuousProjection. Each agent in the context has an optional Point3D position; positions are set explicitly via placeAt / moveTo from user code.

Link copied to clipboard
data class ContractNetOutcome<B>(val winner: AgentModel.Agent, val winningProposal: AgentMessage.Propose<B>)

Result of a successful Contract-Net negotiation. Contains the agent that won the contract and the proposal they submitted, so the caller can read the bid details (e.g., quoted completion time, price).

Link copied to clipboard
class Dynamics<A : AgentLike> @JvmOverloads constructor(val space: ContinuousProjection<A>, var mass: (A) -> Double = { Defaults.unitMass }, maxSpeed: Double = Defaults.maxSpeed, minSpeed: Double = Defaults.minSpeed)

Continuous-time dynamics primitive for agents on a ContinuousProjection. Owns the per-agent velocity state and the list of Forces contributing to motion; the step method performs the Euler integration step (sum forces → integrate velocity → compute candidate position) without applying it. Applying the new state — including boundary handling — is the caller's responsibility, because boundary policy varies between models (toroidal wrap for boids, walled rejection for pedestrians).

Link copied to clipboard
class Dynamics3D<A : AgentLike> @JvmOverloads constructor(val space: ContinuousVolume<A>, var mass: (A) -> Double = { Defaults.unitMass }, maxSpeed: Double = Defaults.maxSpeed, minSpeed: Double = Defaults.minSpeed)

3D analog of Dynamics. Continuous-time dynamics primitive for agents on a ContinuousVolume; owns the per-agent 3D velocity state and the list of Force3Ds contributing to motion. The step method performs the Euler integration step (sum forces → integrate velocity → compute candidate position) without applying it; the caller decides what to do with the candidate (wrap onto a 3D torus, reject if it enters a no-fly zone, clamp altitude to ground/ceiling, accept as-is).

Link copied to clipboard
data class Edge<A>(val from: A, val to: A, val weight: Double = NetworkProjection.Defaults.edgeWeight)

A directed edge in a NetworkProjection, with an optional weight. For undirected networks each "logical" edge is stored as a single Edge instance with the canonical ordering chosen by the user (the projection emits each undirected edge exactly once from NetworkProjection.edges).

Link copied to clipboard
class FlowField @JvmOverloads constructor(val graph: GridGraph, val sources: Set<Cell>, val cellSize: Double = Defaults.cellSize, val origin: Point2D = Defaults.origin)

A precomputed distance-from-sources field over a GridGraph, exposed at point-level granularity for continuous-space agents.

Link copied to clipboard
class FlowField3D @JvmOverloads constructor(val graph: VoxelGraph, val sources: Set<Voxel>, val cellSize: Double = Defaults.cellSize, val origin: Point3D = Defaults.origin)

A precomputed distance-from-sources field over a VoxelGraph, exposed at point-level granularity for continuous-space 3D agents (drones, UAVs, AUVs). The 3D analog of FlowField.

Link copied to clipboard
fun interface Force<A : AgentLike>

A force-producing rule in a continuous-time agent simulation. Given an agent and the Dynamics it belongs to, return the force vector contributed by this rule at the current simulation step.

Link copied to clipboard
fun interface Force3D<A : AgentLike>

3D analog of Force. Given an agent and the Dynamics3D it belongs to, return the 3D force vector contributed by this rule at the current simulation step.

Link copied to clipboard
class GridGraph @JvmOverloads constructor(val columns: Int, val rows: Int, val torus: Boolean = false, val movementRule: MovementRule = MovementRule.MOORE, val allowCornerCutting: Boolean = false)

A 2D-lattice graph: cells are first-class nodes, edges represent allowed movement between adjacent cells, and cells carry movement costs and blocked / passable status. Separate from GridProjection, which places agents on a lattice but doesn't model the lattice's navigation structure.

Link copied to clipboard

Pre-built heuristic functions for A* pathfinding on a GridGraph. All are admissible on uniform-cost grids (cell costs all ≥ 1.0) under the appropriate movement rule:

Link copied to clipboard

Choice of distance metric for GridProjection neighborhood and spatial-query operations.

Link copied to clipboard

Occupancy rule for a GridProjection; see that class for details.

Link copied to clipboard
class GridProjection<A : AgentLike> @JvmOverloads constructor(val context: AgentModel.Context<A>, val columns: Int, val rows: Int, val occupancy: GridOccupancy = GridOccupancy.MULTIPLE, val torus: Boolean = false, val name: String = "grid") : Projection<A>

A 2D lattice projection: each agent in the context occupies an integer-coordinate Cell. The grid has fixed columns and rows; cells are addressed by (col, row) with col ∈ [0, columns) and row ∈ [0, rows).

Link copied to clipboard
open class MovableAgentResource @JvmOverloads constructor(agentModel: AgentModel, val space: ContinuousProjection<AgentLike>, initPosition: Point2D, name: String? = null, capacity: Int = Defaults.capacity, queue: RequestQ? = null) : AgentResource

An AgentResource whose position is tracked in a ContinuousProjection. Composes the agent-resource semantics (seizable, queueable, on-shift / off-shift, statechart, mailbox, optional AgentPerformance stats) with continuous-space position tracking. Spatial queries on the projection (space.within(p, r), space.neighborsOf(...)) automatically see this resource at its current position.

Link copied to clipboard

Movement rule for a GridGraph. Selects the allowed neighbors of each cell:

Link copied to clipboard
class NetworkProjection<A : AgentLike> @JvmOverloads constructor(val context: AgentModel.Context<A>, val directed: Boolean = false, val name: String = "network") : Projection<A>

A graph-based projection: agents are nodes, edges are typed relationships between pairs of agents. The third projection type in the agent layer's spatial abstraction (alongside ContinuousProjection and GridProjection).

Link copied to clipboard
data class Point2D(val x: Double, val y: Double)

A 2D point, used by the agent layer's spatial projections.

Link copied to clipboard
data class Point3D(val x: Double, val y: Double, val z: Double)

A 3D point, used by the agent layer's volumetric projections (introduced in Phase 6 for UAV / drone modeling).

Link copied to clipboard
class Population<A : AgentModel.Agent>(source: () -> Iterable<A>) : Iterable<A>

A composable view over a group of agents.

Link copied to clipboard
interface Projection<A : AgentLike>

A relational or positional structure layered over an AgentModel.Context. Borrowed from Repast Simphony's terminology: a context owns membership (who is in this collection), while projections add structure (where each member is, who's related to whom). A single context can have multiple projections layered on top — an agent can simultaneously have a 2D position and membership in a network without those abstractions interfering.

Link copied to clipboard

Adapter that exposes an agent-layer ContinuousProjection as a spatial-layer SpatialModel. This is the bridge that lets entity-layer code requiring a LocationIfc (notably MovableResource and the KSLProcess.move() family) operate in the same coordinate space as agent-layer code.

Link copied to clipboard
abstract class StateAction

Runtime context passed to every statechart action block. Exposes the owning agent so handlers can read or mutate agent state, and provides transitionTo to schedule a transition to another state.

Link copied to clipboard

Builder for an individual StatechartState. Triggers and lifecycle hooks are configured by calling onEntry, onExit, onMessage, onTimeout, onCondition, or onSignal inside the state { } block. Composite states declare substates by nesting more state(...) { ... } calls inside the block and naming one via initial.

Link copied to clipboard

Top-level builder for AgentModel.Statechart. Constructed via the statechart { } method on an AgentLike owner; users do not instantiate this class directly.

Link copied to clipboard
annotation class StatechartDsl

Marker for DSL scope safety on the statechart builders. Prevents an inner state { } block from accidentally calling builder methods of an enclosing statechart builder.

Link copied to clipboard

A configured state within a statechart. Created by the StatechartBuilder DSL; users do not instantiate this class directly. The actual statechart runtime that consumes these is AgentModel.Statechart.

Link copied to clipboard
object Travel

Namespace holding mutable, globally-overridable defaults for the agent-layer travel primitives (travelTo, travelThrough).

Link copied to clipboard

Mutable handle representing an in-progress interruptible travel in 2D. Returned by startTravel; consumed by awaitTravel. The integration loop inside awaitTravel reads this handle on every step, so external entities (dispatchers, statecharts, other agents) can interrupt or redirect by calling cancel / redirect from their own coroutine context.

Link copied to clipboard

Mutable handle representing an in-progress interruptible 3D travel. The 3D analog of TravelHandle. Same semantics: returned by startTravel3D; consumed by awaitTravel3D; cancellable / redirectable from any coroutine with a reference to the handle.

Link copied to clipboard
data class TravelResult(val startedAt: Double, val arrivedAt: Double, val distance: Double)

Outcome of a travelTo call. Exposed so callers can inspect what just happened — duration, distance, and the start/arrival times — without computing them externally.

Link copied to clipboard
data class Voxel(val col: Int, val row: Int, val layer: Int)

A discrete 3D cell in a VoxelProjection / VoxelGraph, addressed by integer column / row / layer coordinates. The 3D analog of Cell.

Link copied to clipboard
class VoxelGraph @JvmOverloads constructor(val columns: Int, val rows: Int, val layers: Int, val torus: Boolean = false, val movementRule: VoxelMovementRule = VoxelMovementRule.MOORE_26, val allowCornerCutting: Boolean = false)

A 3D-lattice graph: voxels are first-class nodes, edges represent allowed movement between adjacent voxels, and voxels carry movement costs and blocked / passable status. The 3D analog of GridGraph. Separate from VoxelProjection, which places agents on a lattice but doesn't model the lattice's navigation structure.

Link copied to clipboard

Pre-built heuristic functions for A* pathfinding on a VoxelGraph. All are admissible on uniform-cost grids (voxel costs all ≥ 1.0) under the appropriate movement rule:

Link copied to clipboard

Choice of distance metric for VoxelProjection neighborhood and volumetric-query operations. The 3D analog of GridMetric.

Link copied to clipboard

Movement rule for a VoxelGraph. Selects the allowed neighbors of each voxel:

Link copied to clipboard

Occupancy rule for a VoxelProjection; see that class for details.

Link copied to clipboard
class VoxelProjection<A : AgentLike> @JvmOverloads constructor(val context: AgentModel.Context<A>, val columns: Int, val rows: Int, val layers: Int, val occupancy: VoxelOccupancy = VoxelOccupancy.MULTIPLE, val torus: Boolean = false, val name: String = "voxelGrid") : Projection<A>

A 3D lattice projection: each agent in the context occupies an integer-coordinate Voxel. The grid has fixed columns, rows, and layers; voxels are addressed by (col, row, layer) with col ∈ [0, columns), row ∈ [0, rows), layer ∈ [0, layers). The 3D analog of GridProjection.

Link copied to clipboard
data class WeightedPath<A>(val nodes: List<A>, val totalWeight: Double)

Result of a weighted shortest-path query on a NetworkProjection. nodes lists the path including both endpoints (single-element list for a self-path); totalWeight is the sum of edge weights along the path.

Functions

Link copied to clipboard
fun <A : AgentLike> alignment(radius: Double): Force<A>

Reynolds-rule alignment: steer toward the average velocity of neighbors within radius. Force is avg(neighbors.v) - my.v, so the magnitude scales with how off-heading this agent is from the local consensus.

Link copied to clipboard
fun <A : AgentLike> alignment3D(radius: Double): Force3D<A>

Reynolds-rule alignment in 3D: steer toward the average velocity of neighbors within radius. Force is avg(neighbors.v) - my.v.

Link copied to clipboard

Construct a ProjectionSpatialModel over this projection. Each call creates a new spatial model; locations created by one spatial model are not valid in another. Store the result and reuse it across all MovableResource / move / transport calls that need to share coordinates with this projection.

Link copied to clipboard
fun atLeast(minimum: Double, initial: Double, name: String? = null): ReadWriteProperty<Any?, Double>

Inclusive lower bound: value must be >= minimum.

Link copied to clipboard

Drive the integration loop for handle to completion (or cancellation). Suspends. Returns the final TravelResult.

Link copied to clipboard

Drive the 3D integration loop for handle to completion or cancellation. Suspends. Returns the final TravelResult.

Link copied to clipboard
fun <A : AgentLike> cohesion(radius: Double): Force<A>

Reynolds-rule cohesion: steer toward the average position of neighbors within radius. Computed as the average of torus- aware deltas (via ContinuousProjection.delta) so it works correctly across wrap boundaries — averaging absolute positions would break for a peer just over the wrap.

Link copied to clipboard
fun <A : AgentLike> cohesion3D(radius: Double): Force3D<A>

Reynolds-rule cohesion in 3D: steer toward the average position of neighbors within radius. Computed as the average of torus-aware deltas via ContinuousVolume.delta so it works correctly across 3D wrap boundaries.

Link copied to clipboard

Apply a constant force vector regardless of agent state. Useful for global influences like wind, gravity, or a uniform attractor.

Link copied to clipboard

Apply a constant 3D force vector regardless of agent state. Useful for global influences like gravity (Point3D(0, 0, -mg)), wind, or a uniform attractor.

Link copied to clipboard
suspend fun <Q, B> KSLProcessBuilder.contractNet(bidders: List<AgentModel.Agent>, callForProposals: Q, deadline: Double, selectBest: (List<AgentMessage.Propose<B>>) -> AgentMessage.Propose<B>? = { it.firstOrNull() }): ContractNetOutcome<B>?

Run a Contract-Net Protocol negotiation from inside the calling agent's process. The calling agent (the initiator) sends a AgentMessage.Request with payload callForProposals to every agent in bidders, waits for deadline simulated time units, then collects the AgentMessage.Propose messages that arrived with the matching conversation id. The selectBest function picks the winning proposal (default: first received).

Link copied to clipboard
fun <A : AgentLike> desiredVelocity(speed: Double, tau: Double, direction: (agent: A, dynamics: Dynamics<A>) -> Point2D): Force<A>

Helbing-style desired-velocity relaxation force: F = mass * (v_desired - v_current) / tau. Pulls the agent's velocity toward direction * speed over a timescale of tau.

Link copied to clipboard
fun <A : AgentLike> desiredVelocity3D(speed: Double, tau: Double, direction: (agent: A, dynamics: Dynamics3D<A>) -> Point3D): Force3D<A>

Helbing-style desired-velocity relaxation force in 3D: F = mass * (v_desired - v_current) / tau. Pulls the agent's velocity toward direction * speed over a timescale of tau.

Link copied to clipboard
fun greaterThan(minimum: Double, initial: Double, name: String? = null): ReadWriteProperty<Any?, Double>

Strict lower bound: value must be >minimum.

Link copied to clipboard
fun inRange(range: ClosedRange<Double>, initial: Double, name: String? = null): ReadWriteProperty<Any?, Double>

Closed range: value must be in range.

Link copied to clipboard
fun nextConversationId(prefix: String = "cnp"): String

Generate a process-global, JVM-unique conversation id. Exposed for callers that want to construct messages with a pre-allocated id (rare). Note: contractNet does not use this — it draws from a per-model counter reset each replication, so its ids are reproducible run-to-run and isolated between models. If you mix manual ids with contractNet on the same mailboxes, pass a distinct prefix here to avoid any overlap with the default "cnp" namespace.

Link copied to clipboard
fun nonNegative(initial: Double, name: String? = null): ReadWriteProperty<Any?, Double>

Non-negativity: value must be >= 0.0.

fun nonNegative(initial: Int, name: String? = null): ReadWriteProperty<Any?, Int>

Non-negativity: value must be >= 0.

Link copied to clipboard
fun <A : AgentLike> peerRepulsion(radius: Double, minDistance: Double = 0.0, falloff: (distance: Double) -> Double): Force<A>

Peer-peer repulsion. For each neighbor inside radius (excluding self), apply a force along the direction away from the neighbor with magnitude given by falloff of the inter-agent distance. Distances are clamped at minDistance to keep falloff finite at contact.

Link copied to clipboard
fun <A : AgentLike> peerRepulsion3D(radius: Double, minDistance: Double = 0.0, falloff: (distance: Double) -> Double): Force3D<A>

3D peer-peer repulsion. For each neighbor inside radius (excluding self), apply a force along the direction away from the neighbor with magnitude given by falloff of the inter- agent distance. Distances are clamped at minDistance to keep falloff finite at contact. Uses ContinuousVolume.delta for the inter-agent direction so torus-wrapped 3D worlds compute the correct shortest-way vector.

Link copied to clipboard
fun positive(initial: Double, name: String? = null): ReadWriteProperty<Any?, Double>

Strict positivity: value must be > 0.0. Throws on construction or assignment otherwise. Pass name to have construction-time errors (where the property name is not yet known) name the field.

fun positive(initial: Int, name: String? = null): ReadWriteProperty<Any?, Int>

Strict positivity: value must be > 0. Throws on construction or assignment otherwise.

Link copied to clipboard
fun probability(initial: Double, name: String? = null): ReadWriteProperty<Any?, Double>

Probability: value must be in 0.0, 1.0.

Link copied to clipboard
suspend fun <M : AgentMessage> KSLProcessBuilder.receiveMessage(mailbox: AgentModel.AgentMailbox<M>, suspensionName: String? = null, predicate: (M) -> Boolean = { true }): M

Suspend until a message matching predicate is available in mailbox, then return it. Default predicate matches anything.

Link copied to clipboard
inline suspend fun <T : M, M : AgentMessage> KSLProcessBuilder.receiveMessageOfType(mailbox: AgentModel.AgentMailbox<M>, suspensionName: String? = null): T

Suspend until a message of type T arrives in mailbox, then return it. Useful for handlers that key off the performative type.

Link copied to clipboard
suspend fun <A : AgentLike> KSLProcessBuilder.runDynamics(agent: A, dynamics: Dynamics<A>, dt: Double = 0.05, until: () -> Boolean = { false })

Run agent under dynamics until until returns true. Each iteration: compute the Euler step, store the new velocity, move the agent to the candidate position as-is, delay dt.

Link copied to clipboard
suspend fun <A : AgentLike> KSLProcessBuilder.runDynamics3D(agent: A, dynamics: Dynamics3D<A>, dt: Double = 0.05, until: () -> Boolean = { false })

Run agent under dynamics until until returns true. Each iteration: compute the 3D Euler step, store the new velocity, move the agent to the candidate position as-is, delay dt.

Link copied to clipboard
suspend fun <A : AgentLike> KSLProcessBuilder.runDynamics3DAll(dynamics: Dynamics3D<A>, agents: () -> Collection<A>, dt: Double = 0.05, until: () -> Boolean = { false }, apply: (agent: A, vNew: Point3D, pNew: Point3D) -> Unit = { a, v, p -> dynamics.setVelocity(a, v) dynamics.space.moveTo(a, p) })

Drive a whole population under dynamics from a single controller process using a Jacobi (synchronous, order-independent) update — the batched, 3D analog of runDynamics3D. Each tick computes every agent's step from the shared current state via Dynamics3D.stepAll, applies them all, then delays dt.

Link copied to clipboard
suspend fun <A : AgentLike> KSLProcessBuilder.runDynamicsAll(dynamics: Dynamics<A>, agents: () -> Collection<A>, dt: Double = 0.05, until: () -> Boolean = { false }, apply: (agent: A, vNew: Point2D, pNew: Point2D) -> Unit = { a, v, p -> dynamics.setVelocity(a, v) dynamics.space.moveTo(a, p) })

Drive a whole population under dynamics from a single controller process using a Jacobi (synchronous, order-independent) update. Each tick computes every agent's step from the shared current state via Dynamics.stepAll, then applies them all, then delays dt. This is the batched analog of runDynamics and avoids the order-of-update bias you get when each agent runs its own runDynamics loop.

Link copied to clipboard

Send message to mailbox from inside an agent's process { } body. Non-blocking: the mailbox is unbounded and deliver always succeeds. Declared suspend only to be callable from restricted-suspension lambdas; no actual suspension occurs.

Link copied to clipboard
fun <A : AgentLike> separation(radius: Double, minDistance: Double = 0.001): Force<A>

Reynolds-rule separation: peer-peer repulsion with inverse- distance falloff over radius. Convenience wrapper around peerRepulsion; equivalent to peerRepulsion(radius, minDistance) { d -> 1.0 / d }.

Link copied to clipboard
fun <A : AgentLike> separation3D(radius: Double, minDistance: Double = 0.001): Force3D<A>

Reynolds-rule separation in 3D: peer-peer repulsion with inverse-distance falloff over radius. Convenience wrapper around peerRepulsion3D.

Link copied to clipboard
fun <A : AgentLike> KSLProcessBuilder.startTravel(agent: A, space: ContinuousProjection<in A>, destination: Point2D, velocity: Double, stepSize: Double = Travel.Defaults.stepSize): TravelHandle<A>

Start an interruptible 2D travel. Returns the TravelHandle immediately without suspending — the caller must then either call awaitTravel to drive the integration to completion, or hand the handle to another entity (statechart, dispatcher, controller) that will manage the integration.

Link copied to clipboard
fun <A : AgentLike> KSLProcessBuilder.startTravel3D(agent: A, space: ContinuousVolume<in A>, destination: Point3D, velocity: Double, stepSize: Double = Travel.Defaults.stepSize): TravelHandle3D<A>

Start an interruptible 3D travel. Returns the TravelHandle3D immediately without suspending. Caller drives the integration via awaitTravel3D.

Link copied to clipboard

Extract 2D Cartesian coordinates from any LocationIfc that has them. Returns null for locations whose underlying spatial model does not have a 2D Cartesian representation (DistancesModel.Location — just a name; GreatCircleBasedSpatialModel.GPSCoordinate — spherical geometry, not directly Cartesian).

Link copied to clipboard
suspend fun <A : AgentLike> KSLProcessBuilder.travelThrough(agent: A, space: ContinuousProjection<in A>, waypoints: List<Point2D>, velocity: Double, stepSize: Double = Travel.Defaults.stepSize): TravelResult

Travel a sequence of waypoints in order. Equivalent to a chain of travelTo calls, returning the cumulative result. The agent starts from its current position and visits each waypoint in order; the last waypoint is the final destination.

Link copied to clipboard
suspend fun <A : AgentLike> KSLProcessBuilder.travelThrough3D(agent: A, space: ContinuousVolume<in A>, waypoints: List<Point3D>, velocity: Double, stepSize: Double = Travel.Defaults.stepSize): TravelResult

Travel a sequence of waypoints in 3D order. Equivalent to a chain of travelTo3D calls, returning the cumulative result. The agent starts from its current position and visits each waypoint in order; the last waypoint is the final destination.

Link copied to clipboard
suspend fun <A : AgentLike> KSLProcessBuilder.travelTo(agent: A, space: ContinuousProjection<in A>, destination: Point2D, velocity: Double, stepSize: Double = Travel.Defaults.stepSize): TravelResult

Move agent from its current position in space to destination at constant velocity. The traversal takes distance / velocity simulated time units; the projection is updated to interpolated intermediate positions every stepSize coordinate-units of travel so concurrent spatial queries (space.within(...), space.neighborsOf(...)) reflect the moving agent's current position at step granularity.

Link copied to clipboard
suspend fun <A : AgentLike> KSLProcessBuilder.travelTo3D(agent: A, space: ContinuousVolume<in A>, destination: Point3D, velocity: Double, stepSize: Double = Travel.Defaults.stepSize): TravelResult

Move agent from its current 3D position in space to destination at constant velocity. The 3D analog of travelTo.

Link copied to clipboard
fun <A : AgentLike> viscousDrag(coefficient: Double): Force<A>

Viscous drag opposing the current velocity: F = -coefficient * velocity. Useful for damping out runaway oscillations or modeling fluid resistance.

Link copied to clipboard
fun <A : AgentLike> viscousDrag3D(coefficient: Double): Force3D<A>

3D viscous drag opposing the current velocity: F = -coefficient * velocity. Useful for damping out runaway oscillations, modeling air resistance on UAVs, or stabilizing a hover.

Link copied to clipboard
fun <A : AgentLike> wallRepulsion(graph: GridGraph, cellSize: Double, origin: Point2D, scanRadius: Double, minDistance: Double = 0.0, falloff: (distance: Double) -> Double): Force<A>

Exponential repulsion from blocked cells (walls) in a GridGraph. Walls are treated as solid cell-sized bounding boxes: the force per cell uses the closest point on that cell's box to the agent's position. Scans a square of cells of radius ceil(scanRadius/cellSize) around the agent's current cell; cells outside that scan don't contribute.

Link copied to clipboard
fun <A : AgentLike> wallRepulsion3D(graph: VoxelGraph, cellSize: Double, origin: Point3D, scanRadius: Double, minDistance: Double = 0.0, falloff: (distance: Double) -> Double): Force3D<A>

Exponential repulsion from blocked voxels (walls / obstacles / no-fly zones) in a VoxelGraph. Voxels are treated as solid 3D bounding boxes: the force per voxel uses the closest point on that voxel's box to the agent's 3D position. Scans a cube of voxels of half-side ceil(scanRadius/cellSize) around the agent's current voxel.

Link copied to clipboard
fun <A : AgentLike> weighted(force: Force<A>, weight: Double): Force<A>

Scale force's output by a fixed weight. Composes with any other factory:

Link copied to clipboard
fun <A : AgentLike> weighted3D(force: Force3D<A>, weight: Double): Force3D<A>

Scale force's output by a fixed weight in 3D. Composes with any other 3D force factory.