Package-level declarations
Types
Coordinates all per-agent animation for one AgentModel: it announces each agent (ksl.animation.AnimationEvent.AgentRegistered) and wires that agent's statechart (StatechartAnimationEmitter) and mailbox (MailboxAnimationEmitter) emitters. This is what the animation controller installs per agent model so a config-driven trace captures agent behavior, not just registrations.
The non-invasive, opt-in agent-position capture (decision D6 option b): a model element that, every samplingInterval simulated time units, reads each agent's position in projection and emits an AnimationEvent.AgentPositionSampled. It does not touch the agent package; it only reads positions.
An AgentModel.AgentRegistryObserver that emits an AnimationEvent.AgentRegistered whenever an agent is registered with the model. Attach it with agentModel.attachRegistryObserver(AgentRegistryAnimationEmitter(agentModel)); the agent model is unchanged.
Rate-limited capture of per-agent velocity/force vectors for the G10 overlay. Every interval (default 5 samples per simulated second, decoupled from the model's integration dt) it emits an AnimationEvent.AgentVectorSampled for each agent of agentModel's linked dynamics (optionally restricted to OverlaySpec.agentSubset). This is the volume-sensitive overlay; sampling + subset keep it bounded, and it is created only when the velocity or force overlay is enabled.
An AgentModel.MailboxObserver that emits AnimationEvent.AgentMessageDelivered on each delivery and AnimationEvent.AgentMessageConsumed on each consumption for one agent's mailbox. Attach one per agent (agent.mailbox.addObserver(MailboxAnimationEmitter(agent.name, model))); the mailbox is unchanged.
An AgentModel.StatechartObserver that emits agent statechart events: AnimationEvent.AgentStateEntered, AnimationEvent.AgentStateExited, and AnimationEvent.AgentTransition. Attach one per agent to that agent's statechart (agent.statechart?.addObserver(StatechartAnimationEmitter(agent.name, model))).