Spaces:
Running
Running
Minimap: time frames from tick column (t column is non-monotonic across pauses)
Browse files- src/lib/api/world.ts +11 -2
src/lib/api/world.ts
CHANGED
|
@@ -37,7 +37,7 @@ function chunkBaseUrl(chunk: PreviewChunk): string {
|
|
| 37 |
}
|
| 38 |
|
| 39 |
type TickRow = {
|
| 40 |
-
|
| 41 |
x: number;
|
| 42 |
y: number;
|
| 43 |
z: number;
|
|
@@ -48,6 +48,9 @@ type TickRow = {
|
|
| 48 |
is_alive: boolean;
|
| 49 |
};
|
| 50 |
|
|
|
|
|
|
|
|
|
|
| 51 |
async function loadChunkFrames(
|
| 52 |
chunk: PreviewChunk,
|
| 53 |
player: number,
|
|
@@ -55,15 +58,21 @@ async function loadChunkFrames(
|
|
| 55 |
): Promise<WorldFrame[]> {
|
| 56 |
const base = chunkBaseUrl(chunk);
|
| 57 |
const rows = await fetchParquetRows<TickRow>(`${base}/ticks.parquet`, opts);
|
|
|
|
| 58 |
|
| 59 |
const steamid = `slot-${player}`;
|
| 60 |
const name = `Player ${player}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
|
| 62 |
const frames: WorldFrame[] = new Array(rows.length);
|
| 63 |
for (let i = 0; i < rows.length; i++) {
|
| 64 |
const r = rows[i];
|
| 65 |
frames[i] = {
|
| 66 |
-
t: r.
|
| 67 |
player,
|
| 68 |
steamid,
|
| 69 |
name,
|
|
|
|
| 37 |
}
|
| 38 |
|
| 39 |
type TickRow = {
|
| 40 |
+
tick: number;
|
| 41 |
x: number;
|
| 42 |
y: number;
|
| 43 |
z: number;
|
|
|
|
| 48 |
is_alive: boolean;
|
| 49 |
};
|
| 50 |
|
| 51 |
+
// CS2 demo tickrate.
|
| 52 |
+
const TICK_RATE = 64;
|
| 53 |
+
|
| 54 |
async function loadChunkFrames(
|
| 55 |
chunk: PreviewChunk,
|
| 56 |
player: number,
|
|
|
|
| 58 |
): Promise<WorldFrame[]> {
|
| 59 |
const base = chunkBaseUrl(chunk);
|
| 60 |
const rows = await fetchParquetRows<TickRow>(`${base}/ticks.parquet`, opts);
|
| 61 |
+
if (!rows.length) return [];
|
| 62 |
|
| 63 |
const steamid = `slot-${player}`;
|
| 64 |
const name = `Player ${player}`;
|
| 65 |
+
// The ticks.parquet `t` column can be non-monotonic (it resets across
|
| 66 |
+
// tactical-pause segments), which breaks the binary search in snapshotAt.
|
| 67 |
+
// `tick` is the absolute demo tick counter and stays monotonic across the
|
| 68 |
+
// whole round, so derive round-relative time from it.
|
| 69 |
+
const tick0 = rows[0].tick;
|
| 70 |
|
| 71 |
const frames: WorldFrame[] = new Array(rows.length);
|
| 72 |
for (let i = 0; i < rows.length; i++) {
|
| 73 |
const r = rows[i];
|
| 74 |
frames[i] = {
|
| 75 |
+
t: (r.tick - tick0) / TICK_RATE,
|
| 76 |
player,
|
| 77 |
steamid,
|
| 78 |
name,
|