Core Concepts
Services, Systems & Packages
How Engine organises its code into services, systems and packages, how you get each one, and when each tier is the right place to look.
Three tiers
Engine's code is split into three tiers. They differ in what they do and in how much they assume about your game.
| Services | Systems | Packages | |
|---|---|---|---|
| What | New engine capabilities | Complete game features | Pure building blocks |
| Get with | Engine:GetService(name) | Engine:GetSystem(name) | Engine:GetPackage(name) |
| Has state | Yes | Yes, often saved | No (only what you create) |
| Starts things when loaded | Sometimes (hooks, loops) | Yes (players, chat, data) | Never |
| Has settings | Yes | Yes | Some |
| Examples | DataService, NetworkService | EconomySystem, ModerationSystem | Promise, Signal, Octree |
Services
Services add things Roblox does not offer, or offers only as low-level APIs: session-locked data, validated remotes, mesh fracturing, parallel compute, a reactive UI framework. They are general-purpose: a service does not decide how your game works, it gives you the tools.
Systems
Systems are opinionated, finished features built from services: an economy with shops and trades, moderation with bans and commands, leaderboards with weekly resets. Use a system when it matches what you need; it saves weeks of work and has the edge cases handled.
Packages
Packages are plain Luau modules: data structures, maths, serialization, events, promises. They have no side effects, so getting a package never starts anything. Engine's services and systems are built from these packages, and your code can use them too.
Getting a module
Every getter returns the module itself, ready to use. The first call for a name loads the module:
local Engine = require(game:GetService("ServerScriptService"):WaitForChild("Engine"))
local SpatialService = Engine:GetService("SpatialService") -- loaded now
print(Engine:GetService("SpatialService") == SpatialService) -- true- Modules are cached: every later call with the same name returns the same table and loads nothing.
- A misspelled name errors right away:
Engine: no service named "DataServcie" exists. - Getting a server-only module from the client errors with a hint, and so does getting a client module from the server.
To see when each module loads and how long it takes, turn on LogServiceLoads in the General configuration.
Lazy loading
Nothing in Engine runs until you get it. A game that only uses DataService and NetworkService never loads AudioService, never hooks the chat and never creates moderation remotes. This keeps start-up fast and memory low.
Modules that depend on each other load each other: getting EconomySystem also loads DataService, LeaderboardSystem and StatisticsService, because it uses them.
Note
Some systems start working as soon as they load. For example, ModerationSystem begins loading player records and enforcing bans the moment you first get it. Get such systems early, in a server script that runs at start-up, so they are active before players join.
Where to find what
| You want to... | Look at |
|---|---|
| Save player progress | DataService |
| Send data between server and client | NetworkService |
| Sell products and passes | MonetizationService |
| Add coins, shops and daily rewards | EconomySystem |
| Give players items, equipment and crafting | InventorySystem |
| Ban, mute and kick | ModerationSystem |
| Show top players | LeaderboardSystem |
| Build UI | UIService with State |
| Wait for something | Promise |
| Create your own events | Signal |
| Clean up after a player or round | JunkService or Bin |