Ziplines¶
from boon import Demo
demo = Demo("match.dem", preload=False)
nodes = demo.zipline_nodes
changes = demo.zipline_changes
# Both tables share one cached history pass.
Read zipline routes and ownership from the demo. No boon-data catalog is required. Boon stores geometry once and adds a row only when it changes. Ownership and visibility use a separate change table. Boon does not load these tables by default.
Read Boon Demo.zipline_nodes geometry¶
demo.zipline_nodes contains initial definitions and later revisions:
Column |
Meaning |
|---|---|
|
First observation tick for this definition. |
|
Full UInt32 entity handle, including the serial. |
|
Raw lane ID. |
|
World coordinates. |
|
List of full UInt32 target handles. Null means unknown or incomplete; |
|
The game’s cumulative path distance, in world units. |
|
Whether the game marks the node as capturable. |
The key for a definition is (tick, node_handle). A handle can have more than one
geometry revision. Use only revisions at or before the query tick. Do not use the
last definition for all ticks. Connections keep raw handles; resolve targets by
full handle at the same tick. An absent target remains unknown.
Read Boon Demo.zipline_changes ownership¶
demo.zipline_changes contains tick, node_handle, change, and team_num.
Accepted change strings are:
Change |
Meaning |
|---|---|
|
First observation, or observation after leaving visibility. |
|
The recorded team changed. |
|
The node left the visible set; it was not deleted. |
|
The replay explicitly deleted the node. |
team_num keeps the recorded integer. It is null when unknown, on left_pvs,
and on removed. No timeout is applied. Missing observations do not remove nodes.
Full handles keep different occupants of one entity slot separate. Rows describe
state after each tick. A keyframe can delete and recreate the same handle.
If the node stays active through that tick, Boon adds no removal or observation row.
Query Boon zipline snapshots at an exact tick¶
state = demo.snapshots("ziplines", ticks=10000)
sampled = demo.snapshots("ziplines", seconds=5)
frames = demo.snapshots(["player_ticks", "ziplines"], ticks=[321, 10000])
Snapshots contain the node columns plus team_num. Here, tick is the query tick,
not the definition tick. Boon uses only observations through that tick and omits
nodes whose last transition is left_pvs or removed. Absence is not proof of
permanent removal. Unknown fields stay null.
All snapshot selectors work: ticks, every, seconds, events, start_tick,
and end_tick. Windows are inclusive. Tick strides start at the recording’s first
available tick; a window does not reset the stride. Use seconds=5 for a five-second
tick stride. This can include paused samples. The snapshot dataset is ziplines;
load() accepts the two compact table names, not ziplines.
Direct queries and sampled passes use the same serial history. The first query reads that history once; later queries reuse it. Zipline queries do not change the seek or parallel paths used by player, world, and trooper snapshots.
Draw Boon ziplines with plot.positions¶
from boon import plot
fig, ax = plot.positions(demo, tick=10000, version="6795", ziplines=True)
fig.savefig("ziplines.png", dpi=160, bbox_inches="tight")
Select an image version for your replay. Routes use team colors. Lane-name badges use yellow for York, blue for Broadway, and green for Greenwich. A small tick marks different known owners at a connection’s midpoint. This is a display boundary, not a recorded capture position. See Plotting.
Boon zipline evidence limits¶
Ownership describes zipline control. It is not a recorded troop-front position or lane-push percentage. Combine it with troopers and objectives for lane analysis. Cumulative distance is not normalized progress. Route branches can have different origins; use the recorded connections when you construct paths.
Read ziplines with the Boon Rust API¶
use boon::{Parser, ziplines::ZiplineHistory};
use std::path::Path;
let parser = Parser::from_file(Path::new("match.dem"))?;
let history = ZiplineHistory::build(&parser)?;
history.visit_snapshots(&[10000], |tick, node, team| {
println!("{tick}: {} {team:?}", node.node_handle);
});
nodes() and changes() return the compact history. visit_snapshots() sorts
and deduplicates its tick selection. It visits nodes in full-handle order.