News & Releases
Updates, architecture decisions, and release notes for Twill. Full commit history is tracked in CHANGELOG.md.
Tween moves the scale of a UIScale
Tween moves Scale as a property on any instance that is not a model, and refuses two destinations it used to accept.
Scale on a UIScale or a SpecialMesh is tweened like any other property, where it was refused. A destination with a part that is not finite, and a model scale of zero or below, are refused when the tween is built. No code needs changes.
Saves that outlast storage trouble
Store keeps a key whole when storage fails, and the Trade kit checks more before a trade is agreed.
A last write that storage failed is tried again until it lands, and a player who returns to the same server finds what they had. Trade takes readiness and agreement only for the offers a player was shown, and shows what an offered item carries. A config that was already faulty is refused at boot.
Inventory, Wallet and transactions
Twill adds the Inventory and Wallet kits, and Data.Transact keeps several changes to player data together or undoes them all.
The Inventory kit holds counted and one-of-a-kind items in named containers, and the Wallet kit holds currencies that never go below zero or past their ceiling. Data.Transact makes a spend and a grant as one, so a purchase cannot do only half. No code needs changes.
One Twill module per side
Twill installs as two modules named Twill, one per side, and adds traffic counting and the Trade kit.
The server half is a module named Twill, which checks that both halves come from the same release. Kits ship inside Twill, starting with Trade, and Net counts its traffic so bandwidth can be measured on a live server. Some code needs changes; see the migration notes.
Configs, teleports and leaderboards
Six new modules cover configs, asynchronous work, pooling, cross-server budgets, teleports and leaderboards, and player data can refuse a bad save.
Async, Pool, Config, Shared, Teleport and Board join the framework. A Validate check stops a bad state from being saved, and admin edits go through it too. Saves are merged, shutdown stops retrying sooner, and the suite passes under Server Authority. Some code needs changes; see the migration notes.
Replicated state that always arrives
Replicated state of any size reaches the client, and player data survives migrations and departures.
Each replicated key travels as its own call, so a large inventory no longer leaves a client without state for the whole session. Migrations skip new players and run on a copy, and a redelivered purchase is granted only once it is saved. Some code needs changes; see the migration notes.
Player data on Twill's own store
Data runs on Twill's own Store, and the console reads a key's history and holder.
The bundled ProfileStore package is removed, while the Data API and the stored format stay the same. The release fixes eight storage faults, including refused writes reported as saved and nothing saved on shutdown. Tokens issued before this release must be reissued.
Unions carry what they accept
A union refuses members it cannot tell apart, and hostile payloads no longer cost memory.
A union that could not tell two members apart used to pick one and lose data, so maps arrived empty and fractions arrived whole. Such a union is now refused where it is declared. Three security fixes close a memory exhaustion, a replication guard bypass and unmetered instance payloads.
Silent failures made visible
A rollback no longer replays migrations, and three silent failures now fail visibly.
Data saved by a newer server keeps its version, so a rollback can no longer run migrations twice. Compress.Decode no longer throws on altered payloads, oversized variable-width numbers are refused at the sender, and a tween on a destroyed target reports gone.
Compression without a bundled package
Compress is Twill's own code end to end, and never reads past the end of a stream.
The serializer and entropy coder are now Twill modules, with the API and byte format unchanged, so stored data still reads. Colours round to the nearest step, the dictionary rebuilds when it fills, and a hostile payload returns nil instead of reading past its bytes.
Out-of-range numbers are refused
A fixed-width number outside its range is refused at the sender instead of wrapped.
A client sending 256 for a byte used to arrive as 0, after the wrap had already slipped past every validator. Single values and arrays now refuse out-of-range numbers at the sender. A union with a fixed-width number member carries it instead of throwing.
Tweens on one shared loop
Twill's own Tween module moves every value in the game on one connection.
Tween moves properties, attributes, pivots, scales and table fields, sharing one connection that exists only while something plays. Destinations can curve through control points, and colours cross through Oklab. Refusal messages across every module now share one shape.
Faster codec, fewer allocations
The codec stops repeating work and allocates less on its busiest path.
Net.Any builds an error path only when an error is raised, instead of for every key it writes. Fixed-width arrays check bounds once per run, and CFrame packing no longer allocates. The API is unchanged.
Signals that never strand a thread
Twill's own Signal runs every listener and never leaves a waiting thread behind.
Destroying a signal wakes every thread parked in Wait. Each listener runs in its own xpcall, changes made mid-fire follow the engine's rules, and firing one listener is nearly twice as fast. The immediate-mode methods are removed; see the migration table.
Cleanup that always finishes
Twill's own Bag closes newest first and runs to the end even when a step fails.
A cleanup that raised used to strand every entry behind it and stop the bag for good. Bag closes each entry in its own pcall, newest first, in linear time. Scope.Trove is now Scope.Bag; see the migration table.
Networking on Twill's own wire format
Net has a built-in wire format, and a corrupt call costs only itself.
Every call carries the length of its own body, so a corrupt or refused call is skipped and the calls behind it still arrive. Remotes are declared with Net.Types, and the bundled Packet library is removed. Only declarations need to change.
Big numbers survive the console
The console keeps big numbers exact with the new big: prefix.
Values typed into playerdata were read as JSON, so numbers past what a double holds were silently rounded. The big: prefix writes them exactly, and the console prints big numbers in a form you can type back.
Seven console commands
Seven console commands expose state only Twill can see, with a setting to turn them off.
New commands report boot order, remotes, replication and log levels, and act on ranks, passes, saves and disputed rolls. TwillCommands controls which ones register. A security fix makes unban check rank, as kick and ban already did.
Subscriptions with an owner
Replication.Subscribe takes an owner, two defects are fixed, and every module's documentation is rewritten.
A subscription can close with its owner bag, so one made for a player no longer outlives them. Lifecycle no longer announces the departure of a player it never announced, and Schema no longer raises on an object rule with no fields.
Weighted draws and pathfinding
Two new modules, Chance and Navigation, and Random rounds that both can draw from.
Chance draws weighted entries with luck as an exponent, and accepts a Random round so draws stay auditable. Navigation drives every pathfinding agent from one loop, with a route budget and a give-up rule based on progress.
First release
Twill's first release: a modular Luau framework whose API is stable until the next major version.
Core modules cover lifecycle, networking, replication, player data, cleanup and logging, alongside utilities and game systems such as ranks, an admin console, monetization and provably fair randomness. Every module works on its own, with no build step.