Forest Logo
search
package_2

sequenaplus

By @qscythee

Roblox

Mirrored

Sequena+

Sequena+ is the client-facing name for this redesigned networking library. The installed Wally package and Luau module are qscythee/sequenaplus and Sequena respectively. Generated by Rojo 7.7.0.

Getting Started

To build the place from scratch, use:

rojo build -o "SequenaPlus.rbxlx"

Next, open SequenaPlus.rbxlx in Roblox Studio and start the Rojo server:

rojo serve

Wally & pesde Support,

wally add qscythee/sequenaplus@0.2.0

(same for pesde)

For more help, check out the Rojo documentation.

Usage Example

local Data = Sequena.Data

local MyEvent = Sequena.Define(
    {
        Name = "Action",
        Reliable = true,
        UseDelta = true,
    },
    Data.U8,
    Data.Vector3,
    Data.String
)

Packets must have non-empty names. Names use deterministic IDs, so adding or reordering definitions does not change the wire ID. Names must be unique and stable between the server and client; packet names are part of the network protocol.

For more help, join this Discord Server Link

Documentation site

The VitePress documentation site lives in docs/. To develop or preview it:

cd docs
npm install
npm run dev

Build it with npm run build. The main branch deploys the generated site to GitHub Pages through .github/workflows/docs.yml.

Functional library tests

The repository includes a client/server functional test harness in tests/functional/ and integration.project.json. Sync it with Rojo:

rojo serve integration.project.json

Open a place in Studio, connect the Rojo plugin, and press Play. The server and client runners report assertions through the Roblox TestService output. The harness covers primitive values, Roblox values, tables, structs, composites, dynamic values, delta packets, runtime validation, and request/response packets. Performance benchmarking lives separately under benchmarks/networking/.

Networking benchmark

benchmarks/networking/ is an isolated benchmark project. It has its own Rojo project and Wally manifest, and reports engine-observed send/receive Kbps median and peak, message tension, RTT, loss, and sampled CPU time. See its README for setup and the transport list.

Configuration

Configuration can be overridden after requiring the Sequena module and before defining packets. Unknown sections/options are rejected.

Sequena.Configure({
    Security = {
        MaxStringSize = 4096,
        MaxArraySize = 500,
    },
    Network = {
        MaxBatchSize = 32768,
    },
})

Configuration is locked after the first packet is defined so all packet serializers use the same limits.

Incoming payloads are bounds-checked before reads, compressed/decompressed payload sizes are limited, oversized strings/buffers/tables are rejected, unknown packet/type IDs are rejected, and server inbound traffic is rate limited per player.

Data Types

Use Sequena.Data for primitive schema values instead of writing type-name strings directly:

local Data = Sequena.Data

local Packet = Sequena.Define({
    Name = "Inventory/Updated",
}, Data.U8, Data.Vector3F16, Data.String)

Composite types such as Data.Array, Data.Optional, Data.Literal, Data.Or, Data.And, Data.Map, Data.Struct, Data.Enum, and Data.Bitfield are also available.

The public table is assembled internally from focused datatype modules under src/Datatypes: Numbers, Primitives, Roblox, RobloxSerializers, Dynamic, DynamicSerializers, Checks, Resolver, and Composites. Datatype modules register their serializers/deserializers against the active buffer context; composite builders use the same context for schema resolution and bounds enforcement.

Typed packet APIs

Sequena+'s public schema fields carry their Luau value type. The config-first vararg form provides precise positional inference for every packet field:

local Data = Sequena.Data

local Request = Sequena.Define({
    Name = "Inventory/Get",
}, Data.U32, Data.String)

Request.OnServerEvent:Connect(function(Player, UserId, ItemName)
    -- Player: Player, UserId: number, ItemName: string
end)

Request:Fire(42, "Potion")

Packet direction is enforced at runtime. Clients use Fire and OnClientEvent; servers use FireClient, the broadcast/collection fire methods, and OnServerEvent. Calling an API from the wrong context throws.

Request/response packets are client-to-server only. The server binds one handler and the client invokes it with Fire:

local GetItem = Sequena.Define({ Name = "Inventory/GetItem" }, Data.U32)
    :SetRequestResponse(Data.String)

-- Server
GetItem:BindServerInvoke(function(Player, ItemId)
    return "Potion"
end)

-- Client
local ItemName = GetItem:Fire(42)

TypedPacket is also exported when an explicit packet contract annotation is useful:

local Packet: Sequena.TypedPacket<(number, string)> = Sequena.Define({
    Name = "Inventory/Updated",
}, Data.U32, Data.String)

Struct accepts a keyed schema and infers the complete payload table:

local Item = Data.Struct({
    Id = Data.U32,
    Name = Data.String,
})

Keyed struct fields are serialized in sorted key order. Use OrderedStruct when the wire order must be explicit; Data.Field retains each literal field name so the complete payload table is still inferred:

local OrderedItem = Data.OrderedStruct({
    Data.Field("Id", Data.U32),
    Data.Field("Name", Data.String),
})

Or accepts between 2 and 25 schema options and infers their Luau union. Sequena+ writes a one-byte option tag followed by the matching payload:

local StringOrNumber = Data.Or(Data.String, Data.F32)
-- Descriptor<string | number>

And combines between 2 and 25 Struct or OrderedStruct schemas with distinct field names and infers their Luau intersection:

local Item = Data.And(
    Data.Struct({ Id = Data.U32 }),
    Data.Struct({ Name = Data.String })
)
-- Descriptor<{ Id: number } & { Name: string }>

Define carries all positional schema fields through a generic type pack, so there is no builder-specific inference or arity limit. Runtime schemas remain unchanged; the generic typing improves editor and type-checker feedback.

Package Details

Install command (Click to copy)


Version

0.2.0

License

MIT

check_circle

Safe for commercial use

Automated license review — not legal advice.