You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+40-5Lines changed: 40 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -387,7 +387,7 @@ Used as the second argument to `packet:send()` on the server.
387
387
|`Lync.f16`| 2 | ±65,504, roughly 3 digits of precision |
388
388
|`Lync.f32`| 4 | IEEE 754 single |
389
389
|`Lync.f64`| 8 | IEEE 754 double |
390
-
|`Lync.bool`| 1 | true/false. Gets packed into bitfields when inside structs. |
390
+
|`Lync.bool`| 1 | true/false. Gets packed into bitfields when inside structs, and 8-per-byte when inside arrays. |
391
391
392
392
### Datatypes
393
393
@@ -418,7 +418,7 @@ Used as the second argument to `packet:send()` on the server.
418
418
| Constructor | What it does |
419
419
|:------------|:------------|
420
420
|`Lync.struct({ key = codec })`| Named fields. Bools get packed into bitfields automatically. |
421
-
|`Lync.array(codec, maxCount?)`| Variable length list with varint count. Optional `maxCount` rejects on read if exceeded. |
421
+
|`Lync.array(codec, maxCount?)`| Variable length list with varint count. Optional `maxCount` rejects on read if exceeded. Bool arrays are bitpacked (8 per byte). |
422
422
|`Lync.map(keyCodec, valueCodec, maxCount?)`| Key-value pairs with varint count. Optional `maxCount` rejects on read if exceeded. |
423
423
|`Lync.optional(codec)`| 1 byte flag, value only if present. |
424
424
|`Lync.tuple(codec, codec, ...)`| Ordered positional values, no keys. |
@@ -505,9 +505,14 @@ Same data shapes and methodology as [Blink's benchmark suite](https://github.com
505
505
506
506
## Stats
507
507
508
+
Off by default. Call `Lync.enableStats()` before `Lync.start()` to activate. When disabled, zero overhead on send and receive paths.
509
+
508
510
Per-packet counters are available directly on the Packet object. Per-player counters are available via `Lync.getPlayerStats()`.
|`Lync.getPlayerStats(player)`| Returns `{ bytesSent, bytesReceived }` or nil. Server only. |
537
+
|`Lync.resetStats()`| Zeros all counters in-place. |
530
538
531
539
## Flush Control
532
540
@@ -539,8 +547,8 @@ Lync.flush() -- force an immediate flush, resets the accumulator
539
547
540
548
| Function | What it does |
541
549
|:---------|:------------|
542
-
|`Lync.setFlushRate(hz)`| 1 to 60. Default 60. Callable at runtime. |
543
-
|`Lync.flush()`| Immediate flush. Resets the timer so you dont double-send at frame end. |
550
+
|`Lync.setFlushRate(hz)`| 1 to 60. Default 60. Callable at runtime. At 60hz, flushes every Heartbeat directly (no accumulator). Below 60, uses an elapsed-time accumulator with drift correction. |
551
+
|`Lync.flush()`| Immediate flush. Skips the next scheduled Heartbeat flush to prevent double-sending and XOR chain desync. |
544
552
545
553
## Security
546
554
@@ -558,6 +566,32 @@ Fires `onDrop` with reason `"bandwidth"` when a player exceeds the threshold. Re
558
566
559
567
If a packet uses `Lync.unknown` anywhere in its codec tree without a `validate` callback, Lync prints a warning at define time. The `unknown` codec bypasses schema validation entirely; client data goes through Roblox's sidecar without type checking. Adding `validate` suppresses the warning.
560
568
569
+
## Packet Capture
570
+
571
+
Server-only debug tool. Records raw and XOR'd buffer hex for analysis.
572
+
573
+
```luau
574
+
Lync.startCapture("My test")
575
+
-- fire packets...
576
+
Lync.flush()
577
+
Lync.stopCapture()
578
+
579
+
Lync.startCapture("Another test")
580
+
-- fire packets...
581
+
Lync.flush()
582
+
Lync.stopCapture()
583
+
584
+
Lync.dumpCaptures() -- writes JSON to ServerStorage.LyncCapture
585
+
```
586
+
587
+
Each entry contains the label, frame number, raw hex (pre-XOR), XOR'd hex (post-XOR, nil for unreliable), byte count, and refs count. Hex is capped at 512 bytes per buffer to keep the output manageable.
588
+
589
+
| Function | What it does |
590
+
|:---------|:------------|
591
+
|`Lync.startCapture(label?)`| Start recording. Tags entries with the label. |
592
+
|`Lync.stopCapture()`| Stop recording. |
593
+
|`Lync.dumpCaptures()`| Writes all entries as JSON to a StringValue in ServerStorage, then clears. |
594
+
561
595
## Limits & Configuration
562
596
563
597
Call these before `Lync.start()` unless noted otherwise.
@@ -567,6 +601,7 @@ Call these before `Lync.start()` unless noted otherwise.
567
601
| Packet types | 255 | Cant change | u8 on the wire. Each query eats 2 IDs. |
568
602
| Buffer per channel per frame | 256 KB |`Lync.setChannelMaxSize(n)`| 4 KB to 1 MB. |
569
603
| Concurrent queries | 65,536 | Cant change | Varint correlation IDs. Freed on response or timeout. `Lync.queryPendingCount()` returns in-flight count. Queries default to 30/s rate limit. |
604
+
| Stats | Off |`Lync.enableStats()`| Zero overhead when off. Counters on packets and players. |
0 commit comments