Skip to content
Engine

Core Concepts

Server and Client

Where Engine runs, how the client gets its own copy of Engine, which modules exist on which side, and how to write modules that work on both.

Two entry points

Engine has one entry point for each side:

SideRequireContains
ServerServerScriptService.EngineServer services and systems, shared services, all packages.
ClientReplicatedStorage.EngineClient services and systems, shared services, all packages.
Server Script
local Engine = require(game:GetService("ServerScriptService"):WaitForChild("Engine"))
LocalScript
local Engine = require(game:GetService("ReplicatedStorage"):WaitForChild("Engine"))

ReplicatedStorage.Engine does not exist in your place file. When a server starts, the Loader script boots Engine, and Engine builds the client copy: the client modules, the shared modules and the configuration clients need. Server-only code is never sent to clients. Use WaitForChild so client scripts wait until it exists.

Warning

On the server, always require ServerScriptService.Engine, never ReplicatedStorage.Engine. Requiring the client copy on the server loads a second, separate instance of every shared module, with its own state.

Realms

Each reference page shows where the module runs:

BadgeMeaning
SharedOne module that runs on both sides. Some members work on one side only; the page says which.
ServerServer only. Getting it from the client errors.
Server, ClientTwo halves with different APIs. Get each from its own side.

Examples of Server, Client modules: DataService (profiles on the server, a read-only copy of your own data on the client), EconomySystem (balances on the server, live balances on the client), ModerationSystem (sanctions on the server, your own moderation state on the client).

Modules that run on both sides

A ModuleScript in ReplicatedStorage that both sides require (shared remote definitions, for example) should pick the right entry point:

local RunService = game:GetService("RunService")

local Engine = if RunService:IsServer()
	then require(game:GetService("ServerScriptService"):WaitForChild("Engine"))
	else require(game:GetService("ReplicatedStorage"):WaitForChild("Engine"))

Trust nothing from the client

Everything an Engine client half sends to the server is checked again there: purchases, reward claims, reports and commands are validated, permission-checked and rate-limited on the server. Follow the same rule in your own code:

  • Define remotes with a Schema and a RateLimit in NetworkService.
  • Decide outcomes on the server (damage, rewards, positions) and send results to clients.
  • Never put secrets in modules the client can see: webhook URLs, keys and server-only settings belong in server-only configuration.

Configuration on the client

Only configuration modules that belong to a module present on the client (plus General) are copied to ReplicatedStorage.Engine. Server-only modules' settings, such as StatisticsService webhook URLs or CryptographyService keys, stay on the server. See Configuration.