Start typing to search packages!
sawdust
By @griffin-dalby
Roblox
Mirrored from WallyThis version ships no README. Showing the README from v1.4.0, mirrored from wally.
๐ฒ Sawdust Framework
Sawdust is a lightweight, modular framework for Roblox developers who want clarity, control, and smart abstractions, without the bloat ๐
๐ Built with love by Griffin Dalby
๐ Designed for efficient, easy-to-read, and easy-to-use code - made for devs who hate reading docs.
โจ Features
-
๐ Service Injection System
Build, inject, and manage services with dependency resolution. -
๐ Smart Networking
Networking w/ a custom protocol for secure returns from each side, all with a friendly interface. -
๐ฆ CDN System
Efficient asset delivery with preload batching and efficient caching. -
๐ฃ Signal Emitters
Embeddable event behavior for services or general-purpose modules. -
๐ Cache API
Stackable cache management built for structure, and speed. -
๐งน Maid Utility
Clean up anything, connections, callbacks, instances, all with tag-based logic. -
โ And much, much more planned
I hope to get as much quality of life features as possible. -
๐ณ Lignin
Lignin is a plugin being developed to aid even further with sawdust development. You'll be able to gradually create networking channels and events/functions, and many more things All of these will create automatic type metadata for a dynamic feeling typechecking experience including assetIds and networking event names.
๐ Quick Start
Network from server <-> client
--> In StarterCharacterScripts.Mechanics
local networking = sawdust.core.networking
local mechanics = networking.getChannel('mechanics')
mechanics.skill:useMiddleware('after', 1, function(pipeline)
--> I'll fill this all out soon I just want to push this for the rodev game jam tmr I love this module
end)
mechanics.skill:with() --> Returns a new call
:intent('use')
:data('fireball', mousePosition)
:timeout(4)
:invoke() --> Returns a promise
:finally(function(req)
local intent, data = req.intent, req.data
local didUse = (data[1]==true)
end)
:catch(function(issue)
warn('Issue with skill: fireball')
warn(issue)
end)
--> In ServerScriptService.Mechanics
local networking = sawdust.core.networking
local mechanics = networking.getChannel('mechanics')
mechanics.skill:handle(function(req, res)
local intent, data = req.intent, req.data
res.intent('success')
res.data('Whatever you\'d need')
res.send() --> Send the data back
end)
Build a Service
--> In ServerScriptService.SawdustServices
local builder = sawdust.builder
local services = sawdust.services
services:register(builder.new('OtherService')
:init(function(self, deps) --> 'init' runtime phase
self.data = 'Hello!' --> Set OtherService.data to 'Hello!'
end)
:method('methodName', function(msg) --> Create a new method (OtherService.methodName(msg))
print(`Method was called, message: "{msg}"`)
end)
:inject('init', function(self, deps) --> Inject function into 'init' runtime phase
print('Injection into OtherService success!')
end))
services:register(builder.new('ExampleService')
:dependsOn('OtherService') --> Depend on the OtherService
:init(function(self, deps) --> :init() phase
self.otherService = deps.OtherService
end)
:start(function(self) --> :start() phase
print(`Data from other service: "{self.otherService.data}"`)
self.otherService.methodName('I called the function from ExampleService!')
end))
services:resolveAll() --> :init() all services
services:startAll() --> :start() all services
--[[
This should print this, in order:
'Injection into OtherService success!'
'Data from other service: "Hello!"'
'Method was called, message: "I called the function from ExampleService!"'
--]]
๐ง Philosophy
Sawdust is designed to:
- Give maximum control to the developer
- Encourage clean runtime logic
- Reduce boilerplate
- Promote discoverabiliy via tooling & naming clarity
- Minimize documentation checks
You get injection + dependency management without losing Luau's flexibility.
๐ Installation
- Drop the Sawdust folder into
ReplicatedStorage - Access it on server or client via:
local sawdust = require(game:GetService('ReplicatedStorage').Sawdust)
- Access the implementations like:
local sawdust = require(game:GetService('ReplicatedStorage').Sawdust)
local services = sawdust.services
local networking = sawdust.core.networking
local maid = sawdust.util.maid
๐งช Tests
I've built unit tests for sawdust and all of the implementations (this may not be ALL implementations at time of reading, I may still be working on some.)
๐ Documentation
You can find full documentation & quick start examples + implementation tutorials Here!
๐ Modules
Services
| Module | Description |
|---|---|
builder | Service definition w/ injections & dependencies |
services | Service resolver, runner, and state tracker |
Core
| Module | Description |
|---|---|
networking | Networking system modeled after NodeJS' Express |
promise | Promise system modeled after NodeJS |
signal | Simple event emitter system |
cache | Fast, structured memory management |
cdn | Asset delivery w/ preload features |
Util
| Module | Description |
|---|---|
maid | Cleanup utility for tagged objects |
debounce | Timed and interactable debounces |
enum_map | "Maps" enums to human readable, and back. |
states | Simple dynamic state management |
timer | Heartbeat wrapper w/ decay and start/stop control |
uuid | Customizable UUID generator |
๐ License
Sawdust is licensed under Apache 2.0.
Contributions are welcome! While not required by the license, if you would like to improve Sawdust or find bugs, please consider contributing or filing a issue report, it means a lot more than you think <3
Package Details
Install command (Click to copy)
Version
1.6.0
License
Apache-2.0
Safe for commercial use
Modified files must carry a notice of changes. If the package ships a NOTICE file, its attributions must be preserved.
Automated license review โ not legal advice.
