Event Snapshots
This page describes the committed source guideline. It skips certifying revision-sensitive RuneLite UI, packet, or in-game outcomes; treat those as live-client verification pending unless the page records direct evidence.
com.n3plugins.sdk.events exposes passive recent-event snapshots for callers requiring observation without owning RuneLite event-bus wiring. PacketUtils registers SdkEvents with RuneLite's event bus during suite startup and unregisters it during shutdown.
This provides passive observation, not polling or an action surface. Consumers read bounded recent snapshots. They do not click, walk, attack, or mutate game state through these APIs.
SdkEvents
SdkEvents.xpGained().forEach(event ->
log.debug("{} gained {}", event.getSkill(), event.getGainedXp()));
List<NpcLifecycleEvent> bankers = SdkEvents.npcSpawns().stream()
.filter(event -> "Banker".equals(event.getName()))
.collect(Collectors.toList());
Methods:
xpGained()- recentXpGainedEventsnapshots.inventoryDeltas()- recentInventoryDeltaEventsnapshots.inventoryDeltaCursor()- latest monotonic inventory-delta sequence.inventoryDeltasAfter(cursor)- immutable orderedInventoryDeltaBatchwith a safe next cursor and explicit retention-gap detection.npcSpawns()- recent NPC lifecycle snapshots whereisSpawned()returns true.npcDespawns()- recent NPC lifecycle snapshots whereisSpawned()returns false.npcLifecycle()- recent NPC spawn and despawn snapshots.animationChanges()- recentAnimationChangeEventsnapshots.projectileMovements()- recentProjectileMovementEventsnapshots.clear()- clears retained snapshots and tracker baselines.trackerForTesting()- exposes the shared tracker for focused tests.
PacketUtils runtime wiring owns register(eventBus, client) and unregister(eventBus). Ordinary SDK consumers must not register their own suite-level tracker.
Snapshot Types
All event snapshot types include client tick and wall-clock timestamp through the shared SdkEventSnapshot base.
XpGainedEvent- skill, previous XP, current XP, gained XP, real level, and boosted level.InventoryDeltaEvent- monotonic sequence, container id, slot, item id, previous quantity, current quantity, and delta quantity. Slot replacement emits removal before addition.NpcLifecycleEvent- spawn/despawn flag, NPC id, NPC index, name, world location, and local location.AnimationChangeEvent- actor name, animation id, world location, and local location.ProjectileMovementEvent- projectile id, source world point, target world point, target local point, target z, source actor name, and target actor name.
Ownership Detail
SdkEventTracker provides the RuneLite event-bus subscriber behind SdkEvents. It records bounded recent snapshots with a default capacity of 128 per event kind. It remains public for focused tests and explicit runtime ownership, but normal callers must consume the static SdkEvents facade.
Cursor consumers must persist InventoryDeltaBatch.getNextCursor() exactly once per observation cycle. isGapDetected() means output may have been lost and requires snapshot resynchronization; it is never a successful transfer postcondition. Login, hop, and connection-loss states invalidate current-session inventory, equipment, and bank knowledge and clear retained item deltas. The sequence itself is not reset, preventing an old cursor from accidentally matching a later session. Unknown containers remain distinct from known-empty containers.
Semantic Simulation Foundation
The same package contains the generic foundation for semantic event simulation. EventEnvelope<T> carries a stable payload, deterministic sequence and tick metadata, source provenance, and optional scenario/correlation metadata. Transport-specific event classes remain observations rather than the recorded scenario model.
dispatch.StimulusDispatcher routes an envelope to the first supporting StimulusHandler using an explicit DispatchMode. It prevents re-accepting the same event ID in one session. scenario.ScenarioRunner operates tick-driven: it dispatches once, then evaluates state verification on later ticks. It never treats posting an event as proof that the target processed it.
Dispatch Sub-package (sdk.events.dispatch)
| Class | Role |
|---|---|
StimulusDispatcher | Routes an EventEnvelope to the first matching StimulusHandler; deduplicates by event ID per session. |
StimulusHandler | Handler interface with supports(envelope) and handle(envelope, context). |
DispatchMode | Explicit enum: SYNC, ASYNC, or DRY_RUN. |
DispatchContext | Carries dispatcher metadata, mode, and session state into handlers. |
DispatchResult | Outcome of dispatch: HANDLED, NO_HANDLER, DUPLICATE, or error. |
Scenario Sub-package (sdk.events.scenario)
| Class | Role |
|---|---|
Scenario | Immutable sequence of ScenarioStep entries, each with an envelope and optional verification conditions. |
ScenarioStep | One dispatch-then-verify unit: envelope + List<VerificationCondition>. |
ScenarioRunner | Tick-driven executor: dispatches a step once, then evaluates verification on subsequent ticks. |
ScenarioResult | Aggregated pass/fail outcome with per-step VerificationResult entries. |
Verification Sub-package (sdk.events.verify)
| Class | Role |
|---|---|
VerificationCondition | Functional predicate evaluated after dispatch to confirm expected state. |
VerificationResult | Per-condition outcome: PASSED, FAILED, or SKIPPED, with an optional message. |
Replay Sub-package (sdk.events.replay)
EventReplayService replays a recorded EventTimeline (ordered list of EventEnvelope entries with inter-event delays) through the StimulusDispatcher. ReplayPolicy configures timing fidelity, error handling, and whether to skip or abort on handler failures. ReplayResult reports the timeline completion status, per-envelope outcomes, and elapsed wall-clock time.
Packet Transport Sub-package (sdk.events.packet)
PacketReplayHandler provides a StimulusHandler specialized for packet-debug replay scenarios. PacketReplayStimulus wraps packet-trace payload data into an EventEnvelope. PacketReplayTransport bridges packet replay envelopes into the dispatcher without requiring a live packet connection.
Event Lab UI (sdk.events.ui)
EventLabController provides a thin controller for an offline Event Lab view. Target-plugin mutation handlers and full Swing views remain future scope. The controller exposes the replay/scenario/dispatch wiring for test harness and developer tool integration.
State Fixtures (sdk.events.fixture)
| Class | Role |
|---|---|
StateFixtureService | Manages named StateSnapshot fixtures for deterministic scenario setup. |
StateSnapshot | Immutable capture of relevant state fields for fixture comparison. |
StateTransaction | Atomic apply/rollback of state changes during scenario execution. |
Fixtures allow offline tests and cloud agents to set up known state before running scenarios without requiring a live RuneLite client.
OSRS-TCG Integration (sdk.integration.osrstcg)
OsrsTcgCapabilities defines the guarded capability surface for OSRS Trading Card Game plugin-message interop. OsrsTcgPluginMessageClient implements a thin PluginMessage-based communication client. OsrsTcgPluginMessageTransport bridges TCG events into the event dispatch system.
The OSRS-TCG integration provides a development-interop guideline surface. It skips carrying OSRS-TCG implementation dependencies or exposing TCG-specific game mutations through the n3 SDK.
Break Handlers run active-only.