Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), version

## [Unreleased]

## [0.1.2] — 2026-04-30

This update focuses on **Hardening** and **Production Readiness**. We've implemented strict defensive programming to ensure Satset can survive malicious network traffic and internal script errors without crashing the server.

### Added

- **Initialization Guard**: `Satset.start()` now prevents multiple calls, protecting the engine from state corruption.
- **Listener Resilience**: All packet listeners and channel subscribers are now isolated using `xpcall`. An error in one script won't break the entire networking layer.
- **Bounds Checking**: Added strict validation for `string8`, `string16`, `array`, and `map` types to prevent buffer over-reads from malformed packets.
- **CI/CD Automation**: Release workflow now builds and attaches versioned `.rbxm` assets automatically.

### Changed

- **Benchmark Results**: Updated documentation with latest stress-test data showing significant bandwidth and FPS advantages over Roblox and BridgeNet2.
- **Documentation**: Added a detailed Contributor Checklist and updated security guides.

### Fixed

- Resolved type-inference errors and Selene linting warnings in the benchmark harness.
- Fixed a bug where a single failing listener could halt the entire dispatch loop.

## [0.1.1] — 2026-04-30

- **Documentation**: Implementation of `development-patterns.md` and `architecture.md` (df06036) by @protheeuz
Expand Down
100 changes: 73 additions & 27 deletions benchmark/Benchmarks.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/api/channel.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type ChannelConfig = {

### `:subscribe(callback: (entityId: number, state: table) -> ())`

**Client Only.** Registers a listener for state updates. The callback is triggered whenever any field in the entity changes.
**Client Only.** Registers a listener for state updates. The callback is triggered whenever any field in the entity changes. Subscribers are wrapped in `xpcall`, so an error in one subscriber will not affect others or halt state synchronization.

## Entity Object

Expand Down
2 changes: 1 addition & 1 deletion docs/api/packet.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Objects returned by `Satset.definePacket`.

### `:listen(callback: (data: table, sender: Player?) -> ())`

Registers a listener for the packet.
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`.

- **data**: The decoded payload.
- **sender**: The player who sent the packet (Server only).
6 changes: 5 additions & 1 deletion docs/api/satset.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The main entry point for the library.

### `Satset.start(config: SatsetConfig?)`

Initializes the networking engine. Must be called once on both server and client.
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.

- **config**: Optional configuration object.
- **guard**: Guard configuration (see [Guard API](./guard.md)).
Expand All @@ -21,6 +21,10 @@ Defines a new stateful channel.

## Properties

### `Satset.Version`

A string containing the current library version (e.g. `"0.1.1"`).

### `Satset.Types`

Reference to the [Types module](./types.md).
Expand Down
46 changes: 46 additions & 0 deletions docs/guide/development-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,49 @@ Satset uses a specific naming convention to maintain code clarity across the lib
* **camelCase**: Used for public API methods, local variables, and object properties (e.g., `definePacket`, `channelId`, `maxTokens`).
* **_camelCase** (Leading underscore): Used for internal/private state or functions that should not be accessed by the public API (e.g., `_guard`, `_applyUpdate`).
* **SCREAMING_SNAKE_CASE**: Used for constants and environment flags (e.g., `IS_SERVER`, `MTU_LIMIT`).

---

## 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.

### If you change a public API method or add a new one

* [ ] Update the corresponding file in `docs/api/` (e.g., `packet.md`, `channel.md`, `satset.md`).
* [ ] Update `docs/guide/getting-started.md` if the change affects the onboarding flow.
* [ ] Add or update code examples that reference the method.

### If you add or modify a type in `Types/init.luau`

* [ ] Update `docs/api/types.md` with the new type signature and size.
* [ ] If the type has security implications (sanitization, bounds checks), update `docs/guide/security.md`.
* [ ] Run the benchmark suite and update `benchmark/Benchmarks.md` if performance characteristics change.

### If you change serialization or buffer handling

* [ ] Verify `docs/guide/architecture.md` still accurately describes the pipeline.
* [ ] Update `docs/guide/development-patterns.md` if the change introduces a new pattern or modifies an existing one.
* [ ] Update `docs/guide/security.md` if the change affects validation or sanitization.

### If you change error handling or dispatch behavior

* [ ] Update `docs/guide/security.md` (Listener Protection section).
* [ ] Update the relevant API doc (`packet.md` or `channel.md`) to reflect new error behavior.

### If you bump the version (maintainers only)

Version bumps and releases are handled by project maintainers, not contributors. The release workflow is triggered by pushing a `v*` tag to `main`.

Before creating the tag, update these three files:

* [ ] `CHANGELOG.md` — Add a new version header with changes.
* [ ] `wally.toml` — Update the `version` field.
* [ ] `src/init.luau` — Update the `VERSION` constant.

Then push the tag (e.g. `git tag v0.2.0 && git push origin v0.2.0`) to trigger the GitHub Release.

### If you change the benchmark harness

* [ ] Re-run benchmarks in Studio and update `benchmark/Benchmarks.md` with fresh data.
* [ ] Replace the raw JSON block at the bottom of `Benchmarks.md`.
11 changes: 11 additions & 0 deletions docs/guide/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ All incoming data is sanitized:
- **Type Checking**: Satset ensures that data is read according to the schema. If a client sends a payload that is shorter than expected for a given type, the read operation will fail safely.
- **NaN/Infinity Protection**: All float types (`f32`, `f64`, `Vector3`, `Vector2`, `CFrame`) pass through a sanitization layer that clamps `NaN` and `±Infinity` to `0` on both read and write paths.
- **Bounds Checking**: Satset ensures that buffer reads never exceed the length of the received data.
- **Variable-Length Protection**: Types like `string8`, `string16`, `array`, and `map` validate the declared length prefix against the remaining buffer before reading. A malicious client that sends a length of 255 on a 3-byte buffer will get an empty string instead of a VM crash.

## Listener Protection

All user-registered callbacks (both `Packet:listen` and `Channel:subscribe`) are wrapped in `xpcall`. If your callback throws an error, it will:

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.

This prevents a single broken game script from taking down the entire networking layer.

## Stateless Design

Expand Down