diff --git a/README.md b/README.md index c831ed5..32d7308 100644 --- a/README.md +++ b/README.md @@ -11,40 +11,43 @@ -**sat·set** /sat-sèt/ *adjective (slang)* — Indonesian colloquialism for being rapid, efficient, and quick to act. +**sat·set** /sat-sèt/ *adjective (slang)*: Indonesian colloquialism for being rapid, efficient, and quick to act. -> *"Sat set, sampai."* — Indonesian for "Swiftly done." +> *"Sat set, sampai."* means "Swiftly done." -Satset is a high-performance networking library for [Roblox](https://roblox.com). It handles the heavy lifting of buffer serialization and state synchronization. It connects low-level data packing with high-level state sync, offering a unified API for both stateless events (Packets) and delta-compressed channels. +Satset is a buffer-backed networking library for [Roblox](https://roblox.com). It handles packet serialization, batching, rate limiting, and state synchronization. The public API covers stateless events (Packets) and delta-compressed state (Channels). -The library is built on the principle that code on the hot path should not allocate. By using native Luau `buffer` operations and focusing on O(1) operations, Satset maintains performance even when syncing hundreds of entities per frame. +Satset keeps the send path in Luau `buffer` objects where possible. Packet listeners receive decoded tables, and channel subscribers receive reconstructed state tables. # Performance Benchmarks -Satset is designed for high-throughput scenarios. We maintain a [benchmark suite](benchmark/Benchmarks.md) that measures Satset against native RemoteEvents and other common implementations. +The [benchmark suite](benchmark/Benchmarks.md) compares Satset with native Roblox remotes and community networking libraries. It sends 200 events per frame for 10 seconds per payload. The tables report Roblox `Stats.DataSendKbps` p50 values normalized to a 60 FPS baseline. -## Dual-Mode Batching +## Batching Profiles -Satset provides two batching strategies. Users can tune the library for engine stability (segmenting large payloads) or raw throughput. +The latest benchmark uses two Satset profiles: -| Test Case (1,000 items/frame) | Satset (Stability) | Satset (Latency) | Native Remotes | -| :--- | :--- | :--- | :--- | -| **Vectors** | 4.2 MB/s | **39.2 B/s** | 213.7 MB/s | -| **Strings** | 18.4 MB/s | **118.9 B/s** | 140.2 MB/s | -| **Booleans** | 485.4 KB/s | **38.1 B/s** | 160.9 MB/s | +| Payload | Default normalized | Latency normalized | Default commits/frame | Latency commits/frame | +| :--- | ---: | ---: | ---: | ---: | +| Vectors | 118.13 | 38.84 | 3 | 1 | +| Booleans | 10.43 | 10.38 | 1 | 1 | +| Mixed | 4.29 | 4.31 | 1 | 1 | +| Entities | 117.53 | 39.15 | 3 | 1 | +| Strings | 899.63 | 96.37 | 8 | 1 | +| SingleValue | 2.39 | 2.38 | 1 | 1 | > [!NOTE] -> **Payload Segmentation**: In standard use (Stability Mode), Satset segments payloads at 60KB to ensure frame-time consistency. Latency mode sends larger segments to allow better compression density when needed. +> `Normalized` is `Stats.DataSendKbps` adjusted to 60 FPS. The default benchmark profile uses `reliableThreshold = 60000` and `maxPacketsPerFrame = 20`. The latency profile uses `reliableThreshold = 0` and `maxPacketsPerFrame = 0`. -Detailed methodology and raw data can be found in the [Benchmarks Report](benchmark/Benchmarks.md). +Detailed methodology and raw data are in the [Benchmarks Report](benchmark/Benchmarks.md). # Documentation -Comprehensive technical documentation is available in the `docs/` directory: +Technical documentation is available in the `docs/` directory: - **[Architecture & Getting Started](docs/guide/getting-started.md)**: High-level overview and initialization. - **[API Reference](docs/api/satset.md)**: Detailed breakdown of the `Satset` namespace. -- **[Development Patterns](docs/guide/development-patterns.md)**: Design principles and performance constraints. +- **[Development Patterns](docs/guide/development-patterns.md)**: Design rules and performance constraints. - **[Security & Guard](docs/guide/security.md)**: Documentation on the token bucket rate limiting implementation. - **[Serialization Types](docs/api/types.md)**: Available data types for buffer-backed schemas. @@ -63,14 +66,15 @@ Satset provides two distinct communication modes: ## Implementation Details -- **Zero-Allocation Pipeline**: Core operations happen in pre-allocated buffers. We use a callback-based dispatch model to minimize heap allocations on the hot path. +- **Buffer-backed batching**: Outgoing payloads are encoded into Luau buffers and committed as exact-size buffers before transport. - **Nested Structs**: Use `Satset.struct(schema)` to create reusable, composable type objects for complex nested schemas. - **Readable Type Names**: Provides human-readable aliases (`string`, `uint8`, `float64`, etc.) alongside shorthand forms for cleaner, more self-documenting schemas. -- **Built-in Security**: Relies on Luau's native buffer bounds checks. Payload errors are caught via `pcall` to maintain stability without redundant manual checks. +- **Packet dispatch**: Incoming batches are decoded in place. Each packet listener receives a decoded table. +- **Built-in Security**: Relies on Luau's native buffer bounds checks. Payload errors are caught via `pcall` before they reach game code. - **Buffer Safety**: Dynamic data (strings/arrays) is capped relative to the physical buffer size to prevent memory-related issues. - **Sanitized Floats**: Floating-point types (`f32`, `f64`, `Vector3`, etc.) are clamped to 0 if they are `NaN` or `±Infinity` to prevent state corruption. - **Header Stripping**: Automatically identifies fixed-size schemas and omits size headers when possible to reduce protocol overhead. -- **MTU Management**: Automatic fragmentation for batches exceeding the [MTU](https://en.wikipedia.org/wiki/Maximum_transmission_unit) limit. +- **Batch Segmentation**: Reliable batches split at `reliableThreshold`. Unreliable batches split around the configured unreliable threshold, which defaults to 900 bytes. - **Guard**: Built-in server-side rate limiting using a token bucket algorithm to prevent spam. # Architecture @@ -111,13 +115,14 @@ flowchart TB DP --> PK DC --> CH - PK -->|"encode(schema, data)"| SR + PK -->|"calculateSize(schema, data)"| SR ST -->|"compile nested"| SC SR --> SC SR --> SN SC --> TP - PK -->|"enqueue(id, payload)"| BT + PK -->|"allocate stream slot"| BT + PK -->|"encodeInto(buffer, offset)"| SR CH -->|"encodeDelta(bitmask)"| BT BT -->|"flush & segment"| BR @@ -163,7 +168,8 @@ Satset.start({ refillRate = 30, }, batching = { - reliableThreshold = 60000, -- Segmentation for stability + reliableThreshold = 60000, -- Split reliable batches above 60 KB + maxPacketsPerFrame = 0, -- Send all ready batches each frame } }) ``` diff --git a/benchmark/Benchmarks.md b/benchmark/Benchmarks.md index 3a06648..3609222 100644 --- a/benchmark/Benchmarks.md +++ b/benchmark/Benchmarks.md @@ -1,289 +1,285 @@ # [Satset](https://github.com/bookek/satset) Networking Benchmarks -**Last Updated:** May 24, 2026 (source alignment update; raw results from May 5, 2026) +**Last updated:** May 25, 2026 -These benchmarks compare **Satset** against native Roblox remotes and popular community libraries. To ensure a fair comparison, all metrics are normalized to a 60 FPS baseline, even when a library causes the engine's framerate to drop. +These benchmarks compare Satset with native Roblox remotes and several community networking libraries. The benchmark runner fires 200 events per frame for 10 seconds. A `120K / 120K` sent/received count means 120,000 events were sent and verified by the server. -The benchmark runner fires 200 events per frame for each library. Payload descriptions below describe one event payload. A `120K / 120K` sent/received count means 120,000 events over the 10 second run. +The tables use the raw fields from `default-mode-result.json` and `latency-mode-result.json`. ---- +- `Bandwidth` is Roblox `Stats.DataSendKbps` p50. +- `Normalized` is `Stats.DataSendKbps` adjusted to a 60 FPS baseline. +- `Drain` is seconds. +- `Loss` is only `Sent` vs `Received`. A partial run can still show `0.0%` loss. -## 1. Detailed Test Results - -### 1.1 Vectors -> -> Each event contains 100 `Vector3` values. Satset encodes them as `Vector3F16`. -> Measures raw spatial data throughput. -> -> - **FPS:** Higher is better. -> - **Bandwidth:** Lower is better. -> - **Loss:** Lower is better. - -#### Vectors: Default Mode (Stability First) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 60 / 60 / 60 | 200.7 KB/s | 205.5 KB/s | 9.64ms | 120K / 120K | 0.0% | -| BridgeNet2 | 60 / 50 / 60 | 15.6 KB/s | 15.6 KB/s | 23.51ms | 108.2K / 108.2K | 0.0% | -| ByteNet | 60 / 60 / 60 | 72.8 KB/s | 72.9 KB/s | 9.45ms | 120K / 120K | 0.0% | -| Warp | 60 / 52 / 60 | 3.1 KB/s | 3.1 KB/s | 3.78ms | 114K / 114K | 0.0% | -| NetRay | 61 / 60 / 61 | 72.8 KB/s | 72.8 KB/s | 9.63ms | 120K / 120K | 0.0% | -| Zap | 60 / 60 / 60 | 73.1 KB/s | 73.1 KB/s | 9.54ms | 119.8K / 119.8K | 0.0% | -| Blink | 60 / 60 / 60 | 73.0 KB/s | 73.0 KB/s | 9.43ms | 120K / 120K | 0.0% | -| **Satset** | **60 / 45 / 60** | **118.9 KB/s** | **127.7 KB/s** | **9.39ms** | **114.2K / 114.2K** | **0.0%** | - -#### Vectors: Latency Mode (Bypass Chunking) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 60 / 60 / 60 | 145.2 KB/s | 145.2 KB/s | 9.33ms | 120K / 120K | 0.0% | -| BridgeNet2 | 60 / 60 / 61 | 15.7 KB/s | 15.7 KB/s | 22.01ms | 120K / 120K | 0.0% | -| ByteNet | 61 / 60 / 61 | 73.0 KB/s | 73.0 KB/s | 9.06ms | 120K / 120K | 0.0% | -| Warp | 60 / 57 / 60 | 2.8 KB/s | 2.8 KB/s | 3.78ms | 96.6K / 96.6K | 0.0% | -| NetRay | 61 / 60 / 61 | 72.8 KB/s | 73.0 KB/s | 8.78ms | 119.8K / 119.8K | 0.0% | -| Zap | 60 / 60 / 60 | 72.9 KB/s | 72.9 KB/s | 8.84ms | 120K / 120K | 0.0% | -| Blink | 61 / 60 / 61 | 73.0 KB/s | 73.0 KB/s | 8.79ms | 120K / 120K | 0.0% | -| **Satset** | **60 / 60 / 60** | **39.2 KB/s** | **39.2 KB/s** | **7.73ms** | **120K / 120K** | **0.0%** | - -##### Vectors Breakdown - -- **Default Mode:** Satset shows a dip in minimum FPS (45) while using 60KB segmentation. -- **Latency Mode:** With segmentation bypassed, Satset keeps a 60 FPS minimum and bandwidth drops to 39.2 KB/s as fewer Zstd dictionary resets occur. - -### 1.2 Booleans -> -> Each event contains 1,000 `boolean` values. Measures bit-packing efficiency. -> -> - **FPS:** Higher is better. -> - **Bandwidth:** Lower is better. - -#### Booleans: Default Mode (Stability First) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 48 / 44 / 48 | 65.1 KB/s | 65.1 KB/s | 10.88ms | 90K / 90K | 0.0% | -| BridgeNet2 | 49 / 31 / 49 | 24.5 KB/s | 24.5 KB/s | 23.95ms | 73.4K / 73.4K | 0.0% | -| ByteNet | 57 / 34 / 57 | 16.3 KB/s | 19.4 KB/s | 6.48ms | 89.8K / 89.8K | 0.0% | -| Warp | 60 / 60 / 60 | 2.3 KB/s | 2.3 KB/s | 3.66ms | 120K / 120K | 0.0% | -| NetRay | 60 / 60 / 60 | 10.3 KB/s | 10.3 KB/s | 6.23ms | 120K / 120K | 0.0% | -| Zap | 60 / 51 / 60 | 28.5 KB/s | 28.5 KB/s | 7.81ms | 94.6K / 94.6K | 0.0% | -| Blink | 60 / 60 / 60 | 29.4 KB/s | 29.4 KB/s | 7.46ms | 120K / 120K | 0.0% | -| **Satset** | **61 / 60 / 61** | **10.4 KB/s** | **10.4 KB/s** | **5.76ms** | **120K / 120K** | **0.0%** | - -#### Booleans: Latency Mode (Bypass Chunking) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 50 / 49 / 52 | 62.0 KB/s | 62.0 KB/s | 11.32ms | 99.4K / 99.4K | 0.0% | -| BridgeNet2 | 55 / 49 / 57 | 21.7 KB/s | 24.0 KB/s | 26.04ms | 107.8K / 107.8K | 0.0% | -| ByteNet | 60 / 60 / 60 | 19.0 KB/s | 18.9 KB/s | 6.32ms | 119.8K / 119.8K | 0.0% | -| Warp | 60 / 60 / 60 | 2.4 KB/s | 2.4 KB/s | 3.81ms | 120K / 120K | 0.0% | -| NetRay | 60 / 60 / 60 | 10.2 KB/s | 10.2 KB/s | 5.26ms | 120K / 120K | 0.0% | -| Zap | 60 / 60 / 60 | 29.3 KB/s | 29.3 KB/s | 7.26ms | 119.8K / 119.8K | 0.0% | -| Blink | 60 / 60 / 61 | 29.2 KB/s | 29.1 KB/s | 7.29ms | 120K / 120K | 0.0% | -| **Satset** | **60 / 60 / 60** | **10.4 KB/s** | **10.4 KB/s** | **5.28ms** | **120K / 120K** | **0.0%** | - -##### Booleans Breakdown - -- Satset maintains consistent 60 FPS in Latency Mode, with bit-packing efficiency outperforming Zap and Blink, while remaining tied with NetRay for bandwidth leadership. - -### 1.3 Mixed Data -> -> Each event contains one table with strings, numbers, booleans, and vectors. Measures general-purpose serialization. -> -> - **Bandwidth:** Lower is better. -> - **FPS:** Higher is better. - -#### Mixed Data: Default Mode (Stability First) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 60 / 60 / 60 | 3.9 KB/s | 3.9 KB/s | 9.63ms | 120K / 120K | 0.0% | -| BridgeNet2 | 60 / 60 / 60 | 1.6 KB/s | 1.6 KB/s | 17.53ms | 120K / 120K | 0.0% | -| ByteNet | 60 / 59 / 60 | 4.9 KB/s | 4.9 KB/s | 4.78ms | 119.8K / 119.8K | 0.0% | -| Warp | 60 / 48 / 60 | 2.4 KB/s | 2.4 KB/s | 3.94ms | 80.2K / 80.2K | 0.0% | -| NetRay | 60 / 60 / 60 | 5.0 KB/s | 5.0 KB/s | 4.74ms | 120K / 120K | 0.0% | -| Zap | 61 / 60 / 61 | 5.0 KB/s | 5.0 KB/s | 4.69ms | 120K / 120K | 0.0% | -| Blink | 61 / 54 / 61 | 4.9 KB/s | 4.9 KB/s | 4.64ms | 98.2K / 98.2K | 0.0% | -| **Satset** | **60 / 60 / 60** | **4.3 KB/s** | **4.3 KB/s** | **4.70ms** | **120K / 120K** | **0.0%** | - -#### Mixed Data: Latency Mode (Bypass Chunking) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 60 / 60 / 60 | 3.9 KB/s | 3.9 KB/s | 9.31ms | 119.8K / 119.8K | 0.0% | -| BridgeNet2 | 60 / 55 / 60 | 1.6 KB/s | 1.6 KB/s | 17.76ms | 89.8K / 89.8K | 0.0% | -| ByteNet | 60 / 60 / 60 | 4.9 KB/s | 4.9 KB/s | 4.21ms | 120K / 120K | 0.0% | -| Warp | 60 / 60 / 61 | 2.2 KB/s | 2.2 KB/s | 3.81ms | 119.8K / 119.8K | 0.0% | -| NetRay | 60 / 60 / 61 | 4.9 KB/s | 4.9 KB/s | 4.25ms | 120K / 120K | 0.0% | -| Zap | 60 / 60 / 60 | 4.9 KB/s | 4.9 KB/s | 4.28ms | 120K / 120K | 0.0% | -| Blink | 60 / 60 / 61 | 4.9 KB/s | 4.9 KB/s | 4.19ms | 120K / 120K | 0.0% | -| **Satset** | **60 / 60 / 60** | **4.3 KB/s** | **4.3 KB/s** | **4.21ms** | **120K / 120K** | **0.0%** | - -##### Mixed Data Breakdown - -- Under mixed data structures, Satset maintains 60 FPS and stays close to generated networking libraries like NetRay and Zap. - -### 1.4 Entities (High Volume) -> -> Each event contains 100 entity records, each with six `u8` fields. Measures high-frequency bulk replication. -> -> - **FPS:** Higher is better (Crucial for game feel). -> - **Bandwidth:** Lower is better. - -#### Entities: Default Mode (Stability First) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 18 / 18 / 18 | 206.8 KB/s | 206.8 KB/s | 14.76ms | 35.4K / 35.4K | 0.0% | -| BridgeNet2 | 16 / 15 / 16 | 9.7 KB/s | 38.8 KB/s | 29.18ms | 11.2K / 11.2K | 0.0% | -| ByteNet | 52 / 47 / 52 | 33.6 KB/s | 40.0 KB/s | 7.69ms | 85.2K / 85.2K | 0.0% | -| Warp | 49 / 38 / 49 | 7.5 KB/s | 10.2 KB/s | 6.34ms | 65.2K / 65.2K | 0.0% | -| NetRay | 60 / 59 / 60 | 39.0 KB/s | 39.1 KB/s | 8.31ms | 119.8K / 119.8K | 0.0% | -| Zap | 60 / 46 / 60 | 38.8 KB/s | 40.4 KB/s | 8.42ms | 111.6K / 111.6K | 0.0% | -| Blink | 60 / 60 / 60 | 39.0 KB/s | 39.0 KB/s | 8.31ms | 120K / 120K | 0.0% | -| **Satset** | **61 / 60 / 61** | **119.2 KB/s** | **119.2 KB/s** | **9.19ms** | **120K / 120K** | **0.0%** | - -> [!IMPORTANT] -> **ByteNet Performance Anomaly:** ByteNet showed a significant dip to 52 FPS under the entity workload. This indicates difficulty maintaining engine-locked framerates in this benchmark case. - -#### Entities: Latency Mode (Bypass Chunking) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 19 / 18 / 19 | 206.7 KB/s | 206.7 KB/s | 14.77ms | 34.8K / 34.8K | 0.0% | -| BridgeNet2 | 18 / 16 / 18 | 27.0 KB/s | 97.7 KB/s | 26.51ms | 27.0K / 27.0K | 0.0% | -| ByteNet | 61 / 57 / 61 | 38.9 KB/s | 39.2 KB/s | 7.78ms | 118.8K / 118.8K | 0.0% | -| Warp | 52 / 40 / 52 | 10.1 KB/s | 11.8 KB/s | 5.29ms | 87.6K / 87.6K | 0.0% | -| NetRay | 61 / 60 / 61 | 38.9 KB/s | 38.9 KB/s | 7.83ms | 120K / 120K | 0.0% | -| Zap | 60 / 60 / 60 | 39.0 KB/s | 39.0 KB/s | 7.83ms | 120K / 120K | 0.0% | -| Blink | 61 / 60 / 61 | 39.0 KB/s | 39.0 KB/s | 7.51ms | 120K / 120K | 0.0% | -| **Satset** | **60 / 60 / 60** | **39.1 KB/s** | **39.1 KB/s** | **7.80ms** | **120K / 120K** | **0.0%** | - -##### Entities Breakdown - -- Under the entity workload, Satset maintains a 61 FPS median with zero packet loss in Default Mode. - -### 1.5 Strings -> -> Each event contains 100 short strings, each 8-32 characters. Measures buffer handling and string transfer cost. -> -> - **FPS:** Higher is better. -> - **Bandwidth:** Lower is better. - -#### Strings: Default Mode (Stability First) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 60 / 55 / 60 | 156.6 KB/s | 156.6 KB/s | 12.34ms | 118.6K / 118.6K | 0.0% | -| BridgeNet2 | 60 / 60 / 60 | 27.4 KB/s | 27.4 KB/s | 24.13ms | 119.8K / 119.8K | 0.0% | -| ByteNet | 0 / 0 / 0 | 0.0 KB/s | 0.0 KB/s | 3.54ms | 1.4K / 1.4K | 100% | -| Warp | 61 / 60 / 61 | 16.6 KB/s | 16.6 KB/s | 6.38ms | 120K / 120K | 0.0% | -| NetRay | 60 / 60 / 60 | 96.7 KB/s | 96.7 KB/s | 10.29ms | 120K / 120K | 0.0% | -| Zap | 60 / 52 / 60 | 100.4 KB/s | 100.4 KB/s | 10.15ms | 88.6K / 88.6K | 0.0% | -| Blink | 60 / 53 / 60 | 100.2 KB/s | 100.2 KB/s | 11.79ms | 98.8K / 98.8K | 0.0% | -| **Satset** | **60 / 57 / 60** | **948.9 KB/s** | **948.9 KB/s** | **10.31ms** | **117.2K / 117.2K** | **0.0%** | - -> [!IMPORTANT] -> **ByteNet Failure Analysis:** In the Strings benchmark, ByteNet failed after processing approximately 1,400 packets. This resulted in 0 recorded FPS/Bandwidth metrics for that run. - -#### Strings: Latency Mode (Bypass Chunking) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 61 / 53 / 61 | 82.0 KB/s | 85.2 KB/s | 10.94ms | 112.2K / 112.2K | 0.0% | -| BridgeNet2 | 60 / 55 / 60 | 27.2 KB/s | 27.3 KB/s | 24.26ms | 106.2K / 106.2K | 0.0% | -| ByteNet | 0 / 0 / 0 | 0.0 B/s | 0.0 B/s | 3.01ms | 1.6K / 1.6K | 100% | -| Warp | 60 / 60 / 60 | 5.5 KB/s | 5.5 KB/s | 3.76ms | 120K / 120K | 0.0% | -| NetRay | 60 / 60 / 60 | 96.8 KB/s | 96.8 KB/s | 10.83ms | 120K / 120K | 0.0% | -| Zap | 60 / 60 / 60 | 100.7 KB/s | 100.7 KB/s | 9.86ms | 120K / 120K | 0.0% | -| Blink | 60 / 60 / 60 | 100.3 KB/s | 100.4 KB/s | 9.86ms | 120K / 120K | 0.0% | -| **Satset** | **60 / 60 / 60** | **96.5 KB/s** | **96.5 KB/s** | **9.88ms** | **120K / 120K** | **0.0%** | - -##### Strings Breakdown - -- **Latency Mode:** Satset is close to NetRay and Zap in string throughput when segmentation is disabled. This indicates that segmentation and compression reset behavior are major parts of the Default Mode bandwidth result. -- **ByteNet Reliability:** ByteNet failed again in Latency Mode, stopping after 1,600 packets in this run. - -### 1.6 SingleValue -> -> Sending a single primitive value (`u8`) per packet. Measures the baseline overhead of the library's batching system. -> -> - **Bandwidth:** Lower is better. -> - **FPS:** Higher is better. - -#### SingleValue: Default Mode (Stability First) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 60 / 60 / 60 | 227.2 KB/s | 227.2 KB/s | 10.79ms | 120K / 120K | 0.0% | -| BridgeNet2 | 60 / 60 / 60 | 141.8 KB/s | 141.8 KB/s | 11.51ms | 120K / 120K | 0.0% | -| ByteNet | 61 / 60 / 61 | 2.2 KB/s | 2.2 KB/s | 3.68ms | 120K / 120K | 0.0% | -| Warp | 60 / 60 / 60 | 2.3 KB/s | 2.3 KB/s | 3.76ms | 120K / 120K | 0.0% | -| NetRay | 61 / 60 / 61 | 2.4 KB/s | 2.3 KB/s | 3.73ms | 120K / 120K | 0.0% | -| Zap | 61 / 60 / 61 | 2.3 KB/s | 2.3 KB/s | 3.73ms | 120K / 120K | 0.0% | -| Blink | 60 / 60 / 60 | 2.4 KB/s | 2.4 KB/s | 3.71ms | 120K / 120K | 0.0% | -| **Satset** | **61 / 55 / 61** | **2.4 KB/s** | **2.4 KB/s** | **4.03ms** | **103K / 103K** | **0.0%** | - -#### SingleValue: Latency Mode (Bypass Chunking) - -| Library | FPS (p50/min/p95) | Bandwidth (p50) | Norm. BW (p50) | Drain Duration | Sent / Recv | Loss % | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| Roblox | 61 / 60 / 61 | 230.0 KB/s | 230.0 KB/s | 8.38ms | 120K / 120K | 0.0% | -| BridgeNet2 | 60 / 55 / 60 | 142.4 KB/s | 142.4 KB/s | 10.68ms | 98.8K / 98.8K | 0.0% | -| ByteNet | 61 / 60 / 61 | 2.3 KB/s | 2.3 KB/s | 3.73ms | 120K / 120K | 0.0% | -| Warp | 60 / 60 / 60 | 2.4 KB/s | 2.4 KB/s | 4.01ms | 119.8K / 119.8K | 0.0% | -| NetRay | 60 / 60 / 60 | 2.4 KB/s | 2.4 KB/s | 3.73ms | 120K / 120K | 0.0% | -| Zap | 60 / 60 / 60 | 2.3 KB/s | 2.3 KB/s | 3.69ms | 120K / 120K | 0.0% | -| Blink | 61 / 60 / 61 | 2.4 KB/s | 2.4 KB/s | 3.81ms | 120K / 120K | 0.0% | -| **Satset** | **61 / 60 / 61** | **2.4 KB/s** | **2.4 KB/s** | **3.74ms** | **120K / 120K** | **0.0%** | - -##### SingleValue Breakdown - -- In single-value tests, Satset demonstrates minimal batching overhead, performing almost identically to pure code-gen libraries despite its internal stateful synchronization features. +Treat rows with low frame counts or partial packet counts as incomplete rows, not winners. ByteNet in the Strings test is the clearest example: it reports `0.00` bandwidth because the run stops early, not because it sends data for free. --- -## 2. Technical Analysis +## Result Summary + +Satset is clean in all default and latency rows. The current default profile still fragments large reliable payloads. That shows up as 3 reliable commits per frame for Vectors and Entities, and 8 reliable commits per frame for Strings. The latency profile uses one reliable commit per frame and cuts those bandwidth numbers sharply. + +Current Satset default rows: -### The "Compression Illusion" +| Payload | Frames | Sent / Received | Min FPS | Commits / frame | Normalized | +| :--- | ---: | :--- | ---: | ---: | ---: | +| Vectors | 601 | 120.2K / 120.2K | 60 | 3 | 118.13 | +| Booleans | 601 | 120.2K / 120.2K | 60 | 1 | 10.43 | +| Mixed | 601 | 120.2K / 120.2K | 60 | 1 | 4.29 | +| Entities | 601 | 120.2K / 120.2K | 60 | 3 | 117.53 | +| Strings | 601 | 120.2K / 120.2K | 60 | 8 | 899.63 | +| SingleValue | 601 | 120.2K / 120.2K | 60 | 1 | 2.39 | -Roblox uses [Zstd](https://facebook.github.io/zstd/) compression on network traffic. Sending repeated data in fewer buffers can produce lower reported bandwidth because compression has more context. +Current Satset latency rows: -- **Example:** In the **Vectors** benchmark, Satset's normalized bandwidth dropped from **127.7 KB/s** (Default) to **39.2 KB/s** (Latency) when segmentation was bypassed. This shows that segmentation and compression reset behavior affect reported bandwidth. +| Payload | Frames | Sent / Received | Min FPS | Commits / frame | Normalized | +| :--- | ---: | :--- | ---: | ---: | ---: | +| Vectors | 600 | 120K / 120K | 60 | 1 | 38.84 | +| Booleans | 601 | 120.2K / 120.2K | 60 | 1 | 10.38 | +| Mixed | 600 | 120K / 120K | 60 | 1 | 4.31 | +| Entities | 601 | 120.2K / 120.2K | 60 | 1 | 39.15 | +| Strings | 600 | 120K / 120K | 60 | 1 | 96.37 | +| SingleValue | 601 | 120.2K / 120.2K | 60 | 1 | 2.38 | -### GC Pressure and Frame Drops +Opinionated read: -The `Entities` test highlights the impact of allocation and batching behavior. Libraries that create many remote calls or intermediate tables per frame can show lower minimum framerates. Satset's batcher keeps this case at 60 FPS in Default Mode. +- Satset's serializer is not the source of the default-mode gap. Raw bytes per packet are almost identical between default and latency. +- Commit count is the main signal. Vectors and Entities use 3 commits per frame in default mode. Strings uses 8. +- The next useful profile is a named throughput profile that keeps one reliable commit per frame without changing default behavior. +- Repeated-id segmentation should be tested separately. It can reduce benchmark bytes in homogeneous rows, but it does not explain the large default-mode gap by itself. + +--- -### Throttling Philosophy +## Payloads -Satset can spread network load across multiple frames, visible in the higher Drain Duration. This can add a small amount of latency while reducing frame-time spikes. +| Payload | Contents | +| :--- | :--- | +| Vectors | 100 `Vector3` values. Satset uses `Vector3F16`. | +| Booleans | 1,000 boolean values. | +| Mixed | One table with integers, booleans, vectors, and a short string. | +| Entities | 100 records, each with six `u8` fields. | +| Strings | 100 short strings, each 8 to 32 characters. | +| SingleValue | One `u8` value. | --- -## 3. Methodology - -- **Environment:** Local Roblox Studio (1 Player). -- **Test Intensity:** 200 events per frame (approx. 12,000 per second) for 10 seconds. -- **Payload Source:** `benchmark/src/shared/benches`. -- **Satset Mode Source:** `benchmark/src/shared/BenchmarkConfig.luau`. -- **Metrics:** - - **FPS p50/min/p95:** Median, absolute minimum, and 95th percentile framerate (**Higher is better**). - - **Bandwidth p50:** Median raw bytes per second sent over the network (**Lower is better**). - - **Normalized Bandwidth:** Bandwidth adjusted to a 60 FPS baseline (**Lower is better**). - - **Drain Duration:** Time (ms) for the internal data queue to empty (**Lower is better for latency**). - - **Sent / Received:** Total packets fired vs. packets successfully verified on the server (**Higher is better**). - - **Loss %:** Percentage of packets that were dropped or failed verification (**Lower is better**). -- **Validation:** Every packet is verified for data integrity using epsilon-based comparisons. +## Vectors + +### Default Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 60 / 60 / 60 | 179145.70 | 179145.71 | 9.65 | 120K / 120K | 0.0% | +| BridgeNet2 | 60 / 60 / 60 | 15641.98 | 15641.98 | 22.55 | 120K / 120K | 0.0% | +| ByteNet | 60 / 59 / 60 | 72.48 | 72.48 | 9.43 | 119.8K / 119.8K | 0.0% | +| Warp | 60 / 54 / 60 | 2.89 | 2.93 | 5.02 | 107.2K / 107.2K | 0.0% | +| NetRay | 60 / 60 / 61 | 72.54 | 72.49 | 9.87 | 120K / 120K | 0.0% | +| Zap | 60 / 60 / 61 | 72.77 | 72.76 | 9.40 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 60 | 72.72 | 72.72 | 9.45 | 120K / 120K | 0.0% | +| Packet | 60 / 60 / 61 | 72.47 | 72.43 | 9.52 | 120.2K / 120.2K | 0.0% | +| Satset | 60 / 60 / 60 | 118.13 | 118.13 | 8.88 | 120.2K / 120.2K | 0.0% | + +### Latency Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 60 / 60 / 61 | 174809.52 | 174809.52 | 9.87 | 120K / 120K | 0.0% | +| BridgeNet2 | 60 / 59 / 60 | 15613.31 | 15613.31 | 22.55 | 119.8K / 119.8K | 0.0% | +| ByteNet | 60 / 60 / 61 | 72.59 | 72.56 | 10.32 | 120K / 120K | 0.0% | +| Warp | 60 / 54 / 61 | 6.71 | 6.71 | 5.15 | 107.8K / 107.8K | 0.0% | +| NetRay | 60 / 52 / 61 | 71.83 | 71.83 | 9.88 | 108.6K / 108.6K | 0.0% | +| Zap | 60 / 60 / 60 | 72.78 | 72.78 | 9.53 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 61 | 72.62 | 72.62 | 9.50 | 120.2K / 120.2K | 0.0% | +| Packet | 60 / 60 / 60 | 72.85 | 72.85 | 10.08 | 120K / 120K | 0.0% | +| Satset | 60 / 60 / 61 | 38.84 | 38.84 | 8.22 | 120K / 120K | 0.0% | + +Satset wins this row in latency mode. Default mode still pays for three reliable commits per frame. + +## Booleans + +### Default Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 48 / 43 / 51 | 52079.03 | 63487.25 | 10.86 | 93.6K / 93.6K | 0.0% | +| BridgeNet2 | 54 / 52 / 56 | 21597.02 | 24020.96 | 23.38 | 92.8K / 92.8K | 0.0% | +| ByteNet | 60 / 60 / 60 | 19.04 | 19.04 | 6.75 | 120K / 120K | 0.0% | +| Warp | 60 / 60 / 60 | 2.53 | 2.53 | 3.75 | 120K / 120K | 0.0% | +| NetRay | 60 / 60 / 60 | 10.27 | 10.27 | 5.73 | 120K / 120K | 0.0% | +| Zap | 60 / 60 / 60 | 29.35 | 29.35 | 7.80 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 61 | 29.38 | 29.38 | 7.48 | 120K / 120K | 0.0% | +| Packet | 57 / 48 / 61 | 25.30 | 26.89 | 6.58 | 93.2K / 93.2K | 0.0% | +| Satset | 60 / 60 / 61 | 10.43 | 10.43 | 5.47 | 120.2K / 120.2K | 0.0% | + +### Latency Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 47 / 46 / 48 | 54850.50 | 71744.48 | 10.88 | 93.2K / 93.2K | 0.0% | +| BridgeNet2 | 52 / 50 / 52 | 20440.36 | 23969.86 | 23.73 | 102.2K / 102.2K | 0.0% | +| ByteNet | 60 / 60 / 61 | 19.18 | 19.18 | 6.57 | 120K / 120K | 0.0% | +| Warp | 60 / 60 / 60 | 2.51 | 2.51 | 3.83 | 120K / 120K | 0.0% | +| NetRay | 60 / 60 / 60 | 10.41 | 10.41 | 5.52 | 120K / 120K | 0.0% | +| Zap | 60 / 60 / 60 | 29.42 | 29.42 | 7.57 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 61 | 29.40 | 29.40 | 7.48 | 120.2K / 120.2K | 0.0% | +| Packet | 58 / 57 / 60 | 26.10 | 27.07 | 7.36 | 115.8K / 115.8K | 0.0% | +| Satset | 60 / 60 / 61 | 10.39 | 10.38 | 5.73 | 120.2K / 120.2K | 0.0% | + +Warp is the bandwidth leader. Satset and NetRay sit close together and both stay at full frame rate. + +## Mixed + +### Default Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 60 / 60 / 60 | 3645.96 | 3645.96 | 9.32 | 120K / 120K | 0.0% | +| BridgeNet2 | 60 / 60 / 60 | 1674.85 | 1674.85 | 17.47 | 120K / 120K | 0.0% | +| ByteNet | 61 / 60 / 61 | 4.86 | 4.86 | 4.73 | 120K / 120K | 0.0% | +| Warp | 60 / 60 / 60 | 2.37 | 2.37 | 3.80 | 120K / 120K | 0.0% | +| NetRay | 60 / 56 / 61 | 4.97 | 4.99 | 4.45 | 104.6K / 104.6K | 0.0% | +| Zap | 60 / 60 / 60 | 5.06 | 5.06 | 4.53 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 60 | 5.02 | 5.02 | 4.38 | 120K / 120K | 0.0% | +| Packet | 60 / 60 / 60 | 4.79 | 4.79 | 4.38 | 120.2K / 120.2K | 0.0% | +| Satset | 60 / 60 / 61 | 4.28 | 4.29 | 4.11 | 120.2K / 120.2K | 0.0% | + +### Latency Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 60 / 60 / 60 | 3558.99 | 3558.99 | 9.38 | 120K / 120K | 0.0% | +| BridgeNet2 | 60 / 60 / 61 | 1680.33 | 1680.33 | 16.98 | 120K / 120K | 0.0% | +| ByteNet | 60 / 60 / 61 | 4.86 | 4.86 | 4.65 | 120K / 120K | 0.0% | +| Warp | 60 / 60 / 60 | 2.29 | 2.29 | 3.61 | 120K / 120K | 0.0% | +| NetRay | 60 / 60 / 61 | 4.99 | 4.99 | 4.38 | 120K / 120K | 0.0% | +| Zap | 60 / 60 / 60 | 4.97 | 4.97 | 4.58 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 60 | 5.01 | 5.01 | 4.72 | 120.2K / 120.2K | 0.0% | +| Packet | 60 / 60 / 60 | 4.70 | 4.70 | 4.37 | 120K / 120K | 0.0% | +| Satset | 60 / 60 / 60 | 4.31 | 4.31 | 4.22 | 120K / 120K | 0.0% | + +Satset is not the lowest bandwidth row, but it is close to Packet, ByteNet, NetRay, Zap, and Blink while staying at full frame rate. + +## Entities + +### Default Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 19 / 18 / 20 | 200387.59 | 658854.21 | 14.23 | 36K / 36K | 0.0% | +| BridgeNet2 | 17 / 16 / 20 | 21929.40 | 81590.27 | 27.51 | 26.8K / 26.8K | 0.0% | +| ByteNet | 60 / 60 / 61 | 39.03 | 38.88 | 8.28 | 119.8K / 119.8K | 0.0% | +| Warp | 53 / 50 / 55 | 11.20 | 12.73 | 5.86 | 104.8K / 104.8K | 0.0% | +| NetRay | 60 / 59 / 61 | 38.92 | 38.85 | 8.33 | 119.8K / 119.8K | 0.0% | +| Zap | 60 / 60 / 61 | 38.92 | 38.87 | 8.28 | 119.8K / 119.8K | 0.0% | +| Blink | 60 / 49 / 60 | 36.03 | 36.03 | 8.45 | 80.8K / 80.8K | 0.0% | +| Packet | 50 / 49 / 52 | 31.26 | 38.21 | 8.38 | 99.4K / 99.4K | 0.0% | +| Satset | 60 / 60 / 60 | 117.53 | 117.53 | 9.24 | 120.2K / 120.2K | 0.0% | + +### Latency Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 18 / 17 / 19 | 197299.86 | 690549.54 | 14.27 | 34.2K / 34.2K | 0.0% | +| BridgeNet2 | 18 / 17 / 19 | 28973.95 | 98591.93 | 27.85 | 30.2K / 30.2K | 0.0% | +| ByteNet | 60 / 60 / 61 | 39.04 | 39.04 | 8.35 | 119.8K / 119.8K | 0.0% | +| Warp | 52 / 48 / 53 | 9.99 | 12.04 | 7.01 | 100.2K / 100.2K | 0.0% | +| NetRay | 60 / 60 / 60 | 38.97 | 38.97 | 8.32 | 120K / 120K | 0.0% | +| Zap | 60 / 60 / 60 | 38.97 | 38.97 | 8.40 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 61 | 38.98 | 38.98 | 8.26 | 120.2K / 120.2K | 0.0% | +| Packet | 52 / 50 / 52 | 30.12 | 35.43 | 8.34 | 102K / 102K | 0.0% | +| Satset | 60 / 60 / 60 | 39.15 | 39.15 | 8.32 | 120.2K / 120.2K | 0.0% | + +Default mode is the weak Satset row here. Latency mode brings Satset close to NetRay, Zap, Blink, and ByteNet. + +## Strings + +### Default Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 60 / 60 / 61 | 158676.12 | 158214.25 | 11.42 | 119.8K / 119.8K | 0.0% | +| BridgeNet2 | 60 / 59 / 61 | 27369.92 | 27383.28 | 24.10 | 120K / 120K | 0.0% | +| ByteNet | 0 / 0 / 0 | 0.00 | 0.00 | 4.55 | 1.6K / 1.6K | 0.0% | +| Warp | 60 / 57 / 61 | 3.34 | 3.35 | 4.32 | 117.4K / 117.4K | 0.0% | +| NetRay | 60 / 57 / 60 | 96.02 | 96.02 | 10.35 | 91.6K / 91.6K | 0.0% | +| Zap | 60 / 60 / 60 | 101.23 | 101.23 | 10.35 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 61 | 99.90 | 99.86 | 10.35 | 119.8K / 119.8K | 0.0% | +| Packet | 60 / 58 / 60 | 95.74 | 95.76 | 10.35 | 119.8K / 119.8K | 0.0% | +| Satset | 60 / 60 / 60 | 899.63 | 899.63 | 10.30 | 120.2K / 120.2K | 0.0% | + +### Latency Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 60 / 60 / 61 | 62755.32 | 62755.32 | 13.05 | 120K / 120K | 0.0% | +| BridgeNet2 | 60 / 60 / 60 | 27457.38 | 27457.39 | 25.23 | 120K / 120K | 0.0% | +| ByteNet | 0 / 0 / 0 | 0.00 | 0.00 | 4.54 | 1.6K / 1.6K | 0.0% | +| Warp | 60 / 60 / 60 | 4.44 | 4.44 | 4.32 | 120K / 120K | 0.0% | +| NetRay | 60 / 60 / 61 | 96.40 | 96.31 | 11.95 | 120K / 120K | 0.0% | +| Zap | 60 / 60 / 61 | 100.43 | 100.30 | 10.32 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 60 | 100.05 | 100.05 | 12.30 | 120.2K / 120.2K | 0.0% | +| Packet | 60 / 60 / 61 | 95.99 | 95.99 | 10.43 | 120K / 120K | 0.0% | +| Satset | 60 / 60 / 60 | 96.37 | 96.37 | 10.33 | 120K / 120K | 0.0% | + +Strings expose the default segmentation cost most clearly. Satset falls from 899.63 to 96.37 normalized when the run uses one reliable commit per frame. + +## SingleValue + +### Default Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 60 / 55 / 60 | 231.53 | 231.96 | 9.27 | 118.6K / 118.6K | 0.0% | +| BridgeNet2 | 60 / 60 / 60 | 145.09 | 145.09 | 11.35 | 120K / 120K | 0.0% | +| ByteNet | 60 / 60 / 60 | 2.31 | 2.31 | 3.72 | 120K / 120K | 0.0% | +| Warp | 60 / 60 / 61 | 1.80 | 1.80 | 3.78 | 120K / 120K | 0.0% | +| NetRay | 60 / 58 / 60 | 2.39 | 2.39 | 3.75 | 119.6K / 119.6K | 0.0% | +| Zap | 60 / 54 / 61 | 2.39 | 2.38 | 3.80 | 118.4K / 118.4K | 0.0% | +| Blink | 61 / 60 / 61 | 2.33 | 2.33 | 3.70 | 120K / 120K | 0.0% | +| Packet | 60 / 60 / 60 | 2.29 | 2.29 | 3.73 | 120.2K / 120.2K | 0.0% | +| Satset | 60 / 60 / 60 | 2.39 | 2.39 | 3.65 | 120.2K / 120.2K | 0.0% | + +### Latency Mode + +| Library | FPS p50 / min / p95 | Bandwidth | Normalized | Drain | Sent / Received | Loss | +| :--- | :--- | ---: | ---: | ---: | :--- | ---: | +| Roblox | 60 / 60 / 61 | 233.73 | 233.73 | 10.32 | 120K / 120K | 0.0% | +| BridgeNet2 | 60 / 60 / 60 | 144.82 | 144.82 | 11.43 | 120K / 120K | 0.0% | +| ByteNet | 60 / 60 / 60 | 2.36 | 2.36 | 3.75 | 120K / 120K | 0.0% | +| Warp | 60 / 60 / 61 | 2.24 | 2.24 | 3.80 | 120K / 120K | 0.0% | +| NetRay | 60 / 60 / 60 | 2.38 | 2.38 | 3.73 | 120K / 120K | 0.0% | +| Zap | 60 / 60 / 60 | 2.38 | 2.38 | 3.73 | 120K / 120K | 0.0% | +| Blink | 60 / 60 / 60 | 2.39 | 2.39 | 3.68 | 120.2K / 120.2K | 0.0% | +| Packet | 60 / 60 / 60 | 2.31 | 2.31 | 3.75 | 120K / 120K | 0.0% | +| Satset | 60 / 60 / 61 | 2.38 | 2.38 | 3.70 | 120.2K / 120.2K | 0.0% | + +SingleValue is measurement-noise territory for the compact libraries. Warp, Packet, ByteNet, NetRay, Zap, Blink, and Satset are all close. --- -## 4. Raw Data Access +## Methodology + +- Environment: local Roblox Studio, 1 player. +- Test load: 200 events per frame for 10 seconds per library per payload. +- Payload source: `benchmark/src/shared/benches`. +- Satset profile source: `benchmark/src/shared/BenchmarkConfig.luau`. +- Default profile: `reliableThreshold = 60000`, `maxPacketsPerFrame = 20`. +- Latency profile: `reliableThreshold = 0`, `maxPacketsPerFrame = 0`. +- Validation: the server verifies every received packet. + +The benchmark does not prove a single universal winner. It shows how each library behaves under one heavy local Studio workload. Use the packet counts and min FPS before comparing bandwidth. + +## Raw Data + +- [default-mode-result.json](./default-mode-result.json) +- [latency-mode-result.json](./latency-mode-result.json) -For developers wishing to perform their own analysis or verify these claims, the complete, unedited performance logs are available in JSON format: +## Running In Roblox Studio -- **Stability First (Default):** [default-mode-result.json](./default-mode-result.json) -- **Latency Bypassed:** [latency-mode-result.json](./latency-mode-result.json) +The benchmark place file is [satset-benchmark.rbxl](./satset-benchmark.rbxl). -To regenerate the latency-mode result, set `activeMode = "latency"` in `benchmark/src/shared/BenchmarkConfig.luau` before running the benchmark. +1. Open `benchmark/satset-benchmark.rbxl` in Roblox Studio. +2. If you are testing local source changes, connect Rojo to this repo before pressing Play. +3. Set `activeMode` in `benchmark/src/shared/BenchmarkConfig.luau` to `"default"` or `"latency"`. +4. Press Play with one local player and wait until Studio Output prints `Generated results`. +5. The server creates `game.Result`, a `StringValue` whose `Value` contains the JSON for the run. Use that value for `default-mode-result.json` or `latency-mode-result.json`, based on the selected mode. diff --git a/benchmark/default-mode-result.json b/benchmark/default-mode-result.json index 7ffff3f..055e2f3 100644 --- a/benchmark/default-mode-result.json +++ b/benchmark/default-mode-result.json @@ -3,180 +3,186 @@ "warp": { "Framerate": [ 60, - 52, + 54, 60, - 61, - 61, - 61 + 60, + 60, + 60 ], "Bandwidth": [ - 3.088067054748535, - 2.6653831005096437, - 6.292206287384033, - 9.309511184692383, - 9.309511184692383, - 9.309511184692383 - ], - "DrainDuration": 3.7841443450015506, - "Sent": 114000, - "Recieve": 114000, + 2.890460968017578, + 1.7929075956344605, + 3.004763603210449, + 3.5621888637542726, + 3.5621888637542726, + 3.5621888637542726 + ], + "DrainDuration": 5.017596043006051, + "Recieve": 107200, + "Sent": 107200, + "Frames": 536, "NormalizedBandwidth": [ - 3.1382349002274094, - 2.665383239520205, - 6.86422541156543, - 9.309511670221227, - 9.309511670221227, - 9.309511670221227 + 2.9304551222412646, + 1.7929076891418783, + 3.338626403021652, + 3.622565141869823, + 3.622565141869823, + 3.622565141869823 ] }, "bridgenet2": { "Framerate": [ 60, - 50, + 60, 60, 60, 60, 60 ], "Bandwidth": [ - 15635.525390625, - 6571.4423828125, - 15684.734375, - 15690.7099609375, - 15690.7099609375, - 15690.7099609375 - ], - "DrainDuration": 23.515351253001428, - "Sent": 108200, - "Recieve": 108200, + 15641.9755859375, + 11947.02734375, + 15718.9580078125, + 15720.7001953125, + 15815.02734375, + 15815.02734375 + ], + "DrainDuration": 22.54958272499789, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 15635.526206081195, - 7918.588495291852, - 15684.735193022643, - 15690.710779271794, - 15690.710779271794, - 15690.710779271794 + 15641.976401730099, + 11947.02796683603, + 15718.958827620045, + 15720.701015210907, + 15815.028168567951, + 15815.028168567951 ] }, - "packet": { + "netray_compile": { "Framerate": [ 60, 60, - 60, + 61, 61, 61, 61 ], "Bandwidth": [ - 72.11532592773438, - 55.13937759399414, - 72.76392364501953, - 72.87982940673828, - 72.87982940673828, - 72.87982940673828 - ], - "DrainDuration": 9.949517610999465, - "Sent": 120000, + 72.53569793701172, + 54.78264236450195, + 72.73424530029297, + 73.13679504394531, + 73.13679504394531, + 73.13679504394531 + ], + "DrainDuration": 9.866517457994633, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 72.29811908592973, - 55.13937861993202, - 72.76392576307994, - 72.87983152636222, - 72.87983152636222, - 72.87983152636222 + 72.4884757654317, + 55.010906217886077, + 72.64267346634483, + 73.13679885832642, + 73.13679885832642, + 73.13679885832642 ] }, - "roblox": { + "bytenet": { "Framerate": [ 60, - 60, + 59, 60, 60, 60, 60 ], "Bandwidth": [ - 205561.421875, - 178082.953125, - 205574.609375, - 205586.203125, - 205586.203125, - 205586.203125 - ], - "DrainDuration": 9.648211512998387, - "Sent": 120000, - "Recieve": 120000, + 72.48241424560547, + 54.673179626464847, + 72.79023742675781, + 72.7933578491211, + 73.21208190917969, + 73.21208190917969 + ], + "DrainDuration": 9.43261930499284, + "Recieve": 119800, + "Sent": 119800, + "Frames": 599, "NormalizedBandwidth": [ - 205561.42531393527, - 178082.95610738677, - 205574.61281146313, - 205586.2065593845, - 205586.2065593845, - 205586.2065593845 + 72.48241802585796, + 54.67318247789336, + 72.79336164559055, + 73.2120857274873, + 73.77156780983313, + 73.77156780983313 ] }, - "satset": { + "roblox": { "Framerate": [ 60, - 45, + 60, 60, 60, 60, 60 ], "Bandwidth": [ - 118.91763305664062, - 118.91763305664062, - 118.91763305664062, - 118.91763305664062, - 118.91763305664062, - 118.91763305664062 - ], - "DrainDuration": 9.395111124999312, - "Sent": 114200, - "Recieve": 114200, + 179145.703125, + 60405.6171875, + 186123.46875, + 187852.375, + 198002.53125, + 198002.53125 + ], + "DrainDuration": 9.65049344500585, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 127.7345388047936, - 127.73454316954203, - 127.73454316954203, - 127.73454316954203, - 127.73454316954203, - 127.73454316954203 + 179145.7124681765, + 60405.620337898436, + 186123.47845709534, + 187852.38479726483, + 198002.54157663673, + 198002.54157663673 ] }, - "bytenet": { + "blink": { "Framerate": [ 60, 60, 60, - 61, - 61, - 61 + 60, + 60, + 60 ], "Bandwidth": [ - 72.71212768554688, - 52.32768249511719, - 72.93282318115234, - 72.9463119506836, - 72.9463119506836, - 72.9463119506836 - ], - "DrainDuration": 9.458212111000466, - "Sent": 120000, + 72.71742248535156, + 55.3709831237793, + 72.8493881225586, + 72.85452270507813, + 72.90422821044922, + 72.90422821044922 + ], + "DrainDuration": 9.449541082998622, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 72.8122393856112, - 52.32768346764585, - 72.93282531238947, - 72.94631408192074, - 72.94631408192074, - 72.94631408192074 + 72.71742627786068, + 55.370986011601107, + 72.84939192195026, + 72.85452650473758, + 72.90423201270102, + 72.90423201270102 ] }, - "netray": { + "zap": { "Framerate": [ - 61, + 60, 60, 61, 61, @@ -184,55 +190,90 @@ 61 ], "Bandwidth": [ - 72.76811218261719, - 55.13937759399414, - 72.8276138305664, - 72.87982940673828, - 72.87982940673828, - 72.87982940673828 - ], - "DrainDuration": 9.638211512999013, - "Sent": 120000, + 72.76981353759766, + 55.466033935546878, + 73.06119537353516, + 73.22405242919922, + 73.22405242919922, + 73.22405242919922 + ], + "DrainDuration": 9.39830150900525, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 72.8142385458312, - 55.13937861993202, - 72.8276159628868, - 72.87983152636222, - 72.87983152636222, - 72.87983152636222 + 72.76176807324086, + 55.697145289282278, + 73.1241939195844, + 73.22405624813115, + 73.22405624813115, + 73.22405624813115 ] }, - "zap": { + "packet": { "Framerate": [ 60, 60, - 60, - 60, - 60, - 60 + 61, + 61, + 61, + 61 ], "Bandwidth": [ - 73.08212280273438, - 55.27622985839844, - 73.11192321777344, - 73.11192321777344, - 73.11192321777344, - 73.11192321777344 - ], - "DrainDuration": 9.548212112997135, - "Sent": 119800, - "Recieve": 119800, + 72.4673080444336, + 57.30524444580078, + 72.7082748413086, + 72.80976104736328, + 72.80976104736328, + 72.80976104736328 + ], + "DrainDuration": 9.515919608005789, + "Recieve": 120200, + "Sent": 120200, + "Frames": 601, "NormalizedBandwidth": [ - 73.08212403213007, - 55.27623078817734, - 73.1119244473851, - 73.1119244473851, - 73.1119244473851, - 73.1119244473851 + 72.43305584066633, + 57.30524743450218, + 72.80976484468823, + 72.9157867292972, + 72.9157867292972, + 72.9157867292972 ] }, - "blink": { + "satset": { + "DrainDuration": 8.884687450001366, + "DebugStats": { + "reliableCommitBytes": 72724606, + "commitGcKb": 234, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 1803, + "reliableCommits": 1803, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120200, + "sendGcSamples": 240400, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 8523, + "sendGcKb": 3, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120200, + "Frames": 601, + "NormalizedBandwidth": [ + 118.12657781605424, + 114.50610948758367, + 118.94550180895976, + 118.9924607347487, + 119.38084271301222, + 119.38084271301222 + ], "Framerate": [ 60, 60, @@ -242,24 +283,36 @@ 60 ], "Bandwidth": [ - 72.95561218261719, - 55.27622985839844, - 72.98111724853516, - 73.11192321777344, - 73.11192321777344, - 73.11192321777344 - ], - "DrainDuration": 9.438212112996553, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 72.95561340989091, - 55.27623078817734, - 72.98111847647248, - 73.1119244473851, - 73.1119244473851, - 73.1119244473851 - ] + 118.12657165527344, + 114.506103515625, + 118.94549560546875, + 118.9924545288086, + 119.3808364868164, + 119.3808364868164 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 201463, + "listenerCallGcSamples": 120200, + "packetDecodeGcSamples": 120200, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -7680, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 122003, + "receiveDecodeGcKb": 2 + }, + "Recieve": 120200 } }, "Booleans": { @@ -273,115 +326,149 @@ 60 ], "Bandwidth": [ - 2.261234044265747, - 1.898376226425171, - 2.274221181869507, - 2.2882111072540283, - 2.2882111072540283, - 2.2882111072540283 - ], - "DrainDuration": 3.664112124001258, - "Sent": 120000, + 2.5280051231384279, + 2.41890287399292, + 2.5903611183166506, + 2.6852736473083498, + 4.595119476318359, + 4.595119476318359 + ], + "DrainDuration": 3.7509580519981684, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.2612340823055977, - 1.8983762583597402, - 2.274221220131495, - 2.2882111457474474, - 2.2882111457474474, - 2.2882111457474474 + 2.528005254984169, + 2.4189030001485358, + 2.5903612534145106, + 2.6852737873562839, + 4.5951197159725158, + 4.5951197159725158 ] }, "bridgenet2": { "Framerate": [ - 49, - 31, - 49, - 49, - 49, - 49 + 54, + 52, + 55, + 56, + 56, + 56 ], "Bandwidth": [ - 19515.61328125, - 7813.1123046875, - 19515.61328125, - 19515.61328125, - 19515.61328125, - 19515.61328125 - ], - "DrainDuration": 23.951335112002133, - "Sent": 73400, - "Recieve": 73400, + 21597.015625, + 15018.9638671875, + 21933.330078125, + 22058.376953125, + 22058.376953125, + 22058.376953125 + ], + "DrainDuration": 23.37892199799535, + "Recieve": 92800, + "Sent": 92800, + "Frames": 464, "NormalizedBandwidth": [ - 25048.455246604215, - 10019.375253683884, - 25048.455246604215, - 25048.455246604215, - 25048.455246604215, - 25048.455246604215 + 24020.960932802256, + 17401.78102035091, + 24139.794061205463, + 24240.76741273898, + 24240.76741273898, + 24240.76741273898 ] }, - "packet": { + "netray_compile": { "Framerate": [ - 48, - 45, - 48, - 48, - 48, - 48 + 60, + 60, + 60, + 60, + 60, + 60 + ], + "Bandwidth": [ + 10.267995834350586, + 7.645515441894531, + 10.327715873718262, + 10.333728790283204, + 10.337851524353028, + 10.337851524353028 + ], + "DrainDuration": 5.733045668006525, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, + "NormalizedBandwidth": [ + 10.2679963698683, + 7.645515840639234, + 10.327716412350619, + 10.333729329229158, + 10.337852063514, + 10.337852063514 + ] + }, + "bytenet": { + "Framerate": [ + 60, + 60, + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 53381.515625, - 31145.32421875, - 53381.515625, - 53381.515625, - 53381.515625, - 53381.515625 - ], - "DrainDuration": 10.884112110998103, - "Sent": 90000, - "Recieve": 90000, + 19.038877487182618, + 14.346100807189942, + 19.122026443481447, + 19.126558303833009, + 19.186111450195314, + 19.186111450195314 + ], + "DrainDuration": 6.749614586995449, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 66649.3732890472, - 38885.34023770337, - 66649.3732890472, - 66649.3732890472, - 66649.3732890472, - 66649.3732890472 + 19.038878480137457, + 14.346101555397404, + 19.122027458581614, + 19.126559390425734, + 19.186112486565919, + 19.186112486565919 ] }, "roblox": { "Framerate": [ 48, - 44, - 48, - 48, - 48, - 48 + 43, + 49, + 51, + 51, + 51 ], "Bandwidth": [ - 53381.515625, - 31145.32421875, - 53381.515625, - 53381.515625, - 53381.515625, - 53381.515625 - ], - "DrainDuration": 10.884112110998103, - "Sent": 90000, - "Recieve": 90000, + 52079.02734375, + 42960.4296875, + 54077.0625, + 56808.8671875, + 56808.8671875, + 56808.8671875 + ], + "DrainDuration": 10.855842433011276, + "Recieve": 93600, + "Sent": 93600, + "Frames": 468, "NormalizedBandwidth": [ - 66649.3732890472, - 42470.89886363636, - 66649.3732890472, - 66649.3732890472, - 66649.3732890472, - 66649.3732890472 + 63487.24735938568, + 53924.29198465775, + 73126.31130630178, + 73879.55508312948, + 73879.55508312948, + 73879.55508312948 ] }, - "satset": { + "blink": { "Framerate": [ - 61, + 60, 60, 61, 61, @@ -389,55 +476,27 @@ 61 ], "Bandwidth": [ - 10.376221656799316, - 8.653422355651855, - 10.384211540222168, - 10.384211540222168, - 10.384211540222168, - 10.384211540222168 - ], - "DrainDuration": 5.764112124001258, - "Sent": 120000, + 29.376415252685548, + 22.09522819519043, + 29.51577377319336, + 29.67349624633789, + 29.67349624633789, + 29.67349624633789 + ], + "DrainDuration": 7.484228474000702, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 10.376221831146704, - 8.653422501061803, - 10.384211714774648, - 10.384211714774648, - 10.384211714774648, - 10.384211714774648 - ] - }, - "bytenet": { - "Framerate": [ - 57, - 34, - 57, - 57, - 57, - 57 - ], - "Bandwidth": [ - 16.26411247253418, - 9.758411407470703, - 16.273411750793457, - 16.273411750793457, - 16.273411750793457, - 16.273411750793457 - ], - "DrainDuration": 6.484112124001258, - "Sent": 89800, - "Recieve": 89800, - "NormalizedBandwidth": [ - 19.418858739958342, - 17.220726715456223, - 19.429961605333553, - 19.429961605333553, - 19.429961605333553, - 19.429961605333553 + 29.376416784784995, + 22.09522934754638, + 29.51577531256092, + 29.67349779393132, + 29.67349779393132, + 29.67349779393132 ] }, - "netray": { + "zap": { "Framerate": [ 60, 60, @@ -447,112 +506,160 @@ 60 ], "Bandwidth": [ - 10.264211654663086, - 8.653422355651855, - 10.274211883544922, - 10.274211883544922, - 10.274211883544922, - 10.274211883544922 - ], - "DrainDuration": 6.234112124001258, - "Sent": 120000, + 29.3526554107666, + 21.838335037231447, + 29.515899658203126, + 29.562232971191408, + 29.655065536499025, + 29.655065536499025 + ], + "DrainDuration": 7.80146282298665, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 10.264211827050307, - 8.653422501061803, - 10.274212056002778, - 10.274212056002778, - 10.274212056002778, - 10.274212056002778 + 29.352656941626877, + 21.838336176189374, + 29.51590119757725, + 29.562234512982003, + 29.655067083131216, + 29.655067083131216 ] }, - "zap": { + "packet": { "Framerate": [ + 57, + 48, 60, - 51, - 60, - 60, - 60, - 60 + 61, + 61, + 61 ], "Bandwidth": [ - 28.52222442626953, - 18.653422355651855, - 28.52222442626953, - 28.52222442626953, - 28.52222442626953, - 28.52222442626953 - ], - "DrainDuration": 7.814112124001258, - "Sent": 94600, - "Recieve": 94600, + 25.295551300048829, + 14.827459335327149, + 26.949735641479493, + 27.766550064086915, + 27.766550064086915, + 27.766550064086915 + ], + "DrainDuration": 6.576663271000143, + "Recieve": 93200, + "Sent": 93200, + "Frames": 466, "NormalizedBandwidth": [ - 28.52222490130639, - 21.945203300890635, - 28.52222490130639, - 28.52222490130639, - 28.52222490130639, - 28.52222490130639 + 26.89403543481396, + 18.766004243150346, + 27.453480371245488, + 27.88034919787034, + 27.88034919787034, + 27.88034919787034 ] }, - "blink": { + "satset": { + "DrainDuration": 5.46710864501074, + "DebugStats": { + "reliableCommitBytes": 15627202, + "commitGcKb": 26, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 601, + "reliableCommits": 601, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120200, + "sendGcSamples": 240400, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 9386, + "sendGcKb": 2, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120200, + "Frames": 601, + "NormalizedBandwidth": [ + 10.427624292622255, + 8.05251960441066, + 10.48030444912483, + 10.487274716875846, + 10.487274716875846, + 10.487274716875846 + ], "Framerate": [ 60, 60, - 60, - 60, - 60, - 60 + 61, + 61, + 61, + 61 ], "Bandwidth": [ - 29.355115356445312, - 18.653422355651855, - 29.355115356445312, - 29.355115356445312, - 29.355115356445312, - 29.355115356445312 - ], - "DrainDuration": 7.464112124001258, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 29.355115845422892, - 18.653422501061803, - 29.355115845422892, - 29.355115845422892, - 29.355115845422892, - 29.355115845422892 - ] + 10.427623748779297, + 8.085657119750977, + 10.474220275878907, + 10.487274169921875, + 10.487274169921875, + 10.487274169921875 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 828976, + "listenerCallGcSamples": 120200, + "packetDecodeGcSamples": 120200, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -740810, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 120801, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120200 } }, "Mixed": { "warp": { "Framerate": [ 60, - 48, + 60, 60, 60, 60, 60 ], "Bandwidth": [ - 2.3551111221313477, - 1.8211111111111111, - 2.4111211332702637, - 2.4111211332702637, - 2.4111211332702637, - 2.4111211332702637 - ], - "DrainDuration": 3.944111212999464, - "Sent": 80200, - "Recieve": 80200, + 2.367743730545044, + 2.001237630844116, + 2.4215505123138429, + 2.4323205947875978, + 2.5007174015045168, + 2.5007174015045168 + ], + "DrainDuration": 3.7973680819995936, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.355111161427509, - 2.2763889154032014, - 2.4111211734994273, - 2.4111211734994273, - 2.4111211734994273, - 2.4111211734994273 + 2.3677438540325026, + 2.001237735216792, + 2.4215506386075438, + 2.432320721643002, + 2.5007175319270926, + 2.5007175319270926 ] }, "bridgenet2": { @@ -565,52 +672,84 @@ 60 ], "Bandwidth": [ - 1635.43310546875, - 1355.211111111111, - 1648.111111111111, - 1648.111111111111, - 1648.111111111111, - 1648.111111111111 - ], - "DrainDuration": 17.531211112998412, - "Sent": 120000, + 1674.851806640625, + 1321.96240234375, + 1680.8363037109376, + 1685.98828125, + 1688.636962890625, + 1688.636962890625 + ], + "DrainDuration": 17.466414558002727, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 1635.4331327318532, - 1355.2111336952873, - 1648.1111385848202, - 1648.1111385848202, - 1648.1111385848202, - 1648.1111385848202 + 1674.8518939909537, + 1321.962471289462, + 1680.836391373382, + 1685.988369181141, + 1688.6370509599056, + 1688.6370509599056 ] }, - "packet": { + "netray_compile": { "Framerate": [ 60, + 56, 60, + 61, + 61, + 61 + ], + "Bandwidth": [ + 4.971836090087891, + 3.9490153789520265, + 5.230027198791504, + 5.288918972015381, + 5.288918972015381, + 5.288918972015381 + ], + "DrainDuration": 4.449728205989231, + "Recieve": 104600, + "Sent": 104600, + "Frames": 523, + "NormalizedBandwidth": [ + 4.99255233186328, + 4.026360952269961, + 5.251819250254751, + 5.288919247854, + 5.288919247854, + 5.288919247854 + ] + }, + "bytenet": { + "Framerate": [ + 61, 60, - 60, - 60, - 60 + 61, + 61, + 61, + 61 ], "Bandwidth": [ - 72.12211608886719, - 54.12222222222222, - 72.76666666666667, - 72.76666666666667, - 72.76666666666667, - 72.76666666666667 - ], - "DrainDuration": 9.614112110999121, - "Sent": 120000, + 4.8627705574035648, + 3.7894835472106935, + 4.907449722290039, + 4.907667636871338, + 4.907667636871338, + 4.907667636871338 + ], + "DrainDuration": 4.734052910003811, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 72.12211729119614, - 54.12222312440366, - 72.76666787948293, - 72.76666787948293, - 72.76666787948293, - 72.76666787948293 + 4.862770811016812, + 3.7894837448476617, + 4.907449978233487, + 4.907667892826151, + 4.907667892826151, + 4.907667892826151 ] }, "roblox": { @@ -623,26 +762,27 @@ 60 ], "Bandwidth": [ - 3948.111328125, - 2355.111111111111, - 3948.111328125, - 3948.111328125, - 3948.111328125, - 3948.111328125 - ], - "DrainDuration": 9.638211112999464, - "Sent": 120000, + 3645.95849609375, + 3551.18408203125, + 3707.31884765625, + 3745.72607421875, + 3793.969970703125, + 3793.969970703125 + ], + "DrainDuration": 9.315273878994049, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 3948.1113939396263, - 2355.111150371587, - 3948.1113939396263, - 3948.1113939396263, - 3948.1113939396263, - 3948.1113939396263 + 3645.9586862453036, + 3551.1842672399327, + 3707.319041007995, + 3745.726269573588, + 3793.9701685740785, + 3793.9701685740785 ] }, - "satset": { + "blink": { "Framerate": [ 60, 60, @@ -652,55 +792,57 @@ 60 ], "Bandwidth": [ - 4.266666889190674, - 3.211111111111111, - 4.311111111111111, - 4.311111111111111, - 4.311111111111111, - 4.311111111111111 - ], - "DrainDuration": 4.704112110998514, - "Sent": 120000, + 5.01809549331665, + 3.8224503993988039, + 5.083568096160889, + 5.11272668838501, + 5.136458396911621, + 5.136458396911621 + ], + "DrainDuration": 4.382963971002027, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 4.266666960317855, - 3.2111111646394303, - 4.31111118301138, - 4.31111118301138, - 4.31111118301138, - 4.31111118301138 + 5.018095755030725, + 3.822450598755127, + 5.083568361289625, + 5.112726955034486, + 5.136458664798802, + 5.136458664798802 ] }, - "bytenet": { + "zap": { "Framerate": [ 60, - 59, + 60, 60, 60, 60, 60 ], "Bandwidth": [ - 4.855555534362793, - 3.311111111111111, - 4.911111111111111, - 4.911111111111111, - 4.911111111111111, - 4.911111111111111 - ], - "DrainDuration": 4.784112111002353, - "Sent": 119800, - "Recieve": 119800, + 5.063509941101074, + 3.9991307258605959, + 5.120892524719238, + 5.168327808380127, + 5.198076248168945, + 5.198076248168945 + ], + "DrainDuration": 4.533552018008777, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 4.855555615307399, - 3.36723170427188, - 4.911111192972963, - 4.911111192972963, - 4.911111192972963, - 4.911111192972963 + 5.063510205183697, + 3.9991309344315164, + 5.120892791794596, + 5.168328077929427, + 5.198076519269748, + 5.198076519269748 ] }, - "netray": { + "packet": { "Framerate": [ 60, 60, @@ -710,204 +852,195 @@ 60 ], "Bandwidth": [ - 4.955555438995361, - 3.411111111111111, - 5.011111111111111, - 5.011111111111111, - 5.011111111111111, - 5.011111111111111 - ], - "DrainDuration": 4.744112112999464, - "Sent": 120000, - "Recieve": 120000, + 4.789048671722412, + 3.8322553634643556, + 4.831278324127197, + 4.832939624786377, + 4.894881725311279, + 4.894881725311279 + ], + "DrainDuration": 4.382298404001631, + "Recieve": 120200, + "Sent": 120200, + "Frames": 601, "NormalizedBandwidth": [ - 4.955555521606554, - 3.4111111679720336, - 5.01111119462704, - 5.01111119462704, - 5.01111119462704, - 5.01111119462704 + 4.789048921490764, + 3.8322555633320478, + 4.831278576097997, + 4.83293987684382, + 4.894881980599255, + 4.894881980599255 ] }, - "zap": { - "Framerate": [ - 61, - 60, - 61, - 61, - 61, - 61 - ], - "Bandwidth": [ - 4.955555438995361, - 3.411111111111111, - 5.011111111111111, - 5.011111111111111, - 5.011111111111111, - 5.011111111111111 - ], - "DrainDuration": 4.694112111002353, - "Sent": 120000, - "Recieve": 120000, + "satset": { + "DrainDuration": 4.114856778003741, + "DebugStats": { + "reliableCommitBytes": 3847602, + "commitGcKb": 6, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 601, + "reliableCommits": 601, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120200, + "sendGcSamples": 240400, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 0, + "sendGcKb": 1, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120200, + "Frames": 601, "NormalizedBandwidth": [ - 4.955555521606554, - 3.4111111679720336, - 5.01111119462704, - 5.01111119462704, - 5.01111119462704, - 5.01111119462704 - ] - }, - "blink": { + 4.28698275989948, + 3.5555240578105087, + 4.321188675227159, + 4.422958127861509, + 4.476990933261327, + 4.476990933261327 + ], "Framerate": [ - 61, - 54, - 61, - 61, + 60, + 60, + 60, + 60, 61, 61 ], "Bandwidth": [ - 4.855555534362793, - 3.311111111111111, - 4.911111111111111, - 4.911111111111111, - 4.911111111111111, - 4.911111111111111 - ], - "DrainDuration": 4.644112110999121, - "Sent": 98200, - "Recieve": 98200, - "NormalizedBandwidth": [ - 4.855555615307399, - 3.6790123761763784, - 4.911111192972963, - 4.911111192972963, - 4.911111192972963, - 4.911111192972963 - ] + 4.276167392730713, + 3.5555238723754885, + 4.321188449859619, + 4.422957897186279, + 4.476990699768066, + 4.476990699768066 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 34093, + "listenerCallGcSamples": 120200, + "packetDecodeGcSamples": 120200, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -876, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 120801, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120200 } }, "Entities": { "warp": { "Framerate": [ - 49, - 38, - 49, - 49, - 49, - 49 + 53, + 50, + 55, + 55, + 55, + 55 ], "Bandwidth": [ - 7.511111259460449, - 4.211111111111111, - 7.511111111111111, - 7.511111111111111, - 7.511111111111111, - 7.511111111111111 - ], - "DrainDuration": 6.344112112999464, - "Sent": 65200, - "Recieve": 65200, + 11.196282386779786, + 7.589590549468994, + 11.764313697814942, + 11.93932056427002, + 11.93932056427002, + 11.93932056427002 + ], + "DrainDuration": 5.864050429008785, + "Recieve": 104800, + "Sent": 104800, + "Frames": 524, "NormalizedBandwidth": [ - 10.219165275829671, - 6.649122858485743, - 10.219165073144167, - 10.219165073144167, - 10.219165073144167, - 10.219165073144167 + 12.72785005758546, + 9.221353053669024, + 13.350331957596519, + 13.389117109362792, + 13.389117109362792, + 13.389117109362792 ] }, "bridgenet2": { "Framerate": [ + 17, 16, - 15, - 16, - 16, - 16, - 16 + 19, + 20, + 20, + 20 ], "Bandwidth": [ - 9715.43359375, - 6355.211111111111, - 9748.111111111111, - 9748.111111111111, - 9748.111111111111, - 9748.111111111111 - ], - "DrainDuration": 29.181211112998412, - "Sent": 11200, - "Recieve": 11200, + 21929.3984375, + 14871.76171875, + 27527.98828125, + 29490.4296875, + 29490.4296875, + 29490.4296875 + ], + "DrainDuration": 27.5115366109967, + "Recieve": 26800, + "Sent": 26800, + "Frames": 134, "NormalizedBandwidth": [ - 38861.73523412351, - 25420.84473852085, - 38992.44523312351, - 38992.44523312351, - 38992.44523312351, - 38992.44523312351 + 81590.26562036792, + 45916.56730386879, + 92400.67540511597, + 107553.33585984344, + 107553.33585984344, + 107553.33585984344 ] }, - "packet": { + "netray_compile": { "Framerate": [ - 18, - 18, - 18, - 18, - 18, - 18 - ], - "Bandwidth": [ - 211712.115625, - 154122.22222222222, - 211766.66666666667, - 211766.66666666667, - 211766.66666666667, - 211766.66666666667 - ], - "DrainDuration": 14.764112110999121, - "Sent": 35400, - "Recieve": 35400, - "NormalizedBandwidth": [ - 717621.1856214532, - 513740.7513414073, - 717805.8656214532, - 717805.8656214532, - 717805.8656214532, - 717805.8656214532 - ] - }, - "roblox": { - "Framerate": [ - 18, - 18, - 18, - 18, - 18, - 18 + 60, + 59, + 61, + 61, + 61, + 61 ], "Bandwidth": [ - 211712.115625, - 154122.22222222222, - 211766.66666666667, - 211766.66666666667, - 211766.66666666667, - 211766.66666666667 - ], - "DrainDuration": 14.764112110999121, - "Sent": 35400, - "Recieve": 35400, + 38.92438888549805, + 28.630207061767579, + 39.00762939453125, + 39.03105926513672, + 39.03105926513672, + 39.03105926513672 + ], + "DrainDuration": 8.334220327000367, + "Recieve": 119800, + "Sent": 119800, + "Frames": 599, "NormalizedBandwidth": [ - 717621.1856214532, - 513740.7513414073, - 717805.8656214532, - 717805.8656214532, - 717805.8656214532, - 717805.8656214532 + 38.84776410488235, + 28.63020860827715, + 39.03106130076509, + 39.14743247525482, + 39.14743247525482, + 39.14743247525482 ] }, - "satset": { + "bytenet": { "Framerate": [ - 61, + 60, 60, 61, 61, @@ -915,113 +1048,180 @@ 61 ], "Bandwidth": [ - 119.22211608886719, - 84.12222222222222, - 119.26666666666667, - 119.26666666666667, - 119.26666666666667, - 119.26666666666667 - ], - "DrainDuration": 9.194112110999121, - "Sent": 120000, - "Recieve": 120000, + 39.03129577636719, + 28.422805786132814, + 39.16684341430664, + 39.24283218383789, + 39.24283218383789, + 39.24283218383789 + ], + "DrainDuration": 8.278367886989145, + "Recieve": 119800, + "Sent": 119800, + "Frames": 599, "NormalizedBandwidth": [ - 119.22211804364446, - 84.12222362035987, - 119.26666862534591, - 119.26666862534591, - 119.26666862534591, - 119.26666862534591 + 38.88097623292613, + 28.422807850855265, + 39.16684633246388, + 39.24283488837032, + 39.24283488837032, + 39.24283488837032 ] }, - "bytenet": { + "roblox": { "Framerate": [ - 52, - 47, - 52, - 52, - 52, - 52 + 19, + 18, + 19, + 20, + 20, + 20 ], "Bandwidth": [ - 33.61212768554688, - 22.32768249511719, - 33.93282318115234, - 33.9463119506836, - 33.9463119506836, - 33.9463119506836 - ], - "DrainDuration": 7.698212111000466, - "Sent": 85200, - "Recieve": 85200, + 200387.59375, + 169907.078125, + 216616.25, + 217491.9375, + 217491.9375, + 217491.9375 + ], + "DrainDuration": 14.227369316999102, + "Recieve": 36000, + "Sent": 36000, + "Frames": 180, "NormalizedBandwidth": [ - 39.9872413856112, - 31.06642131445657, - 40.01224531238947, - 40.04631408192074, - 40.04631408192074, - 40.04631408192074 + 658854.2108462813, + 554433.6622652277, + 731014.6159614716, + 743114.1216436246, + 743114.1216436246, + 743114.1216436246 ] }, - "netray": { + "blink": { "Framerate": [ 60, - 59, + 49, 60, 60, 60, 60 ], "Bandwidth": [ - 38.86811218261719, - 25.13937759399414, - 39.0276138305664, - 39.07982940673828, - 39.07982940673828, - 39.07982940673828 - ], - "DrainDuration": 8.318211512999013, - "Sent": 119800, - "Recieve": 119800, + 36.03293228149414, + 11.830374717712403, + 38.78770065307617, + 38.87779998779297, + 38.87779998779297, + 38.87779998779297 + ], + "DrainDuration": 8.450334709996242, + "Recieve": 80800, + "Sent": 80800, + "Frames": 404, "NormalizedBandwidth": [ - 39.0142385458312, - 25.565469502366914, - 39.0276159628868, - 39.07983152636222, - 39.07983152636222, - 39.07983152636222 + 36.032934160758, + 14.486173852259676, + 38.7877026760124, + 38.877802015428247, + 38.877802015428247, + 38.877802015428247 ] }, "zap": { "Framerate": [ - 60, - 46, - 60, 60, 60, - 60 + 61, + 61, + 61, + 61 ], "Bandwidth": [ - 38.68212280273438, - 25.27622985839844, - 38.81192321777344, - 38.81192321777344, - 38.81192321777344, - 38.81192321777344 - ], - "DrainDuration": 8.428212112997135, - "Sent": 111600, - "Recieve": 111600, + 38.920501708984378, + 28.92695426940918, + 38.9479866027832, + 38.94910430908203, + 38.94910430908203, + 38.94910430908203 + ], + "DrainDuration": 8.28381725399231, + "Recieve": 119800, + "Sent": 119800, + "Frames": 599, "NormalizedBandwidth": [ - 38.78212403213007, - 40.40422204780517, - 38.8119244473851, - 38.8119244473851, - 38.8119244473851, - 38.8119244473851 + 38.87452519030617, + 28.926955939709364, + 38.94910634043612, + 39.09136793022222, + 39.09136793022222, + 39.09136793022222 ] }, - "blink": { + "packet": { + "Framerate": [ + 50, + 49, + 51, + 52, + 52, + 52 + ], + "Bandwidth": [ + 31.260360717773439, + 21.640050888061525, + 32.47395324707031, + 33.11435317993164, + 33.11435317993164, + 33.11435317993164 + ], + "DrainDuration": 8.382789288007189, + "Recieve": 99400, + "Sent": 99400, + "Frames": 497, + "NormalizedBandwidth": [ + 38.2088710109303, + 25.458884749214115, + 38.91596125487791, + 39.131115721712578, + 39.131115721712578, + 39.131115721712578 + ] + }, + "satset": { + "DrainDuration": 9.23560994998843, + "DebugStats": { + "reliableCommitBytes": 72724606, + "commitGcKb": 2, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 1803, + "reliableCommits": 1803, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120200, + "sendGcSamples": 240400, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 7543, + "sendGcKb": 1, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120200, + "Frames": 601, + "NormalizedBandwidth": [ + 117.52604525299575, + 113.38900585266203, + 118.25751349182838, + 118.65625629891292, + 119.3990540787081, + 119.3990540787081 + ], "Framerate": [ 60, 60, @@ -1031,144 +1231,100 @@ 60 ], "Bandwidth": [ - 38.95561218261719, - 25.27622985839844, - 38.98111724853516, - 39.01192321777344, - 39.01192321777344, - 39.01192321777344 - ], - "DrainDuration": 8.318212112996553, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 38.95561340989091, - 25.27623078817734, - 38.98111847647248, - 39.0119244473851, - 39.0119244473851, - 39.0119244473851 - ] + 117.52603912353516, + 113.38899993896485, + 118.25750732421875, + 118.65625, + 119.3990478515625, + 119.3990478515625 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 37284, + "listenerCallGcSamples": 120200, + "packetDecodeGcSamples": 120200, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -3342, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 122003, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120200 } }, "Strings": { "warp": { "Framerate": [ - 61, 60, - 61, + 57, + 60, 61, 61, 61 ], "Bandwidth": [ - 16.611111221313477, - 10.211111111111111, - 16.611121133270263, - 16.611121133270263, - 16.611121133270263, - 16.611121133270263 - ], - "DrainDuration": 6.384111212999464, - "Sent": 120000, - "Recieve": 120000, + 3.339949369430542, + 2.410991907119751, + 4.599241256713867, + 4.635377883911133, + 4.635377883911133, + 4.635377883911133 + ], + "DrainDuration": 4.316263066997635, + "Recieve": 117400, + "Sent": 117400, + "Frames": 587, "NormalizedBandwidth": [ - 16.61111161427509, - 10.211111111111111, - 16.611121173499427, - 16.611121173499427, - 16.611121173499427, - 16.611121173499427 + 3.345189030590072, + 2.559035405665311, + 4.84130684301723, + 4.879345404525255, + 4.879345404525255, + 4.879345404525255 ] }, "bridgenet2": { "Framerate": [ 60, - 60, - 60, - 60, - 60, - 60 - ], - "Bandwidth": [ - 27435.43310546875, - 18355.21111111111, - 27448.11111111111, - 27448.11111111111, - 27448.11111111111, - 27448.11111111111 - ], - "DrainDuration": 24.131211112998412, - "Sent": 119800, - "Recieve": 119800, - "NormalizedBandwidth": [ - 27435.433132731853, - 18355.211133695287, - 27448.11113858482, - 27448.11113858482, - 27448.11113858482, - 27448.11113858482 - ] - }, - "packet": { - "Framerate": [ - 60, - 55, - 60, - 60, - 60, - 60 - ], - "Bandwidth": [ - 160351.515625, - 123145.32421875, - 160351.515625, - 160351.515625, - 160351.515625, - 160351.515625 - ], - "DrainDuration": 12.344112110998103, - "Sent": 118600, - "Recieve": 118600, - "NormalizedBandwidth": [ - 160351.515625, - 142345.32421875, - 160351.515625, - 160351.515625, - 160351.515625, - 160351.515625 - ] - }, - "roblox": { - "Framerate": [ - 60, - 55, - 60, - 60, - 60, - 60 + 59, + 61, + 61, + 61, + 61 ], "Bandwidth": [ - 160351.515625, - 123145.32421875, - 160351.515625, - 160351.515625, - 160351.515625, - 160351.515625 - ], - "DrainDuration": 12.344112110998103, - "Sent": 118600, - "Recieve": 118600, + 27369.91796875, + 21649.95703125, + 27724.568359375, + 27839.669921875, + 27839.669921875, + 27839.669921875 + ], + "DrainDuration": 24.09962713799905, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 160351.515625, - 142345.32421875, - 160351.515625, - 160351.515625, - 160351.515625, - 160351.515625 + 27383.283318518294, + 21561.228833576643, + 27610.94453193514, + 27690.14639641275, + 27690.14639641275, + 27690.14639641275 ] }, - "satset": { + "netray_compile": { "Framerate": [ 60, 57, @@ -1178,23 +1334,24 @@ 60 ], "Bandwidth": [ - 948.9176330566406, - 948.9176330566406, - 948.9176330566406, - 948.9176330566406, - 948.9176330566406, - 948.9176330566406 - ], - "DrainDuration": 10.315111124999312, - "Sent": 117200, - "Recieve": 117200, + 96.01789855957031, + 72.67913818359375, + 96.50682830810547, + 96.6336898803711, + 96.6336898803711, + 96.6336898803711 + ], + "DrainDuration": 10.349840333990869, + "Recieve": 91600, + "Sent": 91600, + "Frames": 458, "NormalizedBandwidth": [ - 948.9176330566406, - 998.9176330566406, - 948.9176330566406, - 948.9176330566406, - 948.9176330566406, - 948.9176330566406 + 96.01790356729396, + 72.67914197410619, + 96.50683334132879, + 101.71967886337974, + 101.71967886337974, + 101.71967886337974 ] }, "bytenet": { @@ -1214,9 +1371,10 @@ 0, 0 ], - "DrainDuration": 3.5402112290030347, - "Sent": 1400, - "Recieve": 1400, + "DrainDuration": 4.554712537996238, + "Recieve": 1600, + "Sent": 1600, + "Frames": 8, "NormalizedBandwidth": [ 0, 0, @@ -1226,96 +1384,160 @@ 0 ] }, - "netray": { + "roblox": { "Framerate": [ 60, 60, + 61, + 61, + 61, + 61 + ], + "Bandwidth": [ + 158676.125, + 62701.5625, + 185281.1875, + 189184.796875, + 189184.796875, + 189184.796875 + ], + "DrainDuration": 11.418339181996999, + "Recieve": 119800, + "Sent": 119800, + "Frames": 599, + "NormalizedBandwidth": [ + 158214.249038932, + 62701.5658275794, + 185281.19750828006, + 189973.0770341348, + 189973.0770341348, + 189973.0770341348 + ] + }, + "blink": { + "Framerate": [ 60, 60, - 60, - 60 + 61, + 61, + 61, + 61 ], "Bandwidth": [ - 96.71212768554688, - 52.32768249511719, - 96.93282318115234, - 96.9463119506836, - 96.9463119506836, - 96.9463119506836 - ], - "DrainDuration": 10.298212111000466, - "Sent": 120000, - "Recieve": 120000, + 99.90201568603516, + 70.48593139648438, + 100.270751953125, + 100.72390747070313, + 100.72390747070313, + 100.72390747070313 + ], + "DrainDuration": 10.348186507995706, + "Recieve": 119800, + "Sent": 119800, + "Frames": 599, "NormalizedBandwidth": [ - 96.8122393856112, - 52.32768346764585, - 96.93282531238947, - 96.94631408192074, - 96.94631408192074, - 96.94631408192074 + 99.8598115024206, + 71.36700929384239, + 100.33517218108904, + 100.5040093556488, + 100.5040093556488, + 100.5040093556488 ] }, "zap": { "Framerate": [ 60, - 52, + 60, 60, 60, 60, 60 ], "Bandwidth": [ - 100.41212768554688, - 82.32768249511719, - 100.43282318115234, - 100.4463119506836, - 100.4463119506836, - 100.4463119506836 - ], - "DrainDuration": 10.158212111000466, - "Sent": 88600, - "Recieve": 88600, + 101.22911071777344, + 76.48998260498047, + 101.49319458007813, + 101.49600219726563, + 101.52214050292969, + 101.52214050292969 + ], + "DrainDuration": 10.35065956399194, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 100.4122393856112, - 94.32768346764585, - 100.43282531238947, - 100.44631408192074, - 100.44631408192074, - 100.44631408192074 + 101.22911599728298, + 76.48998659424393, + 101.49319987336071, + 101.49600749069464, + 101.52214579772192, + 101.52214579772192 ] }, - "blink": { + "packet": { "Framerate": [ 60, - 53, + 58, 60, 60, 60, 60 ], "Bandwidth": [ - 100.21212768554688, - 82.32768249511719, - 100.23282318115234, - 100.2463119506836, - 100.2463119506836, - 100.2463119506836 - ], - "DrainDuration": 11.798212111000466, - "Sent": 98800, - "Recieve": 98800, + 95.73635864257813, + 73.33147430419922, + 95.94190979003906, + 96.01290893554688, + 96.23210906982422, + 96.23210906982422 + ], + "DrainDuration": 10.348626498001977, + "Recieve": 119800, + "Sent": 119800, + "Frames": 599, "NormalizedBandwidth": [ - 100.2122393856112, - 113.32768346764585, - 100.23282531238947, - 100.24631408192074, - 100.24631408192074, - 100.24631408192074 + 95.75932811435507, + 73.33147812873364, + 96.01291394301029, + 96.23211408871981, + 96.87157463597005, + 96.87157463597005 ] - } - }, - "SingleValue": { - "warp": { + }, + "satset": { + "DrainDuration": 10.300590774000739, + "DebugStats": { + "reliableCommitBytes": 260723416, + "commitGcKb": 824, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 4808, + "reliableCommits": 4808, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120200, + "sendGcSamples": 240400, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 9132, + "sendGcKb": 1, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120200, + "Frames": 601, + "NormalizedBandwidth": [ + 899.6280376419122, + 849.0741409623524, + 907.7277084744992, + 922.8502068217927, + 958.1896251687931, + 958.1896251687931 + ], "Framerate": [ 60, 60, @@ -1325,23 +1547,67 @@ 60 ], "Bandwidth": [ - 2.261234044265747, - 1.898376226425171, - 2.274221181869507, - 2.2882111072540283, - 2.2882111072540283, - 2.2882111072540283 - ], - "DrainDuration": 3.764112124001258, - "Sent": 120000, + 899.6279907226563, + 849.0740966796875, + 907.7276611328125, + 922.8501586914063, + 958.1895751953125, + 958.1895751953125 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 104335, + "listenerCallGcSamples": 120200, + "packetDecodeGcSamples": 120200, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": 2, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 125008, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120200 + } + }, + "SingleValue": { + "warp": { + "Framerate": [ + 60, + 60, + 61, + 61, + 61, + 61 + ], + "Bandwidth": [ + 1.801207184791565, + 1.2526928186416627, + 1.969154953956604, + 1.9788663387298585, + 1.9788663387298585, + 1.9788663387298585 + ], + "DrainDuration": 3.783751056995243, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.2612340823055977, - 1.8983762583597402, - 2.274221220131495, - 2.2882111457474474, - 2.2882111457474474, - 2.2882111457474474 + 1.80120727873184, + 1.2526928839746843, + 1.9691550566560379, + 1.9788664419357805, + 1.9788664419357805, + 1.9788664419357805 ] }, "bridgenet2": { @@ -1354,55 +1620,57 @@ 60 ], "Bandwidth": [ - 145.261234044265747, - 112.898376226425171, - 145.274221181869507, - 145.2882111072540283, - 145.2882111072540283, - 145.2882111072540283 - ], - "DrainDuration": 11.514112124001258, - "Sent": 120000, + 145.08642578125, + 114.35136413574219, + 145.39695739746095, + 145.45826721191407, + 145.72694396972657, + 145.72694396972657 + ], + "DrainDuration": 11.348725957999705, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 145.2612340823055977, - 112.8983762583597402, - 145.274221220131495, - 145.2882111457474474, - 145.2882111457474474, - 145.2882111457474474 + 145.08643334809677, + 114.35137009963057, + 145.39696498050319, + 145.45827479815388, + 145.72695156997896, + 145.72695156997896 ] }, - "packet": { + "netray_compile": { "Framerate": [ 60, - 60, + 58, 60, 60, 60, 60 ], "Bandwidth": [ - 232.71212768554688, - 185.32768249511719, - 232.73282318115234, - 232.7463119506836, - 232.7463119506836, - 232.7463119506836 - ], - "DrainDuration": 10.798212111000466, - "Sent": 120000, - "Recieve": 120000, + 2.390005350112915, + 1.8530726432800294, + 2.4323086738586427, + 2.463594436645508, + 2.4771370887756349, + 2.4771370887756349 + ], + "DrainDuration": 3.7498374999995578, + "Recieve": 119600, + "Sent": 119600, + "Frames": 598, "NormalizedBandwidth": [ - 232.7122393856112, - 185.32768346764585, - 232.73282531238947, - 232.74631408192074, - 232.74631408192074, - 232.74631408192074 + 2.3900054758743405, + 1.8530727399252989, + 2.4323088007134254, + 2.46359456513197, + 2.4771372179684016, + 2.4771372179684016 ] }, - "roblox": { + "bytenet": { "Framerate": [ 60, 60, @@ -1412,55 +1680,57 @@ 60 ], "Bandwidth": [ - 232.71212768554688, - 185.32768249511719, - 232.73282318115234, - 232.7463119506836, - 232.7463119506836, - 232.7463119506836 - ], - "DrainDuration": 10.798212111000466, - "Sent": 120000, + 2.309868097305298, + 1.8454840183258057, + 2.333796977996826, + 2.3554787635803224, + 2.3859333992004396, + 2.3859333992004396 + ], + "DrainDuration": 3.716698995005572, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 232.7122393856112, - 185.32768346764585, - 232.73282531238947, - 232.74631408192074, - 232.74631408192074, - 232.74631408192074 + 2.309868217774307, + 1.8454841145752977, + 2.3337970997138237, + 2.355478886428113, + 2.385933523636563, + 2.385933523636563 ] }, - "satset": { + "roblox": { "Framerate": [ - 61, + 60, 55, - 61, - 61, - 61, - 61 + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 2.41763305664062, - 2.21763305664062, - 2.41763305664062, - 2.41763305664062, - 2.41763305664062, - 2.41763305664062 - ], - "DrainDuration": 4.035111124999312, - "Sent": 103200, - "Recieve": 103200, + 231.52804565429688, + 228.96710205078126, + 232.88821411132813, + 232.92637634277345, + 232.92637634277345, + 232.92637634277345 + ], + "DrainDuration": 9.268308947008336, + "Recieve": 118600, + "Sent": 118600, + "Frames": 593, "NormalizedBandwidth": [ - 2.41763305664062, - 2.41763305664062, - 2.41763305664062, - 2.41763305664062, - 2.41763305664062, - 2.41763305664062 + 231.96397083809758, + 228.96711399234619, + 232.92638849083063, + 253.2994244071896, + 253.2994244071896, + 253.2994244071896 ] }, - "bytenet": { + "blink": { "Framerate": [ 61, 60, @@ -1470,84 +1740,120 @@ 61 ], "Bandwidth": [ - 2.21212768554688, - 1.32768249511719, - 2.23282318115234, - 2.2463119506836, - 2.2463119506836, - 2.2463119506836 - ], - "DrainDuration": 3.688212111000466, - "Sent": 120000, + 2.3300230503082277, + 1.87629234790802, + 2.3399951457977297, + 2.3567752838134767, + 2.3567752838134767, + 2.3567752838134767 + ], + "DrainDuration": 3.704949916995247, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.2122393856112, - 1.32768346764585, - 2.23282531238947, - 2.24631408192074, - 2.24631408192074, - 2.24631408192074 + 2.3285805009310147, + 1.8762924457642916, + 2.3399952678379867, + 2.356775406728886, + 2.356775406728886, + 2.356775406728886 ] }, - "netray": { + "zap": { "Framerate": [ - 61, 60, + 54, 61, 61, 61, 61 ], "Bandwidth": [ - 2.36811218261719, - 1.13937759399414, - 2.4276138305664, - 2.47982940673828, - 2.47982940673828, - 2.47982940673828 - ], - "DrainDuration": 3.738211512999013, - "Sent": 120000, - "Recieve": 120000, + 2.387258529663086, + 1.9198942184448243, + 2.4283559322357179, + 2.4355409145355226, + 2.4355409145355226, + 2.4355409145355226 + ], + "DrainDuration": 3.7995638299908025, + "Recieve": 118400, + "Sent": 118400, + "Frames": 592, "NormalizedBandwidth": [ - 2.3142385458312, - 1.13937861993202, - 2.4276159628868, - 2.47983152636222, - 2.47983152636222, - 2.47983152636222 + 2.377474808318438, + 1.9198943185751106, + 2.4355410415588798, + 2.4587105107511948, + 2.4587105107511948, + 2.4587105107511948 ] }, - "zap": { + "packet": { "Framerate": [ - 61, 60, - 61, - 61, - 61, - 61 + 60, + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 2.28212280273438, - 1.27622985839844, - 2.31192321777344, - 2.31192321777344, - 2.31192321777344, - 2.31192321777344 - ], - "DrainDuration": 3.738212112997135, - "Sent": 120000, - "Recieve": 120000, + 2.289534330368042, + 1.8420891761779786, + 2.332875967025757, + 2.3344199657440187, + 2.3497910499572756, + 2.3497910499572756 + ], + "DrainDuration": 3.7332146920089146, + "Recieve": 120200, + "Sent": 120200, + "Frames": 601, "NormalizedBandwidth": [ - 2.28212403213007, - 1.27623078817734, - 2.3119244473851, - 2.3119244473851, - 2.3119244473851, - 2.3119244473851 + 2.2895344497765626, + 1.8420892722504157, + 2.3328760886947199, + 2.3344200874935074, + 2.3497911725084288, + 2.3497911725084288 ] }, - "blink": { + "satset": { + "DrainDuration": 3.650029887998244, + "DebugStats": { + "reliableCommitBytes": 241602, + "commitGcKb": 0, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 601, + "reliableCommits": 601, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120200, + "sendGcSamples": 240400, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 9392, + "sendGcKb": 1, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120200, + "Frames": 601, + "NormalizedBandwidth": [ + 2.385438566640534, + 1.9411599456378737, + 2.437851317710864, + 2.4420696578509117, + 2.4612120481467505, + 2.4612120481467505 + ], "Framerate": [ 60, 60, @@ -1557,24 +1863,36 @@ 60 ], "Bandwidth": [ - 2.35561218261719, - 1.27622985839844, - 2.38111724853516, - 2.41192321777344, - 2.41192321777344, - 2.41192321777344 - ], - "DrainDuration": 3.718212112996553, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 2.35561340989091, - 1.27623078817734, - 2.38111847647248, - 2.4119244473851, - 2.4119244473851, - 2.4119244473851 - ] + 2.3854384422302248, + 1.9411598443984986, + 2.4378511905670168, + 2.4420695304870607, + 2.461211919784546, + 2.461211919784546 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 8374, + "listenerCallGcSamples": 120200, + "packetDecodeGcSamples": 120200, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -1196, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 120801, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120200 } } } \ No newline at end of file diff --git a/benchmark/latency-mode-result.json b/benchmark/latency-mode-result.json index eb2371a..210704b 100644 --- a/benchmark/latency-mode-result.json +++ b/benchmark/latency-mode-result.json @@ -3,120 +3,94 @@ "warp": { "Framerate": [ 60, - 57, - 60, - 60, - 60, - 60 - ], - "Bandwidth": [ - 2.764441728591919, - 1.4328962564468384, - 2.820237398147583, - 2.820838451385498, - 2.820838451385498, - 2.820838451385498 - ], - "DrainDuration": 3.782715762994485, - "Sent": 96600, - "Recieve": 96600, - "NormalizedBandwidth": [ - 2.7898992562986448, - 1.5145965598851226, - 2.8208385985036878, - 2.8773008914065905, - 2.8773008914065905, - 2.8773008914065905 - ] - }, - "bridgenet2": { - "Framerate": [ - 60, - 60, + 54, 60, 61, 61, 61 ], "Bandwidth": [ - 15659.8876953125, - 12391.0556640625, - 15722.8193359375, - 15762.7939453125, - 15762.7939453125, - 15762.7939453125 - ], - "DrainDuration": 22.01582332000544, - "Sent": 120000, - "Recieve": 120000, + 6.709656715393066, + 1.4099892377853394, + 7.120542049407959, + 8.696324348449707, + 8.696324348449707, + 8.696324348449707 + ], + "DrainDuration": 5.149838657001965, + "Recieve": 107800, + "Sent": 107800, + "Frames": 539, "NormalizedBandwidth": [ - 15659.888512039288, - 12391.056310306412, - 15711.897303814258, - 15722.820155946429, - 15722.820155946429, - 15722.820155946429 + 6.709657065328933, + 1.5797102491326936, + 7.120542420773166, + 8.696324801998366, + 8.696324801998366, + 8.696324801998366 ] }, - "netray_compile": { + "bridgenet2": { "Framerate": [ 60, + 59, 60, 60, - 61, - 61, - 61 + 60, + 60 ], "Bandwidth": [ - 72.5334701538086, - 54.906944274902347, - 72.76528930664063, - 72.81885528564453, - 72.81885528564453, - 72.81885528564453 - ], - "DrainDuration": 8.782914968003752, - "Sent": 119800, + 15613.310546875, + 11969.8486328125, + 15708.1064453125, + 15735.0009765625, + 15743.3115234375, + 15743.3115234375 + ], + "DrainDuration": 22.54962864400295, "Recieve": 119800, + "Sent": 119800, + "Frames": 599, "NormalizedBandwidth": [ - 72.53347393672385, - 54.90694713852264, - 72.79964317877873, - 73.06848178901908, - 73.06848178901908, - 73.06848178901908 + 15613.3113611726, + 11969.849257088754, + 15708.107264554092, + 15735.00179720675, + 15743.31234451518, + 15743.31234451518 ] }, - "bytenet": { + "netray_compile": { "Framerate": [ 60, + 52, 60, 61, 61, - 61, 61 ], "Bandwidth": [ - 72.9428939819336, - 55.87860107421875, - 73.03919219970703, - 73.2262191772461, - 73.2262191772461, - 73.2262191772461 - ], - "DrainDuration": 9.066092023000238, - "Sent": 120000, - "Recieve": 120000, + 71.82942962646485, + 25.026762008666993, + 73.36336517333985, + 73.59359741210938, + 73.59359741210938, + 73.59359741210938 + ], + "DrainDuration": 9.882727651012829, + "Recieve": 108600, + "Sent": 108600, + "Frames": 543, "NormalizedBandwidth": [ - 72.92611555853438, - 55.8786039885149, - 73.0334510746161, - 73.34352595835705, - 73.34352595835705, - 73.34352595835705 + 71.82943337266153, + 29.23799749849648, + 73.3633689995375, + 73.90024122125453, + 73.90024122125453, + 73.90024122125453 ] }, - "roblox": { + "zap": { "Framerate": [ 60, 60, @@ -126,84 +100,131 @@ 60 ], "Bandwidth": [ - 148732.1875, - 68882.234375, - 176976.265625, - 178919.484375, - 202897.765625, - 202897.765625 - ], - "DrainDuration": 9.332765226004995, - "Sent": 120000, + 72.78044128417969, + 54.00513458251953, + 73.04763793945313, + 73.0983657836914, + 73.4731216430664, + 73.4731216430664 + ], + "DrainDuration": 9.532480356007, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 148732.19525698806, - 68882.23796748847, - 176976.27485503153, - 178919.49370637828, - 202897.7762069431, - 202897.7762069431 + 72.7804450799755, + 54.005137399106789, + 73.04764174918432, + 73.09836959606827, + 73.47312547498831, + 73.47312547498831 ] }, - "satset": { + "roblox": { "Framerate": [ 60, 60, 60, - 60, - 60, - 60 + 61, + 61, + 61 ], "Bandwidth": [ - 38.990421295166019, - 29.033836364746095, - 39.19265365600586, - 39.27354431152344, - 39.325870513916019, - 39.325870513916019 - ], - "DrainDuration": 7.732752484997036, - "Sent": 120000, + 174809.515625, + 100636.25, + 209766.03125, + 214198.3125, + 214198.3125, + 214198.3125 + ], + "DrainDuration": 9.866745417006314, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 38.99042332867495, - 29.03383787897866, - 39.19265570006203, - 39.27354635979839, - 39.32587256491999, - 39.32587256491999 + 174809.5247420267, + 101055.57293192949, + 209766.04219015107, + 213320.4617871618, + 213320.4617871618, + 213320.4617871618 ] }, - "packet": { + "satset": { + "DrainDuration": 8.215696908999235, + "DebugStats": { + "reliableCommitBytes": 72601200, + "commitGcKb": 118, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 600, + "reliableCommits": 600, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 1, + "streamGrowthBytes": 131072, + "adapterGcSamples": 120000, + "sendGcSamples": 240001, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 8127, + "sendGcKb": 131, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120000, + "Frames": 600, + "NormalizedBandwidth": [ + 38.83786594767159, + 29.728144561102256, + 39.110662592758419, + 39.11792577673097, + 39.11792577673097, + 39.11792577673097 + ], "Framerate": [ 60, 60, - 60, - 60, - 60, - 60 + 61, + 61, + 61, + 61 ], "Bandwidth": [ - 72.66801452636719, - 55.08686828613281, - 73.01099395751953, - 73.1099624633789, - 73.3668441772461, - 73.3668441772461 - ], - "DrainDuration": 8.866096705009113, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 72.66801831629948, - 55.08687115913688, - 73.0109977653396, - 73.10996627636058, - 73.3668480036252, - 73.3668480036252 - ] + 38.83786392211914, + 29.60478973388672, + 39.117923736572269, + 39.164852142333987, + 39.164852142333987, + 39.164852142333987 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 200269, + "listenerCallGcSamples": 120000, + "packetDecodeGcSamples": 120000, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -1845, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 120600, + "receiveDecodeGcKb": 2 + }, + "Recieve": 120000 }, - "blink": { + "bytenet": { "Framerate": [ 60, 60, @@ -213,26 +234,27 @@ 61 ], "Bandwidth": [ - 72.8770751953125, - 56.13698959350586, - 72.98052978515625, - 73.06175994873047, - 73.06175994873047, - 73.06175994873047 - ], - "DrainDuration": 8.799909338995349, - "Sent": 120000, + 72.5946044921875, + 48.951656341552737, + 72.68463897705078, + 72.85352325439453, + 72.85352325439453, + 72.85352325439453 + ], + "DrainDuration": 10.316452951999964, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 72.6814330773089, - 55.90692290550966, - 72.9588966273684, - 73.36618774083948, - 73.36618774083948, - 73.36618774083948 + 72.56147381611385, + 48.95165889458056, + 72.68464276785011, + 72.85352705400186, + 72.85352705400186, + 72.85352705400186 ] }, - "zap": { + "packet": { "Framerate": [ 60, 60, @@ -242,23 +264,54 @@ 60 ], "Bandwidth": [ - 72.64482879638672, - 55.25006103515625, - 72.87446594238281, - 72.88887023925781, - 72.99724578857422, - 72.99724578857422 - ], - "DrainDuration": 8.849431556009222, - "Sent": 120000, + 72.8536148071289, + 54.42557907104492, + 72.95780944824219, + 72.96881866455078, + 73.09724426269531, + 73.09724426269531 + ], + "DrainDuration": 10.084193439004594, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 72.64483258510978, - 55.25006391667148, - 72.87446974308239, - 72.88887404070863, - 72.99724959567726, - 72.99724959567726 + 72.85361860674101, + 54.425581909560069, + 72.95781325328847, + 72.96882247017124, + 73.09724807501368, + 73.09724807501368 + ] + }, + "blink": { + "Framerate": [ + 60, + 60, + 60, + 60, + 61, + 61 + ], + "Bandwidth": [ + 72.62368774414063, + 55.93399429321289, + 72.85077667236328, + 72.93170928955078, + 72.97710418701172, + 72.97710418701172 + ], + "DrainDuration": 9.499660818997655, + "Recieve": 120200, + "Sent": 120200, + "Frames": 601, + "NormalizedBandwidth": [ + 72.62098309656125, + 55.93399721039802, + 72.85078047182737, + 72.93171309323583, + 72.9771079930643, + 72.9771079930643 ] } }, @@ -273,52 +326,54 @@ 60 ], "Bandwidth": [ - 2.447920799255371, - 2.340574026107788, - 2.484408140182495, - 2.508678913116455, - 4.404301643371582, - 4.404301643371582 - ], - "DrainDuration": 3.8168795419915115, - "Sent": 120000, + 2.5086474418640138, + 2.4267008304595949, + 2.5434975624084474, + 2.599701404571533, + 4.8839430809021, + 4.8839430809021 + ], + "DrainDuration": 3.833497883999371, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.4479209269243897, - 2.340574148178236, - 2.4844082697544769, - 2.508679043954256, - 4.404301873073813, - 4.404301873073813 + 2.5086475727001735, + 2.4267009570219058, + 2.5434976950621825, + 2.599701540156527, + 4.8839433356195809, + 4.8839433356195809 ] }, "bridgenet2": { "Framerate": [ - 55, - 49, - 57, - 57, - 57, - 57 + 52, + 50, + 52, + 52, + 52, + 52 ], "Bandwidth": [ - 21750.3515625, - 17700.634765625, - 22568.650390625, - 22712.251953125, - 22712.251953125, - 22712.251953125 - ], - "DrainDuration": 26.04329594099545, - "Sent": 107800, - "Recieve": 107800, + 20440.36328125, + 14222.26953125, + 20817.8203125, + 20830.083984375, + 20830.083984375, + 20830.083984375 + ], + "DrainDuration": 23.72997330999351, + "Recieve": 102200, + "Sent": 102200, + "Frames": 511, "NormalizedBandwidth": [ - 24007.249926893564, - 18787.516740806925, - 25090.393220684535, - 26944.340773374064, - 26944.340773374064, - 26944.340773374064 + 23969.856756586956, + 17208.946823698858, + 24235.002486936766, + 24259.964925092096, + 24259.964925092096, + 24259.964925092096 ] }, "netray_compile": { @@ -326,202 +381,253 @@ 60, 60, 60, - 61, - 61, - 61 + 60, + 60, + 60 ], "Bandwidth": [ - 10.281547546386719, - 7.180410861968994, - 10.323692321777344, - 10.326251029968262, - 10.326251029968262, - 10.326251029968262 - ], - "DrainDuration": 5.266024893993745, - "Sent": 120000, + 10.411065101623536, + 7.795403957366943, + 10.457037925720215, + 10.478292465209961, + 10.514304161071778, + 10.514304161071778 + ], + "DrainDuration": 5.517919953999808, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 10.273659288254465, - 7.180411236456603, - 10.32625156852422, - 10.366708242310012, - 10.366708242310012, - 10.366708242310012 + 10.411065644602893, + 7.795404363928942, + 10.457038471097242, + 10.478293011695499, + 10.514304709435472, + 10.514304709435472 ] }, - "bytenet": { + "zap": { "Framerate": [ 60, 60, 60, - 61, - 61, - 61 + 60, + 60, + 60 ], "Bandwidth": [ - 19.037439346313478, - 14.59847354888916, - 19.096935272216798, - 19.101850509643556, - 19.101850509643556, - 19.101850509643556 - ], - "DrainDuration": 6.328172858004109, - "Sent": 119800, - "Recieve": 119800, + 29.41815948486328, + 22.286975860595704, + 29.495773315429689, + 29.504188537597658, + 29.623083114624025, + 29.623083114624025 + ], + "DrainDuration": 7.56714076299977, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 18.945279040047514, - 14.598474310258887, - 19.06402500133346, - 19.0969363037704, - 19.0969363037704, - 19.0969363037704 + 29.41816101913986, + 22.286977022952074, + 29.495774853754143, + 29.504190076361, + 29.6230846595882, + 29.6230846595882 ] }, "roblox": { "Framerate": [ - 50, - 49, - 52, - 52, - 52, - 52 + 47, + 46, + 47, + 48, + 48, + 48 ], "Bandwidth": [ - 53546.9609375, - 48074.2578125, - 54663.33984375, - 57044.5859375, - 57044.5859375, - 57044.5859375 - ], - "DrainDuration": 11.325150161006605, - "Sent": 99400, - "Recieve": 99400, + 54850.5, + 50982.9921875, + 58248.68359375, + 58498.89453125, + 58498.89453125, + 58498.89453125 + ], + "DrainDuration": 10.883574213992688, + "Recieve": 93200, + "Sent": 93200, + "Frames": 466, "NormalizedBandwidth": [ - 63524.20128242976, - 58636.994590338, - 67751.19841846568, - 70141.56062914123, - 70141.56062914123, - 70141.56062914123 + 71744.48005270695, + 66654.17844951219, + 74609.2600992908, + 75301.77151548857, + 75301.77151548857, + 75301.77151548857 ] }, "satset": { + "DrainDuration": 5.733056135009974, + "DebugStats": { + "reliableCommitBytes": 15627202, + "commitGcKb": 25, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 601, + "reliableCommits": 601, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120200, + "sendGcSamples": 240400, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 9384, + "sendGcKb": 1, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120200, + "Frames": 601, + "NormalizedBandwidth": [ + 10.378378455703299, + 8.016314906988994, + 10.436980791828497, + 10.473319364547969, + 10.473319364547969, + 10.473319364547969 + ], "Framerate": [ 60, 60, - 60, - 60, - 60, - 60 + 61, + 61, + 61, + 61 ], "Bandwidth": [ - 10.376862525939942, - 7.734817028045654, - 10.407729148864746, - 10.408055305480957, - 10.421064376831055, - 10.421064376831055 - ], - "DrainDuration": 5.28272814299271, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 10.376863067135496, - 7.734817431447798, - 10.40772969167012, - 10.408055848303342, - 10.421064920331915, - 10.421064920331915 - ] + 10.39358901977539, + 7.983051776885986, + 10.430319786071778, + 10.436980247497559, + 10.436980247497559, + 10.436980247497559 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 893668, + "listenerCallGcSamples": 120200, + "packetDecodeGcSamples": 120200, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -897841, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 120801, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120200 }, - "packet": { + "bytenet": { "Framerate": [ 60, - 54, + 60, 60, 61, 61, 61 ], "Bandwidth": [ - 28.786466598510743, - 21.48399543762207, - 29.15029525756836, - 29.432878494262697, - 29.432878494262697, - 29.432878494262697 - ], - "DrainDuration": 7.313814018998528, - "Sent": 109000, - "Recieve": 109000, + 19.176868438720704, + 14.401999473571778, + 19.27757453918457, + 19.283002853393556, + 19.283002853393556, + 19.283002853393556 + ], + "DrainDuration": 6.567377958999714, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 28.895067833989999, - 21.663030082844409, - 29.514675772655609, - 30.427802018942939, - 30.427802018942939, - 30.427802018942939 + 19.17686943887233, + 14.402000224694583, + 19.283003859080524, + 19.352660432438755, + 19.352660432438755, + 19.352660432438755 ] }, - "blink": { + "packet": { "Framerate": [ + 58, + 57, + 58, 60, 60, - 61, - 61, - 61, - 61 + 60 ], "Bandwidth": [ - 29.26051139831543, - 22.337413787841798, - 29.318355560302736, - 29.335769653320314, - 29.335769653320314, - 29.335769653320314 - ], - "DrainDuration": 7.297905995990732, - "Sent": 120000, - "Recieve": 120000, + 26.09518814086914, + 19.7695369720459, + 28.519512176513673, + 29.08045768737793, + 29.08045768737793, + 29.08045768737793 + ], + "DrainDuration": 7.360662229999434, + "Recieve": 115800, + "Sent": 115800, + "Frames": 579, "NormalizedBandwidth": [ - 29.19819990161679, - 22.2458681804663, - 29.335771183299927, - 29.422323500054497, - 29.422323500054497, - 29.422323500054497 + 27.071632823912127, + 20.536459916930484, + 29.44396522846702, + 29.502945554249235, + 29.502945554249235, + 29.502945554249235 ] }, - "zap": { + "blink": { "Framerate": [ 60, 60, 60, - 61, + 60, 61, 61 ], "Bandwidth": [ - 29.381929397583009, - 21.87703514099121, - 29.435056686401368, - 29.541475296020509, - 29.541475296020509, - 29.541475296020509 - ], - "DrainDuration": 7.267011803996866, - "Sent": 119800, - "Recieve": 119800, + 29.401473999023439, + 22.449277877807618, + 29.4440975189209, + 29.45580291748047, + 29.459657669067384, + 29.459657669067384 + ], + "DrainDuration": 7.4836189199995719, + "Recieve": 120200, + "Sent": 120200, + "Frames": 601, "NormalizedBandwidth": [ - 29.38193092997004, - 21.877036281967507, - 29.423049553940716, - 29.5577042837756, - 29.5577042837756, - 29.5577042837756 + 29.4014755324298, + 22.449279048628698, + 29.44409905455025, + 29.45965920550826, + 29.578536958561047, + 29.578536958561047 ] } }, @@ -530,90 +636,93 @@ "Framerate": [ 60, 60, - 61, - 61, - 61, - 61 + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 2.2454726696014406, - 1.8616403341293336, - 2.325646162033081, - 2.3369789123535158, - 2.3369789123535158, - 2.3369789123535158 - ], - "DrainDuration": 3.8144485960074236, - "Sent": 119800, - "Recieve": 119800, + 2.285691976547241, + 2.0940165519714357, + 2.4591119289398195, + 2.503413677215576, + 2.5347096920013429, + 2.5347096920013429 + ], + "DrainDuration": 3.6146651309973096, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.245472786711966, - 1.861640431221443, - 2.3256462833249804, - 2.346716445790875, - 2.346716445790875, - 2.346716445790875 + 2.2856920957553674, + 2.094016661182909, + 2.4591120571925009, + 2.5034138077787739, + 2.5347098241967549, + 2.5347098241967549 ] }, "bridgenet2": { "Framerate": [ 60, - 55, 60, 60, - 60, - 60 + 61, + 61, + 61 ], "Bandwidth": [ - 1680.568603515625, - 1323.0751953125, - 1682.277587890625, - 1683.3160400390626, - 1683.3160400390626, - 1683.3160400390626 - ], - "DrainDuration": 17.761656613001834, - "Sent": 89800, - "Recieve": 89800, + 1680.3319091796876, + 1333.3367919921876, + 1682.7130126953126, + 1683.593505859375, + 1683.593505859375, + 1683.593505859375 + ], + "DrainDuration": 16.98342470198986, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 1681.1296042792993, - 1323.0752643162487, - 1683.3161278308353, - 1820.4390354684579, - 1820.4390354684579, - 1820.4390354684579 + 1680.3319968158258, + 1333.3368615311202, + 1682.713100455635, + 1683.5935936656188, + 1683.5935936656188, + 1683.5935936656188 ] }, "netray_compile": { "Framerate": [ 60, 60, - 61, + 60, 61, 61, 61 ], "Bandwidth": [ - 4.93384313583374, - 3.7336151599884035, - 4.954408645629883, - 4.975438117980957, - 4.975438117980957, - 4.975438117980957 - ], - "DrainDuration": 4.250556561994017, - "Sent": 120000, + 4.987257480621338, + 3.819934844970703, + 5.054417610168457, + 5.069162368774414, + 5.069162368774414, + 5.069162368774414 + ], + "DrainDuration": 4.383725410996703, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 4.933843393153712, - 3.733615354711608, - 4.954408904022429, - 4.975438377470276, - 4.975438377470276, - 4.975438377470276 + 4.987257740727085, + 3.8042795744528599, + 5.0544178737768779, + 5.069162633151834, + 5.069162633151834, + 5.069162633151834 ] }, - "bytenet": { + "zap": { "Framerate": [ 60, 60, @@ -623,23 +732,24 @@ 60 ], "Bandwidth": [ - 4.901780605316162, - 3.8276753425598146, - 4.975456237792969, - 4.991796970367432, - 5.037708282470703, - 5.037708282470703 - ], - "DrainDuration": 4.216418586001964, - "Sent": 120000, + 4.97285795211792, + 4.023661136627197, + 5.1511945724487309, + 5.165728569030762, + 5.211760997772217, + 5.211760997772217 + ], + "DrainDuration": 4.583293417003006, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 4.901780860963942, - 3.82767554218864, - 4.975456497283233, - 4.991797230709931, - 5.037708545207664, - 5.037708545207664 + 4.972858211472673, + 4.023661346477478, + 5.151194841104463, + 5.165728838444501, + 5.211761269586734, + 5.211761269586734 ] }, "roblox": { @@ -652,26 +762,60 @@ 60 ], "Bandwidth": [ - 3902.99658203125, - 3682.523193359375, - 4031.613525390625, - 4065.48876953125, - 4065.48876953125, - 4065.48876953125 - ], - "DrainDuration": 9.315510572007043, - "Sent": 119800, - "Recieve": 119800, + 3558.9931640625, + 3427.2333984375, + 3706.50439453125, + 3745.291015625, + 3847.739013671875, + 3847.739013671875 + ], + "DrainDuration": 9.383830263992423, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 3902.9967855883844, - 3682.523385417926, - 4031.6137356556557, - 4065.488981563012, - 4065.488981563012, - 4065.488981563012 + 3558.993349678458, + 3427.2335771816508, + 3706.504587840518, + 3745.291210957148, + 3847.7392143471026, + 3847.7392143471026 ] }, "satset": { + "DrainDuration": 4.217027832011809, + "DebugStats": { + "reliableCommitBytes": 3841200, + "commitGcKb": 7, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 600, + "reliableCommits": 600, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120000, + "sendGcSamples": 240000, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120000, + "Frames": 600, + "NormalizedBandwidth": [ + 4.31099437309026, + 3.3748039575191326, + 4.396046390923285, + 4.417518369277023, + 4.4220998209319799, + 4.4220998209319799 + ], "Framerate": [ 60, 60, @@ -681,26 +825,38 @@ 60 ], "Bandwidth": [ - 4.293588161468506, - 3.270570755004883, - 4.32204008102417, - 4.324096202850342, - 4.366925239562988, - 4.366925239562988 - ], - "DrainDuration": 4.217419569002232, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 4.293588385396578, - 3.27057092557844, - 4.322040306436126, - 4.324096428369533, - 4.3669254673158879, - 4.3669254673158879 - ] + 4.3109941482543949, + 3.3748037815093996, + 4.396046161651611, + 4.417518138885498, + 4.422099590301514, + 4.422099590301514 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 33733, + "listenerCallGcSamples": 120000, + "packetDecodeGcSamples": 120000, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -815, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 120600, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120000 }, - "packet": { + "bytenet": { "Framerate": [ 60, 60, @@ -710,55 +866,57 @@ 61 ], "Bandwidth": [ - 4.803657531738281, - 3.796332597732544, - 4.824338912963867, - 4.825944900512695, - 4.825944900512695, - 4.825944900512695 - ], - "DrainDuration": 4.199859785003355, - "Sent": 120000, + 4.859020233154297, + 3.9970057010650636, + 5.129150867462158, + 5.145942211151123, + 5.145942211151123, + 5.145942211151123 + ], + "DrainDuration": 4.64927950699348, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 4.8045672849604099, - 3.8121508472744409, - 4.816999171817148, - 4.846053254758935, - 4.846053254758935, - 4.846053254758935 + 4.85902048657195, + 3.9970059169701588, + 5.129151134968222, + 5.145942479532923, + 5.145942479532923, + 5.145942479532923 ] }, - "blink": { + "packet": { "Framerate": [ 60, 60, - 61, - 61, - 61, - 61 + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 4.998149871826172, - 3.912663221359253, - 5.013729095458984, - 5.015888214111328, - 5.015888214111328, - 5.015888214111328 - ], - "DrainDuration": 4.198811416004901, - "Sent": 120000, + 4.7038164138793949, + 3.645994186401367, + 4.75673770904541, + 4.799077987670898, + 4.884762287139893, + 4.884762287139893 + ], + "DrainDuration": 4.366468509004335, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 4.998150132500001, - 3.9126634254205419, - 5.015888475710284, - 5.021390465179062, - 5.021390465179062, - 5.021390465179062 + 4.703816659202538, + 3.645994376554782, + 4.756737957128614, + 4.79907823796232, + 4.884762541900098, + 4.884762541900098 ] }, - "zap": { + "blink": { "Framerate": [ 60, 60, @@ -768,173 +926,212 @@ 60 ], "Bandwidth": [ - 4.982448577880859, - 3.807426691055298, - 5.024774551391602, - 5.049847602844238, - 5.059690952301025, - 5.059690952301025 - ], - "DrainDuration": 4.283437647012761, - "Sent": 120000, - "Recieve": 120000, + 5.011424541473389, + 3.9369800090789797, + 5.033984184265137, + 5.068098545074463, + 5.081544399261475, + 5.081544399261475 + ], + "DrainDuration": 4.716122358004213, + "Recieve": 120200, + "Sent": 120200, + "Frames": 601, "NormalizedBandwidth": [ - 4.982448837735802, - 3.807426889628074, - 5.024774813454016, - 5.049847866214314, - 5.059691216184472, - 5.059691216184472 + 5.011424802839546, + 3.9369802144084877, + 5.033984446807871, + 5.0680988093964, + 5.081544664284667, + 5.081544664284667 ] } }, "Entities": { "warp": { "Framerate": [ - 50, - 40, - 52, 52, + 48, 52, - 52 + 53, + 53, + 53 ], "Bandwidth": [ - 8.710792541503907, - 4.467971324920654, - 10.118857383728028, - 10.149181365966797, - 10.149181365966797, - 10.149181365966797 - ], - "DrainDuration": 5.2914539460034579, - "Sent": 87600, - "Recieve": 87600, + 9.991240501403809, + 7.457734107971191, + 11.156453132629395, + 11.567028999328614, + 11.567028999328614, + 11.567028999328614 + ], + "DrainDuration": 7.008535045009921, + "Recieve": 100200, + "Sent": 100200, + "Frames": 501, "NormalizedBandwidth": [ - 10.895018055909928, - 6.757806987631254, - 11.815462019070863, - 11.870198790826985, - 11.870198790826985, - 11.870198790826985 + 12.039445493511014, + 8.963623217458578, + 13.791458409616113, + 13.808304795985452, + 13.808304795985452, + 13.808304795985452 ] }, "bridgenet2": { "Framerate": [ - 17, - 16, - 17, 18, + 17, 18, - 18 + 19, + 19, + 19 ], "Bandwidth": [ - 23520.376953125, - 12758.107421875, - 27017.2109375, - 27022.33203125, - 27022.33203125, - 27022.33203125 - ], - "DrainDuration": 26.51570917101344, - "Sent": 27000, - "Recieve": 27000, + 28973.953125, + 13049.1376953125, + 31393.55859375, + 33632.66015625, + 33632.66015625, + 33632.66015625 + ], + "DrainDuration": 27.845124879007927, + "Recieve": 30200, + "Sent": 30200, + "Frames": 151, "NormalizedBandwidth": [ - 87240.7040796132, - 42527.02640305121, - 97738.73922716463, - 101333.75009127376, - 101333.75009127376, - 101333.75009127376 + 98591.92874522704, + 41894.60215413484, + 109005.41620196977, + 120187.30636667559, + 120187.30636667559, + 120187.30636667559 ] }, "netray_compile": { "Framerate": [ 60, 60, - 61, - 61, - 61, - 61 + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 38.93456268310547, - 28.886159896850587, - 38.98399353027344, - 38.98530578613281, - 38.98530578613281, - 38.98530578613281 - ], - "DrainDuration": 7.833227431008709, - "Sent": 120000, + 38.96963882446289, + 28.8632755279541, + 39.038116455078128, + 39.07029724121094, + 39.072296142578128, + 39.072296142578128 + ], + "DrainDuration": 8.316689771003439, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 38.891821028610568, - 29.00652039577748, - 38.98399556344714, - 38.98530781937495, - 38.98530781937495, - 38.98530781937495 + 38.969640856887938, + 28.863277033291227, + 39.038118491074559, + 39.07029927888573, + 39.072298180357169, + 39.072298180357169 ] }, - "bytenet": { + "zap": { "Framerate": [ 60, - 57, - 61, - 61, - 61, - 61 + 60, + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 38.159420013427737, - 29.424619674682618, - 38.9777946472168, - 39.206695556640628, - 39.206695556640628, - 39.206695556640628 - ], - "DrainDuration": 7.782035968004493, - "Sent": 118800, - "Recieve": 118800, + 38.96997833251953, + 29.015649795532228, + 39.00817108154297, + 39.02146530151367, + 39.12831497192383, + 39.12831497192383 + ], + "DrainDuration": 8.400210028004949, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 38.58125714508226, - 29.547223811370097, - 39.20669763794322, - 39.610457282828189, - 39.610457282828189, - 39.610457282828189 + 38.96998036496228, + 29.015651308816289, + 39.00817311597763, + 39.02146733664168, + 39.12831701262448, + 39.12831701262448 ] }, "roblox": { "Framerate": [ 18, + 17, 18, 19, 19, - 19, 19 ], "Bandwidth": [ - 208655.3125, - 184098.6875, - 211734.09375, - 213581.03125, - 213581.03125, - 213581.03125 - ], - "DrainDuration": 14.778737654996803, - "Sent": 34800, - "Recieve": 34800, + 197299.859375, + 182099.53125, + 212456.8125, + 217581.34375, + 217581.34375, + 217581.34375 + ], + "DrainDuration": 14.265211578996969, + "Recieve": 34200, + "Sent": 34200, + "Frames": 171, "NormalizedBandwidth": [ - 707109.71090404, - 618776.1803695357, - 720484.1075725526, - 721747.0565034436, - 721747.0565034436, - 721747.0565034436 + 690549.5426024647, + 629760.9114681836, + 738742.9832118796, + 780733.0848301966, + 780733.0848301966, + 780733.0848301966 ] }, "satset": { + "DrainDuration": 8.322948571003508, + "DebugStats": { + "reliableCommitBytes": 72722202, + "commitGcKb": 0, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 601, + "reliableCommits": 601, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120200, + "sendGcSamples": 240400, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 7869, + "sendGcKb": 1, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120200, + "Frames": 601, + "NormalizedBandwidth": [ + 39.15123952968912, + 29.455731974468479, + 39.24122442818103, + 39.258817812887659, + 39.273450992361777, + 39.273450992361777 + ], "Framerate": [ 60, 60, @@ -944,84 +1141,130 @@ 60 ], "Bandwidth": [ - 38.97240447998047, - 28.81517219543457, - 39.12338638305664, - 39.136940002441409, - 39.13933181762695, - 39.13933181762695 - ], - "DrainDuration": 7.8001610320061449, - "Sent": 120000, - "Recieve": 120000, + 39.15123748779297, + 29.455730438232423, + 39.2412223815918, + 39.25881576538086, + 39.2734489440918, + 39.2734489440918 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 88813, + "listenerCallGcSamples": 120200, + "packetDecodeGcSamples": 120200, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -2994, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 120801, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120200 + }, + "bytenet": { + "Framerate": [ + 60, + 60, + 61, + 61, + 61, + 61 + ], + "Bandwidth": [ + 39.04008483886719, + 29.01456069946289, + 39.21613311767578, + 39.225399017333987, + 39.225399017333987, + 39.225399017333987 + ], + "DrainDuration": 8.350599078999949, + "Recieve": 119800, + "Sent": 119800, + "Frames": 599, "NormalizedBandwidth": [ - 38.97240651254975, - 28.81517369826291, - 39.123388423500248, - 39.13694204359189, - 39.13933385890218, - 39.13933385890218 + 39.04008771122126, + 29.256351014764783, + 39.45072944186563, + 39.55228050123543, + 39.55228050123543, + 39.55228050123543 ] }, "packet": { "Framerate": [ - 51, - 48, + 52, + 50, 52, 52, 52, 52 ], "Bandwidth": [ - 30.554224014282228, - 22.863338470458986, - 32.05663299560547, - 33.080440521240237, - 33.080440521240237, - 33.080440521240237 - ], - "DrainDuration": 7.531132645992329, - "Sent": 100200, - "Recieve": 100200, + 30.11553955078125, + 20.197500228881837, + 31.87305450439453, + 32.00583267211914, + 32.00583267211914, + 32.00583267211914 + ], + "DrainDuration": 8.339981492012157, + "Recieve": 102000, + "Sent": 102000, + "Frames": 510, "NormalizedBandwidth": [ - 36.77355554879297, - 27.122196900753069, - 38.037682241174199, - 39.442065648820719, - 39.442065648820719, - 39.442065648820719 + 35.430048180170988, + 23.499015784715494, + 37.39143131132933, + 38.24766722194006, + 38.24766722194006, + 38.24766722194006 ] }, "blink": { "Framerate": [ 60, 60, - 61, - 61, + 60, + 60, 61, 61 ], "Bandwidth": [ - 39.00115203857422, - 29.122724533081056, - 39.026817321777347, - 39.04824447631836, - 39.04824447631836, - 39.04824447631836 - ], - "DrainDuration": 7.514331072990899, - "Sent": 120000, - "Recieve": 120000, + 38.97825241088867, + 29.38810157775879, + 38.99757385253906, + 39.017723083496097, + 39.03395080566406, + 39.03395080566406 + ], + "DrainDuration": 8.263846114001354, + "Recieve": 120200, + "Sent": 120200, + "Frames": 601, "NormalizedBandwidth": [ - 38.97832692301478, - 29.1227260519495, - 39.04824651284301, - 39.16365886311749, - 39.16365886311749, - 39.16365886311749 + 38.97825444376295, + 29.388103110467726, + 38.99757588642103, + 39.01772511842893, + 39.03395284144324, + 39.03395284144324 ] - }, - "zap": { + } + }, + "Strings": { + "warp": { "Framerate": [ 60, 60, @@ -1031,28 +1274,27 @@ 60 ], "Bandwidth": [ - 38.95712661743164, - 29.078960418701173, - 39.0257682800293, - 39.05777359008789, - 39.10287857055664, - 39.10287857055664 - ], - "DrainDuration": 7.833464256007574, - "Sent": 120000, + 4.443981647491455, + 3.3753182888031008, + 5.856051445007324, + 6.189422130584717, + 6.478349685668945, + 6.478349685668945 + ], + "DrainDuration": 4.317077106999932, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 38.95712864920412, - 29.078961989450926, - 39.02577031538172, - 39.05777562710952, - 39.10288060993068, - 39.10288060993068 + 4.443981879263159, + 3.3753184648396674, + 5.856051750424207, + 6.189422453388236, + 6.478350023541211, + 6.478350023541211 ] - } - }, - "Strings": { - "warp": { + }, + "bridgenet2": { "Framerate": [ 60, 60, @@ -1062,55 +1304,150 @@ 60 ], "Bandwidth": [ - 3.385514497756958, - 3.21207332611084, - 5.507931709289551, - 6.249972820281982, - 7.934593677520752, - 7.934593677520752 - ], - "DrainDuration": 3.7656679959909526, + 27457.384765625, + 21161.580078125, + 27694.439453125, + 27980.609375, + 28068.15625, + 28068.15625 + ], + "DrainDuration": 25.232977284002119, + "Recieve": 120000, "Sent": 120000, + "Frames": 600, + "NormalizedBandwidth": [ + 27457.386197639207, + 21161.58122120392, + 27694.440897502573, + 27980.610834302497, + 28068.157713868422, + 28068.157713868422 + ] + }, + "netray_compile": { + "Framerate": [ + 60, + 60, + 61, + 61, + 61, + 61 + ], + "Bandwidth": [ + 96.4015884399414, + 72.80319213867188, + 96.70467376708985, + 96.89170837402344, + 96.89170837402344, + 96.89170837402344 + ], + "DrainDuration": 11.949982346995967, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 3.3855146743252986, - 3.2120734936335184, - 5.507931996550575, - 6.249973146243466, - 7.93459409134206, - 7.93459409134206 + 96.3110630674467, + 73.1065425514845, + 96.7046788106316, + 96.89171342731982, + 96.89171342731982, + 96.89171342731982 ] }, - "bridgenet2": { + "zap": { "Framerate": [ 60, - 55, 60, 60, + 61, + 61, + 61 + ], + "Bandwidth": [ + 100.43354797363281, + 67.98133087158203, + 100.70870208740235, + 100.7239990234375, + 100.7239990234375, + 100.7239990234375 + ], + "DrainDuration": 10.317053609993309, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, + "NormalizedBandwidth": [ + 100.2959667820463, + 67.98133441708473, + 100.72400427660341, + 101.01239020824147, + 101.01239020824147, + 101.01239020824147 + ] + }, + "roblox": { + "Framerate": [ 60, - 60 + 60, + 60, + 61, + 61, + 61 ], "Bandwidth": [ - 27012.642578125, - 19714.439453125, - 27200.52734375, - 27309.103515625, - 27309.103515625, - 27309.103515625 - ], - "DrainDuration": 24.265411052998389, - "Sent": 106200, - "Recieve": 106200, + 62755.31640625, + 47559.0078125, + 146779.453125, + 160764.46875, + 160764.46875, + 160764.46875 + ], + "DrainDuration": 13.047871394010145, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 27071.311958753868, - 21410.245237316405, - 27309.104939905737, - 27523.818904290434, - 27523.818904290434, - 27523.818904290434 + 62755.3196791948, + 47364.09633806866, + 146779.46078014503, + 161434.32904771914, + 161434.32904771914, + 161434.32904771914 ] }, - "netray_compile": { + "satset": { + "DrainDuration": 10.333382266006084, + "DebugStats": { + "reliableCommitBytes": 260281200, + "commitGcKb": 424, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 600, + "reliableCommits": 600, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 2, + "streamGrowthBytes": 786432, + "adapterGcSamples": 120000, + "sendGcSamples": 240002, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 7168, + "sendGcKb": 769, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120000, + "Frames": 600, + "NormalizedBandwidth": [ + 96.37056471849917, + 73.8260689138059, + 96.86780290361185, + 96.93914537559437, + 97.09934741031674, + 97.09934741031674 + ], "Framerate": [ 60, 60, @@ -1120,24 +1457,36 @@ 60 ], "Bandwidth": [ - 96.54653930664063, - 72.74851989746094, - 96.86563873291016, - 97.10099792480469, - 97.40682983398438, - 97.40682983398438 - ], - "DrainDuration": 10.832776184994146, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 96.54654434193503, - 72.74852369159192, - 96.8656437848469, - 97.10100298901637, - 97.40683491414643, - 97.40683491414643 - ] + 96.37055969238281, + 73.82606506347656, + 96.8677978515625, + 96.93914031982422, + 97.0993423461914, + 97.0993423461914 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 159692, + "listenerCallGcSamples": 120000, + "packetDecodeGcSamples": 120000, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": 2, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 120600, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120000 }, "bytenet": { "Framerate": [ @@ -1156,9 +1505,10 @@ 0, 0 ], - "DrainDuration": 3.010798364994116, - "Sent": 1600, + "DrainDuration": 4.535122966000927, "Recieve": 1600, + "Sent": 1600, + "Frames": 8, "NormalizedBandwidth": [ 0, 0, @@ -1168,64 +1518,6 @@ 0 ] }, - "roblox": { - "Framerate": [ - 56, - 53, - 60, - 61, - 61, - 61 - ], - "Bandwidth": [ - 53459.51171875, - 39032.52734375, - 82090.7578125, - 116585.578125, - 116585.578125, - 116585.578125 - ], - "DrainDuration": 10.945210890000454, - "Sent": 112200, - "Recieve": 112200, - "NormalizedBandwidth": [ - 58319.470805656594, - 41820.56773755125, - 85275.31763855576, - 127184.27450777802, - 127184.27450777802, - 127184.27450777802 - ] - }, - "satset": { - "Framerate": [ - 60, - 60, - 60, - 60, - 60, - 60 - ], - "Bandwidth": [ - 96.43982696533203, - 72.35977172851563, - 96.58458709716797, - 96.72514343261719, - 96.90149688720703, - 96.90149688720703 - ], - "DrainDuration": 9.882589490996907, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 96.43983199506096, - 72.3597755023718, - 96.58459213444672, - 96.72514847722653, - 96.90150194101392, - 96.90150194101392 - ] - }, "packet": { "Framerate": [ 60, @@ -1236,55 +1528,27 @@ 61 ], "Bandwidth": [ - 96.45869445800781, - 72.38963317871094, - 96.79341888427735, - 97.13880920410156, - 97.13880920410156, - 97.13880920410156 - ], - "DrainDuration": 9.866840552000213, - "Sent": 120000, + 95.9897689819336, + 72.84919738769531, + 96.62486267089844, + 96.62947845458985, + 96.62947845458985, + 96.62947845458985 + ], + "DrainDuration": 10.433760499989149, "Recieve": 120000, - "NormalizedBandwidth": [ - 96.42791488018162, - 72.69126040772432, - 96.74070442022716, - 96.89167679308182, - 96.89167679308182, - 96.89167679308182 - ] - }, - "blink": { - "Framerate": [ - 60, - 60, - 60, - 60, - 60, - 60 - ], - "Bandwidth": [ - 99.93290710449219, - 68.13643646240235, - 100.39676666259766, - 100.58865356445313, - 100.66536712646485, - 100.66536712646485 - ], - "DrainDuration": 9.863170425000135, "Sent": 120000, - "Recieve": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 99.93291231639944, - 68.13644001599443, - 100.39677189869707, - 100.58865881056022, - 100.66537237657286, - 100.66537237657286 + 95.98977398819017, + 72.84920118707703, + 96.62486771027773, + 96.62948349420987, + 96.62948349420987, + 96.62948349420987 ] }, - "zap": { + "blink": { "Framerate": [ 60, 60, @@ -1294,23 +1558,24 @@ 60 ], "Bandwidth": [ - 100.30909729003906, - 72.05551147460938, - 100.70087432861328, - 100.71550750732422, - 100.72301483154297, - 100.72301483154297 - ], - "DrainDuration": 9.86579776200233, - "Sent": 120000, - "Recieve": 120000, + 100.05217742919922, + 75.12348175048828, + 100.24107360839844, + 100.26873779296875, + 100.42533111572266, + 100.42533111572266 + ], + "DrainDuration": 12.300088531002985, + "Recieve": 120200, + "Sent": 120200, + "Frames": 601, "NormalizedBandwidth": [ - 100.30910252156616, - 72.05551523259715, - 100.70087958057315, - 100.71551276004726, - 100.72302008465755, - 100.72302008465755 + 100.0521826473269, + 75.12348566848317, + 100.24107883637783, + 100.26874302239094, + 100.42533635331182, + 100.42533635331182 ] } }, @@ -1320,57 +1585,59 @@ 60, 60, 60, - 60, - 60, - 60 + 61, + 61, + 61 ], "Bandwidth": [ - 2.2502639293670656, - 1.965975284576416, - 2.418292760848999, - 2.507328748703003, - 2.507328748703003, - 2.507328748703003 - ], - "DrainDuration": 4.010584692005068, - "Sent": 119800, - "Recieve": 119800, + 2.241762399673462, + 1.7462072372436524, + 2.280869483947754, + 2.311460494995117, + 2.311460494995117, + 2.311460494995117 + ], + "DrainDuration": 3.7998242970061257, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.250264046727475, - 1.9659753871100172, - 2.418292886972795, - 2.5073288794703876, - 2.5073288794703876, - 2.5073288794703876 + 2.241762516590482, + 1.7390507417041388, + 2.2808696029043675, + 2.311460615547176, + 2.311460615547176, + 2.311460615547176 ] }, "bridgenet2": { "Framerate": [ 60, - 55, + 60, 60, 60, 60, 60 ], "Bandwidth": [ - 145.30645751953126, - 86.84367370605469, - 145.8762969970703, - 145.9589385986328, - 145.9589385986328, - 145.9589385986328 - ], - "DrainDuration": 10.68330016300024, - "Sent": 98800, - "Recieve": 98800, + 144.8165740966797, + 114.40079498291016, + 144.9199981689453, + 144.95138549804688, + 145.18226623535157, + 145.18226623535157 + ], + "DrainDuration": 11.432884189998731, + "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 145.30646509785357, - 95.13330211097316, - 145.87630460511208, - 145.95894621098467, - 145.95894621098467, - 145.95894621098467 + 144.8165816494526, + 114.40080094937656, + 144.9200057271122, + 144.95139305785075, + 145.1822738071968, + 145.1822738071968 ] }, "netray_compile": { @@ -1383,84 +1650,120 @@ 60 ], "Bandwidth": [ - 2.3817059993743898, - 1.874155879020691, - 2.411635160446167, - 2.4140243530273439, - 2.4336061477661135, - 2.4336061477661135 - ], - "DrainDuration": 3.7315073780046079, - "Sent": 120000, + 2.37839412689209, + 1.7392919063568116, + 2.423856735229492, + 2.4351439476013185, + 2.451141119003296, + 2.451141119003296 + ], + "DrainDuration": 3.733749546998297, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.381706123590037, - 1.874155976765537, - 2.411635286222742, - 2.414024478928525, - 2.4336062746885647, - 2.4336062746885647 + 2.37839425093501, + 1.7392919970679533, + 2.423856861643472, + 2.435144074603972, + 2.451141246840267, + 2.451141246840267 ] }, - "bytenet": { + "zap": { "Framerate": [ - 61, 60, - 61, - 61, - 61, - 61 + 60, + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 2.3101882934570314, - 1.8508734703063965, - 2.3256075382232668, - 2.327732563018799, - 2.327732563018799, - 2.327732563018799 - ], - "DrainDuration": 3.733247598996968, - "Sent": 120000, + 2.3771073818206789, + 1.826068639755249, + 2.4150452613830568, + 2.4232165813446047, + 2.426578998565674, + 2.426578998565674 + ], + "DrainDuration": 3.732387935000588, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.309021116518579, - 1.8508735668369703, - 2.3256076595131516, - 2.3277326844195125, - 2.3277326844195125, - 2.3277326844195125 + 2.3771075057964898, + 1.82606873499215, + 2.415045387337482, + 2.4232167077251978, + 2.4265791251216308, + 2.4265791251216308 ] }, "roblox": { "Framerate": [ 60, 60, - 61, + 60, 61, 61, 61 ], "Bandwidth": [ - 232.29190063476563, - 228.8047637939453, - 235.5247802734375, - 235.59292602539063, - 235.59292602539063, - 235.59292602539063 - ], - "DrainDuration": 8.382915554990177, - "Sent": 120000, + 233.7328643798828, + 229.4481658935547, + 234.47068786621095, + 235.19984436035157, + 235.19984436035157, + 235.19984436035157 + ], + "DrainDuration": 10.316508645002614, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 232.29191274973233, - 228.80477572704366, - 235.524792557012, - 235.5929383125192, - 235.5929383125192, - 235.5929383125192 + 233.73287657000163, + 229.44817786020907, + 234.47070009481025, + 235.19985662697935, + 235.19985662697935, + 235.19985662697935 ] }, "satset": { + "DrainDuration": 3.698995181999635, + "DebugStats": { + "reliableCommitBytes": 241602, + "commitGcKb": 0, + "unreliableCommits": 0, + "receiveDecodeGcKb": 0, + "commitGcSamples": 601, + "reliableCommits": 601, + "packetDecodeGcKb": 0, + "listenerCallGcSamples": 0, + "packetDecodeGcSamples": 0, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 120200, + "sendGcSamples": 240400, + "listenerDispatchGcKb": 0, + "listenerDispatchGcSamples": 0, + "adapterGcKb": 7792, + "sendGcKb": 1, + "unreliableCommitBytes": 0, + "listenerCallGcKb": 0, + "receiveDecodeGcSamples": 0 + }, + "Sent": 120200, + "Frames": 601, + "NormalizedBandwidth": [ + 2.382770424182654, + 1.8550478677193945, + 2.4348571714693225, + 2.4499806251366698, + 2.4499806251366698, + 2.4499806251366698 + ], "Framerate": [ 60, 60, @@ -1470,84 +1773,98 @@ 61 ], "Bandwidth": [ - 2.3600337505340578, - 1.8788734674453736, - 2.4089317321777345, - 2.423952341079712, - 2.423952341079712, - 2.423952341079712 - ], - "DrainDuration": 3.748035296011949, - "Sent": 120000, - "Recieve": 120000, - "NormalizedBandwidth": [ - 2.3600338736194095, - 1.878873565436261, - 2.4089318578133147, - 2.423952467498678, - 2.423952467498678, - 2.423952467498678 - ] + 2.382770299911499, + 1.8473504781723023, + 2.4247539043426515, + 2.4499804973602297, + 2.4499804973602297, + 2.4499804973602297 + ], + "ServerDebugStats": { + "reliableCommitBytes": 0, + "commitGcKb": 0, + "unreliableCommits": 0, + "listenerDispatchGcSamples": 0, + "commitGcSamples": 0, + "reliableCommits": 0, + "packetDecodeGcKb": 8023, + "listenerCallGcSamples": 120200, + "packetDecodeGcSamples": 120200, + "streamGrowths": 0, + "streamGrowthBytes": 0, + "adapterGcSamples": 0, + "sendGcSamples": 0, + "listenerDispatchGcKb": 0, + "listenerCallGcKb": -1127, + "adapterGcKb": 0, + "sendGcKb": 0, + "unreliableCommitBytes": 0, + "receiveDecodeGcSamples": 120801, + "receiveDecodeGcKb": 0 + }, + "Recieve": 120200 }, - "packet": { + "bytenet": { "Framerate": [ 60, 60, - 61, - 61, - 61, - 61 + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 2.2492129802703859, - 1.8232378959655762, - 2.2864480018615724, - 2.3006608486175539, - 2.3006608486175539, - 2.3006608486175539 - ], - "DrainDuration": 3.7495955190097449, - "Sent": 120000, + 2.3558192253112795, + 1.8665226697921754, + 2.3975536823272707, + 2.4173099994659426, + 2.4335269927978517, + 2.4335269927978517 + ], + "DrainDuration": 3.750927599001443, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.249213097575984, - 1.8157657050413503, - 2.286448121109128, - 2.3006609686063674, - 2.3006609686063674, - 2.3006609686063674 + 2.3558193481768265, + 1.8665227671389185, + 2.397553807369439, + 2.4173101255384834, + 2.4335271197161747, + 2.4335271197161747 ] }, - "blink": { + "packet": { "Framerate": [ 60, 60, - 61, - 61, - 61, - 61 + 60, + 60, + 60, + 60 ], "Bandwidth": [ - 2.4459776878356935, - 1.9182907342910767, - 2.4515068531036379, - 2.479783296585083, - 2.479783296585083, - 2.479783296585083 - ], - "DrainDuration": 3.817761062993668, - "Sent": 120000, + 2.312589645385742, + 1.8398791551589966, + 2.3718972206115724, + 2.4044816493988039, + 2.433119058609009, + 2.433119058609009 + ], + "DrainDuration": 3.750964612001553, "Recieve": 120000, + "Sent": 120000, + "Frames": 600, "NormalizedBandwidth": [ - 2.437858547605591, - 1.9182908343377348, - 2.4580825298049859, - 2.47978342591586, - 2.47978342591586, - 2.47978342591586 + 2.312589765996691, + 1.8398792511161722, + 2.371897344315652, + 2.404481774802294, + 2.4331191855060565, + 2.4331191855060565 ] }, - "zap": { + "blink": { "Framerate": [ 60, 60, @@ -1557,23 +1874,24 @@ 60 ], "Bandwidth": [ - 2.3627519607543947, - 1.885648488998413, - 2.3907129764556886, - 2.397568941116333, - 2.4187347888946535, - 2.4187347888946535 - ], - "DrainDuration": 3.6999580029951177, - "Sent": 120000, - "Recieve": 120000, + 2.390836715698242, + 1.910537838935852, + 2.447601795196533, + 2.464641571044922, + 2.487464189529419, + 2.487464189529419 + ], + "DrainDuration": 3.683417451000423, + "Recieve": 120200, + "Sent": 120200, + "Frames": 601, "NormalizedBandwidth": [ - 2.362752083981512, - 1.8856485873426455, - 2.3907131011410867, - 2.3975690661592976, - 2.4187349150415029, - 2.4187349150415029 + 2.3908368403900939, + 1.9105379385781652, + 2.4476019228489145, + 2.4646416995859967, + 2.487464319260786, + 2.487464319260786 ] } } diff --git a/benchmark/satset-benchmark.rbxl b/benchmark/satset-benchmark.rbxl new file mode 100644 index 0000000..72ec6a5 Binary files /dev/null and b/benchmark/satset-benchmark.rbxl differ diff --git a/benchmark/src/client/init.client.luau b/benchmark/src/client/init.client.luau index 71d0d35..2a3496d 100644 --- a/benchmark/src/client/init.client.luau +++ b/benchmark/src/client/init.client.luau @@ -1,5 +1,5 @@ -- Benchmark client. Fires 200 events per frame for 10 seconds per tool per bench. --- Measures FPS and bandwidth (Kbps) at percentile intervals. +-- Measures FPS and bandwidth in KB/s as reported by Stats.DataSendKbps. local HttpService = game:GetService("HttpService") local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") @@ -7,20 +7,19 @@ local RunService = game:GetService("RunService") local StarterGui = game:GetService("StarterGui") local Stats = game:GetService("Stats") +local BenchmarkConfig = require(ReplicatedStorage.Shared.BenchmarkConfig) local Satset = require(ReplicatedStorage.references.Satset) +local SatsetBatcher = require(ReplicatedStorage.references.Satset.Core.Batcher) Satset.start({ - batching = { - reliableThreshold = 60000, - maxPacketsPerFrame = 20, - }, + batching = BenchmarkConfig.batching, }) +SatsetBatcher.setDebugGcEnabled(true) local MAXIMUM_FRAMERATE = 60 local Benches, Modes -- Minimize rendering overhead to isolate network performance. --- Disabe Character AutoLoads in Player service instead for _, item in Enum.CoreGuiType:GetEnumItems() do while true do @@ -40,6 +39,9 @@ type Benchmark = { NormalizedBandwidth: { number }, Framerate: { number }, DrainDuration: number, + Frames: number?, + DebugStats: { [string]: number }?, + ServerDebugStats: { [string]: number }?, } type Results = { @@ -117,6 +119,14 @@ local function waitForDrain(baselineKbps: number): number return os.clock() - started end +local function assertSplitDebugStats(stats: { [string]: number }?, source: string) + if not stats or stats.packetDecodeGcKb == nil or stats.listenerCallGcKb == nil then + error( + `[Satset Benchmark] {source} is missing split GC stats. Stop Play, reconnect Rojo, and rerun the benchmark.` + ) + end +end + local function runBenchmark(tool: string, bench: string): Benchmark local total = 0 local frames = 0 @@ -125,12 +135,18 @@ local function runBenchmark(tool: string, bench: string): Benchmark local framerates = {} local sent = 0 + local totalFrames = 0 local data = Benches[bench] local events = Modes[tool] local event = events[bench] local method local lowerTool = string.lower(tool) + if lowerTool == "satset" then + SatsetBatcher.resetDebugStats() + ReplicatedStorage.Shared.GetRecieved:InvokeServer("resetSatsetDebugStats") + end + if lowerTool == "roblox" then method = function(d) event:FireServer(d) @@ -150,6 +166,7 @@ local function runBenchmark(tool: string, bench: string): Benchmark local connection = RunService.PostSimulation:Connect(function(dt: number) total += dt frames += 1 + totalFrames += 1 if total >= 1 then local actualKbps = Stats.DataSendKbps @@ -189,13 +206,28 @@ local function runBenchmark(tool: string, bench: string): Benchmark table.insert(frameratePercentiles, percentile(framerates, pct)) end - return { + local result: Benchmark = { Sent = sent, Recieve = 0, Bandwidth = bandwidthPercentiles, NormalizedBandwidth = normalizedBandwidthPercentiles, Framerate = frameratePercentiles, + Frames = totalFrames, } + + if lowerTool == "satset" then + local debugStats = SatsetBatcher.getDebugStats() + assertSplitDebugStats(debugStats, "Client SatsetBatcher") + result.DebugStats = debugStats + + if BenchmarkConfig.activeMode == "latency" and debugStats.reliableCommits > totalFrames + 2 then + error( + `[Satset Benchmark] reliableThreshold = 0 produced {debugStats.reliableCommits} reliable commits across {totalFrames} frames` + ) + end + end + + return result end local function runAll() @@ -203,6 +235,12 @@ local function runAll() Modes = require(ReplicatedStorage.Shared.modes) local results: Results = {} + assertSplitDebugStats(SatsetBatcher.getDebugStats(), "Client SatsetBatcher") + assertSplitDebugStats( + ReplicatedStorage.Shared.GetRecieved:InvokeServer("getSatsetDebugStats"), + "Server SatsetBatcher" + ) + print("Measuring baseline bandwidth...") local baselineKbps = measureBaseline(5) print(`Baseline DataSendKbps: {baselineKbps}`) @@ -216,6 +254,24 @@ local function runAll() results[bench][tool] = runBenchmark(tool, bench) local drainDuration = waitForDrain(baselineKbps) results[bench][tool].DrainDuration = drainDuration + + if string.lower(tool) == "satset" then + local debugStats = SatsetBatcher.getDebugStats() + assertSplitDebugStats(debugStats, "Client SatsetBatcher") + results[bench][tool].DebugStats = debugStats + if + BenchmarkConfig.activeMode == "latency" + and debugStats.reliableCommits > (results[bench][tool].Frames or 0) + 2 + then + error( + `[Satset Benchmark] reliableThreshold = 0 produced {debugStats.reliableCommits} reliable commits across {results[bench][tool].Frames or 0} frames` + ) + end + + local serverDebugStats = ReplicatedStorage.Shared.GetRecieved:InvokeServer("getSatsetDebugStats") + assertSplitDebugStats(serverDebugStats, "Server SatsetBatcher") + results[bench][tool].ServerDebugStats = serverDebugStats + end end waitForDrain(baselineKbps) diff --git a/benchmark/src/server/init.server.luau b/benchmark/src/server/init.server.luau index e599188..471be55 100644 --- a/benchmark/src/server/init.server.luau +++ b/benchmark/src/server/init.server.luau @@ -1,13 +1,13 @@ -- Benchmark server. Receives data from all modes and validates correctness. local ReplicatedStorage = game:GetService("ReplicatedStorage") +local BenchmarkConfig = require(ReplicatedStorage.Shared.BenchmarkConfig) local Satset = require(ReplicatedStorage.references.Satset) +local SatsetBatcher = require(ReplicatedStorage.references.Satset.Core.Batcher) Satset.start({ - batching = { - reliableThreshold = 60000, - maxPacketsPerFrame = 20, - }, + batching = BenchmarkConfig.batching, }) +SatsetBatcher.setDebugGcEnabled(true) local Benches = require(game:GetService("ReplicatedStorage").Shared.benches) local Modes = require(ReplicatedStorage.Shared.modes) @@ -111,7 +111,14 @@ for name, data in Benches do end -- Client pulls received counts to compute packet loss. -ReplicatedStorage.Shared.GetRecieved.OnServerInvoke = function() +ReplicatedStorage.Shared.GetRecieved.OnServerInvoke = function(_player, action: string?) + if action == "resetSatsetDebugStats" then + SatsetBatcher.resetDebugStats() + return true + elseif action == "getSatsetDebugStats" then + return SatsetBatcher.getDebugStats() + end + return received end diff --git a/benchmark/src/shared/BenchmarkConfig.luau b/benchmark/src/shared/BenchmarkConfig.luau new file mode 100644 index 0000000..633e08b --- /dev/null +++ b/benchmark/src/shared/BenchmarkConfig.luau @@ -0,0 +1,24 @@ +-- Select which Satset batching profile the benchmark runner uses. +-- Change activeMode to "latency" when regenerating latency-mode-result.json. +local activeMode = "default" + +local modes = { + default = { + batching = { + reliableThreshold = 60000, + maxPacketsPerFrame = 20, + }, + }, + latency = { + batching = { + reliableThreshold = 0, + maxPacketsPerFrame = 0, + }, + }, +} + +return { + activeMode = activeMode, + batching = modes[activeMode].batching, + modes = modes, +} diff --git a/benchmark/src/shared/modes/bridgenet2.luau b/benchmark/src/shared/modes/bridgenet2.luau index d8c1492..62f00ff 100644 --- a/benchmark/src/shared/modes/bridgenet2.luau +++ b/benchmark/src/shared/modes/bridgenet2.luau @@ -1,6 +1,6 @@ -- BridgeNet2 benchmark mode (v1.0.0 API). -- BridgeNet2 uses ReferenceBridge with string identifiers. -local BridgeNet2 = require(game:GetService("ReplicatedStorage").DevPackages.bridgenet2) +local BridgeNet2 = require(game:GetService("ReplicatedStorage").DevPackages.BridgeNet2) local Benches = require(game:GetService("ReplicatedStorage").Shared.benches) diff --git a/benchmark/src/shared/modes/bytenet.luau b/benchmark/src/shared/modes/bytenet.luau index 3693282..d8810f2 100644 --- a/benchmark/src/shared/modes/bytenet.luau +++ b/benchmark/src/shared/modes/bytenet.luau @@ -1,5 +1,5 @@ -- ByteNet benchmark mode (v0.4.6 API). -local ByteNet = require(game:GetService("ReplicatedStorage").DevPackages.bytenet) +local ByteNet = require(game:GetService("ReplicatedStorage").DevPackages.ByteNet) -- ByteNet 0.4.6 requires the schema to be in the 'value' field. return ByteNet.defineNamespace("Benchmark", function() diff --git a/benchmark/src/shared/modes/satset.luau b/benchmark/src/shared/modes/satset.luau index 56d085d..ad14044 100644 --- a/benchmark/src/shared/modes/satset.luau +++ b/benchmark/src/shared/modes/satset.luau @@ -1,6 +1,7 @@ -- Satset benchmark mode. local RunService = game:GetService("RunService") local Satset = require(game:GetService("ReplicatedStorage").references.Satset) +local SatsetBatcher = require(game:GetService("ReplicatedStorage").references.Satset.Core.Batcher) local Types = Satset.Types -- We don't call Satset.start() here anymore. @@ -81,12 +82,14 @@ for name, packet: any in Packets do Wrapped[name] = { fire = function(data: any) if RunService:IsClient() then + local gcStart = SatsetBatcher.beginDebugGc() local isWrapped = (type(data) == "table" and data[1] ~= nil) or type(data) == "number" + local payload = data if isWrapped then - packet:fireServer({ value = data }) - else - packet:fireServer(data) + payload = { value = data } end + SatsetBatcher.recordDebugGc("adapter", gcStart) + packet:fireServer(payload) end end, listen = function(callback: any) diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000..477e7af Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/api/channel.md b/docs/api/channel.md index a408636..70d8300 100644 --- a/docs/api/channel.md +++ b/docs/api/channel.md @@ -15,7 +15,7 @@ type ChannelConfig = { > [!IMPORTANT] > Channels only support **fixed-size types**. This allows the engine to pre-compute buffer offsets and perform zero-allocation updates. -> There is a limit of **32 fields** per channel. This is a technical constraint of the 32-bit dirty bitmask tracking used to keep delta updates O(1) and extremely compact. +> There is a limit of **32 fields** per channel. This is a technical constraint of the 32-bit dirty bitmask tracking used to keep delta updates O(1) and compact. ## Methods (Channel Object) diff --git a/docs/api/packet.md b/docs/api/packet.md index f248c19..5b2014f 100644 --- a/docs/api/packet.md +++ b/docs/api/packet.md @@ -18,7 +18,7 @@ Objects returned by `Satset.definePacket`. ### `:listen(callback: (data: table, sender: Player?) -> ())` -Registers a listener for the packet. Listeners are wrapped in `xpcall` internally, so an error in one listener will not prevent other listeners from running or crash the library. Errors are reported to the output via `warn`. +Registers a listener for the packet. Listener calls are wrapped in `pcall`, so an error in one listener does not prevent later listeners from running. Errors are reported through `warn`. - **data**: The decoded payload. - **sender**: The player who sent the packet (Server only). diff --git a/docs/api/satset.md b/docs/api/satset.md index 1ed8c42..f7755d1 100644 --- a/docs/api/satset.md +++ b/docs/api/satset.md @@ -6,13 +6,14 @@ The main entry point for the library. ### `Satset.start(config: SatsetConfig?)` -Initializes the networking engine. Must be called once on both server and client. Calling it more than once is safe — subsequent calls are ignored with a warning. +Initializes the networking engine. Must be called once on both server and client. Calling it more than once is safe; later calls are ignored with a warning. - **config**: Optional configuration object. - **guard**: Guard configuration (see [Guard API](./guard.md)). - **batching**: Batching behavior. - - **reliableThreshold**: (number) Size in bytes before a reliable payload is segmented. Default is `60000`. Set to `0` to disable segmentation for lower latency. - - **maxPacketsPerFrame**: (number) Maximum number of packets to process per frame. Default is `0` (unlimited). + - **reliableThreshold**: (number) Size in bytes before a reliable stream is committed and a new stream begins. Default is `60000`. Set to `0` to disable threshold splitting; reliable packets are committed at the frame flush. + - **unreliableThreshold**: (number) Size in bytes before an unreliable stream is committed and a new stream begins. Default is `900`. + - **maxPacketsPerFrame**: (number) Maximum committed batches sent per frame for each queue. Default is `0` (no cap). ### `Satset.definePacket(config: PacketConfig): Packet` @@ -55,7 +56,7 @@ Reference to the [Types module](./types.md). ## Performance Context -Initialization and packet definitions are O(1) operations. For details on how Satset's hybrid engine performs under extreme network load, see the [Benchmarks Report](../../benchmark/Benchmarks.md). +Initialization and packet definitions are O(1) operations. For benchmark results under heavy local Studio load, see the [Benchmarks Report](../../benchmark/Benchmarks.md). ## Related Guides diff --git a/docs/api/types.md b/docs/api/types.md index c7d8c94..d509454 100644 --- a/docs/api/types.md +++ b/docs/api/types.md @@ -34,7 +34,7 @@ Standard and optimized types for schemas. - `optional(type)`: Nullable type. Adds a **1-byte header** (a `u8` boolean flag) to check for `nil`. - `array(type)`: Array of a specific type. Includes a **2-byte header** (a `u16` integer) for length (max 65,535 elements) followed by the array elements. -- `map(keyType, valType)`: Dictionary mapping. Includes a **2-byte header** (a `u16` integer) for element count. Keys are sorted alphabetically during serialization to ensure deterministic byte order output. +- `map(keyType, valType)`: Dictionary mapping. Includes a **2-byte header** (a `u16` integer) for element count. Keys are sorted alphabetically during serialization to produce deterministic byte order output. - `enum(values: {string})`: Efficient mapping. Converts string constants into a **single 1-byte `u8` index** corresponding to its array position. ## Specialized diff --git a/docs/guide/architecture.md b/docs/guide/architecture.md index 0bd51c3..7c6b07e 100644 --- a/docs/guide/architecture.md +++ b/docs/guide/architecture.md @@ -32,23 +32,21 @@ sequenceDiagram participant SN as Sanitizer Dev->>PK: fireServer(data) - PK->>SR: encode(compiledSchema, data) + PK->>SR: calculateSize(compiledSchema, data) SR->>SC: uses field order and offsets - SR->>SR: calculateSize(compiledSchema, data) - SR->>SR: encodeInto(buffer, offset) - SR-->>PK: returns payload buffer - - PK->>BT: enqueue(packetId, payload, reliable) + PK->>BT: allocateForServer(packetId, size, reliable) + BT-->>PK: buffer, offset + PK->>SR: encodeInto(compiledSchema, data, buffer, offset) Note over BT: PostSimulation fires once per frame - BT->>BT: encodeBatch(queue) - opt payload > reliableThreshold - BT->>BT: segment(payload) + BT->>BT: commitStream(queue) + opt reliableThreshold > 0 and stream exceeds threshold + BT->>BT: commit current buffer and start a new one end - Note right of BT: Wire: [u8 count][u8 id, (opt u16 size), payload]... + Note right of BT: Wire: [u16 count][u8 id, (opt u16 size), payload]... BT->>BR: getReliable() - BR->>RE: FireServer(segments[]) + BR->>RE: FireServer(batchBuffer) Note over RE: Crosses the network boundary @@ -56,16 +54,15 @@ sequenceDiagram GD->>GD: consume(player) via token bucket alt Token available GD->>PK: _dispatch(batchBuffer, player) - PK->>BT: decodeBatch(batchBuffer) - BT-->>PK: entries[] + PK->>BT: processBatch(batchBuffer, player, _dispatchSingle) loop For each entry - PK->>PK: pcall(decode) - PK->>SR: decodeFrom(compiled, buffer, offset, dispatch) - SR->>SR: uses callback-based iteration + BT->>PK: dispatch(packetId, buffer, payloadOffset, sender) + PK->>PK: pcall(decodeToTable) + PK->>SR: decodeToTable(compiled, buffer, offset) SR->>SN: sanitizeFloat(value) for each number field SR->>SN: checkBounds(buffer, cursor, size) - SR-->>PK: invokes dispatch(...) callback - PK->>Dev: listener(data, sender) + SR-->>PK: decoded data table + PK->>Dev: listener(data, sender) via pcall Note over PK: data table constructed only if listeners exist end else Token exhausted @@ -76,7 +73,7 @@ sequenceDiagram ### Wire Format (Reliable Batch) ```luau -[u8 packetCount] +[u16 packetCount] [u8 packetId][u16 payloadSize][...payload bytes] (Variable size) [u8 packetId][...payload bytes] (Fixed size - size header omitted) ... @@ -87,7 +84,7 @@ sequenceDiagram Unreliable batches include a sequence number for stale packet detection. If the batch exceeds 900 bytes (MTU limit), it is automatically split into multiple sub-batches, each with its own sequence number. ```luau -[u16 sequenceNumber][u8 packetCount] +[u16 sequenceNumber][u16 packetCount] [u8 packetId][u16 payloadSize][...payload bytes] (Variable) [u8 packetId][...payload bytes] (Fixed) ... @@ -157,38 +154,38 @@ Channels periodically send a full keyframe to prevent client-side state drift ca Satset processes incoming data through a strict validation stack before it reaches the developer's listener: -1. **OOB Shielding (`pcall`)**: All packet decoding runs inside a protected call. If a malicious payload forces a read past the end of the buffer, the VM throws an error that is immediately caught and silenced. -2. **Allocation Capping (`table.create`)**: Variable-length types (arrays, strings, maps) mathematically limit their allocations based on the remaining bytes in the payload. This prevents exploiters from crashing the server with massive GC spikes. +1. **OOB Shielding (`pcall`)**: Packet decoding runs inside a protected call. If a malicious payload forces a read past the end of the buffer, the VM throws an error that is caught and silenced. +2. **Allocation Capping (`table.create`)**: Variable-length types (arrays, strings, maps) limit their allocations based on the remaining bytes in the payload. This prevents memory exhaustion and large GC spikes. 3. **Float Sanitization (`Sanitizer.sanitizeFloat`)**: All floating-point fields (`f32`, `f64`, `Vector3`, etc.) are clamped to prevent `NaN` and `Infinity` from propagating into game logic. 4. **Schema Verification (`Sanitizer.checkBounds`)**: For fixed-size schema fields, the serializer checks that enough bytes remain before executing the read. ## Batching Strategies -Satset's batching engine can be configured to balance between raw networking performance and engine stability. This is controlled via the `batching` table in `Satset.start()`. +Satset's batching engine is configured through the `batching` table in `Satset.start()`. -### Stability Mode (Default) +### Default Runtime Settings -Optimized for consistent engine frame-times and reliable delivery of large data chunks. +The default runtime settings split reliable streams above 60 KB and send every ready batch during the frame flush. ```luau batching = { - reliableThreshold = 60000, -- Segmentation at 60KB - maxPacketsPerFrame = 0 -- No rate limiting (default) + reliableThreshold = 60000, -- Split reliable batches above 60 KB + maxPacketsPerFrame = 0, -- Send all ready batches each frame } ``` -> In this mode, Satset segments large payloads to stay within Roblox's internal buffer > limits, preventing "packet too large" errors and ensuring the engine can process network ?traffic smoothly. +`maxPacketsPerFrame` caps how many committed batches each queue can send in one frame. A value of `0` means no cap. -### Latency Mode +### One-Commit Profile -Optimized for minimum overhead and maximum throughput. Recommended for competitive games with small, frequent updates. +Setting `reliableThreshold` to `0` disables threshold splitting for reliable streams. Queued reliable packets are committed once at the frame flush. ```luau batching = { - reliableThreshold = 0, -- Bypass segmentation - maxPacketsPerFrame = 0 + reliableThreshold = 0, -- Disable threshold splitting + maxPacketsPerFrame = 0, } ``` ->[!NOTE] ->By setting `reliableThreshold` to 0, Satset sends payloads as a single segment. This reduces protocol overhead and allows the engine's underlying [Zstd](https://github.com/facebook/zstd) compression to work much more efficiently, often resulting in significantly lower bandwidth usage in benchmarks. +> [!NOTE] +> The current benchmark latency profile uses this setting. It reduces commit count for large homogeneous payloads, which reduces measured `Stats.DataSendKbps` in the benchmark. It also allows larger `RemoteEvent` payloads, so test it with real game payloads before use. diff --git a/docs/guide/development-patterns.md b/docs/guide/development-patterns.md index 67817d2..aa95572 100644 --- a/docs/guide/development-patterns.md +++ b/docs/guide/development-patterns.md @@ -1,19 +1,19 @@ # Development Patterns -Satset follows strict performance and safety constraints. These patterns ensure the library stays efficient under high-throughput conditions. +Satset follows strict performance and safety constraints. These patterns keep the library predictable under high-throughput conditions. -## Zero-allocation hot path +## Allocation-aware hot path -Allocations during the sync cycle are prohibited. Satset uses native Luau `buffer` operations for all throughput to avoid garbage collection (GC) overhead. +The send path avoids per-packet queue tables. Satset writes payloads directly into Luau `buffer` streams and commits exact-size buffers at flush time. -* **The Problem**: Table and string allocations trigger GC pauses. When syncing hundreds of entities, these pauses cause frame drops. -* **The Pattern**: Reuse pre-allocated buffers. Avoid creating tables or strings during encoding and decoding. +* **The Problem**: Table and string allocations can trigger GC pauses. When syncing hundreds of entities, those pauses can reduce frame rate. +* **The Pattern**: Reuse working buffers on the send path. Decode into tables only at the public API boundary, where packet listeners and channel subscribers receive Lua values. ## Deterministic byte alignment Satset doesn't transmit type metadata or field names. Server and client must share an identical understanding of the buffer layout. -* **The Pattern**: `SchemaCompiler` sorts field definitions alphabetically before calculating memory offsets. This guarantees that different environments produce the same binary schema, regardless of how the Luau table is ordered. +* **The Pattern**: `SchemaCompiler` sorts field definitions alphabetically before calculating memory offsets. This produces the same binary schema across environments, regardless of how the Luau table is ordered. ## Mandatory input sanitization @@ -32,7 +32,7 @@ Choose data types based on bit-density. State sync is an explicit, bitmask-tracked process, not an automatic "magic" sync. -* **The Pattern**: `Channels` track modified fields using a 32-bit mask. Only dirty fields are sent. Syncing happens during `PostSimulation` to maximize batching efficiency. +* **The Pattern**: `Channels` track modified fields using a 32-bit mask. Only dirty fields are sent. Syncing happens during `PostSimulation`, the same frame phase used by packet batching. ## Defensive buffer reads @@ -53,7 +53,7 @@ Satset uses a specific naming convention to maintain code clarity across the lib ## Change checklist -When you modify any part of Satset, use this checklist to make sure nothing falls out of sync. Not every change touches every item, but you should actively consider each one. +When you modify any part of Satset, use this checklist to make sure related docs and examples stay in sync. Not every change touches every item. ### If you change a public API method or add a new one diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md index 4bce1ed..3bde5ba 100644 --- a/docs/guide/getting-started.md +++ b/docs/guide/getting-started.md @@ -16,8 +16,8 @@ Satset.start({ studioBypass = true -- Enabled by default }, batching = { - reliableThreshold = 60000, -- Segmentation for stability - maxPacketsPerFrame = 0 -- No frame-spreading + reliableThreshold = 60000, -- Split reliable batches above 60 KB + maxPacketsPerFrame = 0, -- Send all ready batches each frame } }) ``` diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 4359aa3..01b8adf 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -24,4 +24,4 @@ wally install ## Rojo -If you are using Rojo, you can simply sync the `src/` folder into your project under `ReplicatedStorage.Packages.Satset`. +If you are using Rojo, sync the `src/` folder into your project under `ReplicatedStorage.Packages.Satset`. diff --git a/docs/guide/introduction.md b/docs/guide/introduction.md index 0852cba..c4d71d2 100644 --- a/docs/guide/introduction.md +++ b/docs/guide/introduction.md @@ -1,17 +1,17 @@ # Introduction -**Satset** is a high-performance, buffer-backed hybrid networking library for Roblox. It is designed to be the fastest and most efficient way to synchronize data between the server and clients, combining the best patterns from community leaders like [Blink](https://github.com/1Axen/blink), [Zap](https://github.com/red-blox/zap), [ByteNet](https://github.com/ffrostfall/ByteNet), [Warp](https://github.com/imezx/Warp), [BridgeNet2](https://github.com/ffrostfall/BridgeNet2), [Packet](https://devforum.roblox.com/t/packet-networking-library/3573907/1), and [Red](https://github.com/red-blox/Red). +**Satset** is a buffer-backed hybrid networking library for Roblox. It provides stateless packets, stateful channels, schema-based serialization, and server-side rate limiting. ## Why Satset? -Roblox's native `RemoteEvent` system is powerful but can be inefficient for high-frequency data (like character positions or combat state). Satset solves this by: +Roblox's native `RemoteEvent` system can become expensive for high-frequency data such as character positions or combat state. Satset handles this with: -- **Buffer-backed serialization**: Uses Luau `buffer` for zero-allocation, tightly packed data. -- **Automatic batching**: Combines multiple packet fires into a single remote call per frame. +- **Buffer-backed serialization**: Uses Luau `buffer` for compact binary payloads. +- **Automatic batching**: Queues packet fires and commits them during `PostSimulation`. - **Stateful Channels**: Efficiently synchronizes state changes using bitmask-based delta compression. -- **Security-first**: Built-in rate limiting (Guard) and data sanitization. -- **Developer Experience**: Simple, type-safe API that doesn't require a complex build step for most use cases. +- **Guard and sanitization**: Applies server-side token buckets, buffer bounds checks, and float sanitization. +- **Plain Luau API**: Works without a code generation step. ## "Sat set, sampai." -The name comes from Indonesian slang meaning "quick and efficient." Our goal is to get your data from A to B as fast and reliably as possible, with no overhead. +The name comes from Indonesian slang meaning "quick and efficient." Satset aims to reduce per-event overhead while keeping the API direct. diff --git a/docs/guide/packets.md b/docs/guide/packets.md index e7c8afe..8e13df2 100644 --- a/docs/guide/packets.md +++ b/docs/guide/packets.md @@ -1,12 +1,12 @@ # Packets -Packets are the primary way to send data in Satset. They are designed for **stateless** communication—you send a piece of data, and the receiver handles it. +Packets are the primary way to send data in Satset. They are designed for **stateless** communication: you send a piece of data, and the receiver handles it. ## Automatic Batching -One of Satset's core strengths is automatic batching. When you call `:fireServer()` or `:fireClient()`, the data isn't sent immediately. Instead, Satset waits until the end of the frame, combines all outgoing packets into a single buffer, and sends them in one go. +When you call `:fireServer()` or `:fireClient()`, Satset queues the encoded payload instead of sending it immediately. During `PostSimulation`, each queue is committed to one or more buffers and sent through the matching remote. -This drastically reduces the overhead caused by Roblox's internal `RemoteEvent` overhead. +Reliable batches split at `reliableThreshold`. Unreliable batches split around 900 bytes by default. Fixed-size packet schemas omit payload-size headers. ## Reliability @@ -18,7 +18,7 @@ local PositionUpdate = Satset.definePacket({ schema = { pos = Types.Vector3, }, - reliable = false -- Use UnreliableRemoteEvent + reliable = false, -- Use UnreliableRemoteEvent }) ``` diff --git a/docs/guide/security.md b/docs/guide/security.md index efe8cf6..8dc6096 100644 --- a/docs/guide/security.md +++ b/docs/guide/security.md @@ -1,6 +1,6 @@ # Security -Satset was built with production security in mind. It includes multiple layers of protection to keep your server safe from malicious clients. +Satset treats incoming network data as untrusted. The server validates payloads before game code receives them. ## The Guard @@ -28,19 +28,19 @@ When a player exceeds their limit, the Guard drops the packet silently. We do no We treat all incoming client data as hostile. If an exploiter sends a corrupted or spoofed packet, the server must not crash or lag. -- **OOB Shielding**: We wrap all packet decoding in a `pcall`. If a malicious client truncates a buffer to force an out-of-bounds read, the operation fails silently. The server drops the packet without printing stack traces to the console. +- **OOB Shielding**: We wrap packet decoding in a `pcall`. If a malicious client truncates a buffer to force an out-of-bounds read, the operation fails silently. The server drops the packet without printing stack traces to the console. - **Allocation Capping**: When reading variable-length types like arrays or strings, we cap the `table.create` allocation to the actual remaining bytes in the buffer. If an exploiter sends a 4-byte payload claiming to contain 65,000 elements, Satset limits the array size to match the buffer. This stops memory exhaustion and garbage collector spikes. - **Float Sanitization**: We clamp `NaN` and `±Infinity` to `0` when reading or writing floating-point numbers (`f32`, `f64`, `Vector3`). This prevents corrupted math from infecting the server state. ## Listener Protection -All user-registered callbacks (both `Packet:listen` and `Channel:subscribe`) are wrapped in `xpcall`. If your callback throws an error, it will: +User-registered callbacks are protected before Satset calls them. `Packet:listen` uses `pcall`; `Channel:subscribe` uses `xpcall`. If your callback throws an error, Satset: -1. Be caught and reported via `warn` with the packet/channel name and the error message. -2. Not affect any other listeners registered on the same packet or channel. -3. Not halt the library's internal dispatch loop. +1. Catches it and reports it via `warn` with the packet or channel name and the error message. +2. Continues running other listeners registered on the same packet or channel. +3. Continues the internal dispatch loop. -This prevents a single broken game script from taking down the entire networking layer. +One broken game callback does not stop packet or channel dispatch. ## Stateless Design