Skip to content

Module reference

Twill installs as two ModuleScripts, both named Twill. Both are required.

ModuleContents
ReplicatedStorage.TwillThe modules a client is allowed to see, the client half of each kit, and the root table.
ServerScriptService.TwillThe server half, and the server half of each kit. Never replicated.

The root table resolves modules lazily, so a single require reaches everything:

local Twill = require("@game/ServerScriptService/Twill")
Twill.Log -- shared
Twill.Data -- server only
Twill.Kits.Trade -- a kit, its server half on the server

Requiring a module directly works too, and is the better choice inside a client module that must not wait. See Admin for the one case where it is required rather than preferred.

The root table also carries Twill.Version, which is the quickest way to confirm an install answered at all.

Available on the server and the client.

ModuleWhat it does
LifecycleService discovery, boot order, and the player pipeline.
NetDeclaring remotes, and serving them with metering and validation.
ReplicationPublishing server state and reading it on the client.
ScopeCleanup bags tied to a player, a character, or a life.
BagThe cleanup container those bags are, and how it closes.
SignalEvents of your own, where every listener runs.
LogScoped, level-filtered logging.
SchemaDeclarative validation for values you did not write.
LimitToken buckets, per-player allowances, and log throttling.
LoopRepeating work, delays, and spreading a list across frames.
WatchFollowing a set of instances as it changes.
FormatNumbers and durations turned into readable text.
SerializeRoblox values in a shape a DataStore accepts.
CompressLarge values made small and safe to send as text.
TreeInstances described as data and built in one pass.
ErrorOne listener for every unhandled script error.
BigNumberExact whole numbers with no ceiling.
ChanceWeighted draws, and the odds behind them.
TweenValues moved over time, every one of them on a single loop.
AsyncYielding work with a deadline, run together, or tried again.
PoolParts and models reused rather than cloned and destroyed.
NavigationAgents that walk somewhere, and one loop driving all of them.
AuthorizationRanks, and the questions that depend on them.
AdminAn in-game command console built on Cmdr, with nine commands of its own.

Requiring any of these from a client fails with a message naming the module.

ModuleWhat it does
DataPlayer data, with versioning, migrations, and branches.
StoreThe key held by one server at a time, under Data.
MonetizationDeveloper products and passes, granted once.
LeaderstatsThe Roblox player list, filled from replicated state.
FilterPlayer-written text made safe to show.
RandomUnpredictable draws, and rolls a player can audit.
TokenSigned text that proves nobody edited it.
SharedCross-server messages and memory store maps, within one budget.
ConfigLive experience configs, with a default for every key.
TeleportPlayers sent between servers, with carried data kept off the client.
BoardA leaderboard read from a cache and written in batches.

A kit covers one kind of game feature rather than every game. Kits ship inside Twill and load only when named, as Twill.Kits.<Name>: the server half on the server, the client half on a client.

KitWhat it does
InventoryItems a player holds, in named containers, changed whole or not at all.
WalletCurrencies a player holds, which never go below zero or past their ceiling.
TradeTrades between two players on one server that cannot duplicate or lose an item.

Four modules span both sides under one name. Net, Replication, Authorization, and Admin each have a server half that is not replicated, and their pages mark every member that only exists there.

Every member on every page carries the sides it exists on.

BadgeMeaning
[Server] | [Client]Available on both.
[Server]Calling it from a client fails.
[Client]The receiving half of a module whose publisher is server-side.

Signatures are written as Luau type annotations, taken from the source.

function Limit.PerPlayer(rate: number, burst: number?): Allowance

A trailing ? means the argument may be omitted or the return may be nil. self appears in a signature only where the member is called with a colon.

Generic parameters such as <T> mean the module hands back whatever type you put in. Nothing is checked at runtime by the generic itself.