DataModel and hierarchy
Every place has a DataModel root named game. Services are direct children of the DataModel. World objects and character models belong in Workspace. Player account/session instances belong in the Players service, while each Player's Character model is parented to Workspace.
game
Workspace
Map
Character
Players
Player
Backpack
PlayerScripts
Lighting
ReplicatedStorage
ServerStorage
ServerScriptService
StarterGui
StarterPack
StarterPlayer
SoundService
ServerStorage and ServerScriptService are server-only. Their private contents are filtered out before a published place is sent to a browser.
Poieia Lua runtime
Poieia uses a Lua-like scripting runtime built for the Poieia object model. Script, LocalScript, and ModuleScript source is stored in the place hierarchy. Client scripts run in the browser runtime. Server scripts under ServerScriptService run in the Python game-server runtime.
The implemented language surface covers the common control-flow, function, table, iteration, service, instance, signal, and ModuleScript patterns documented here. It is not full Lua 5.x or full Luau compatibility, so code should target the Poieia API documented on this page.
local part = Instance.new("Part")
part.Name = "Demo"
part.Position = Vector3.new(0, 4, 0)
part.Size = Vector3.new(6, 1, 6)
part.Parent = workspace
print(part:GetFullName())
Supported scripting patterns
localvariables and assignmentif,elseif,else,while,repeat, anduntil- numeric
forloops andpairs/ipairsloops - local and global functions, anonymous functions, callbacks, and signal connections
- array-style and keyed table literals
break,continue, andreturn- ModuleScript
require()with cached results
Studio Lua IDE
Double-click a Script, LocalScript, or ModuleScript in Explorer to open it in the center editor. The editor includes syntax highlighting, line numbers, autocomplete, live diagnostics, and error navigation.
| Action | Shortcut or behavior |
|---|---|
| Autocomplete | Ctrl+Space, or type at least two characters |
| Indent | Tab |
| Check script | Use the Check button to run static diagnostics |
| Apply script | Use Apply after diagnostics pass |
| Go to error | Click a diagnostic to move the caret to that line |
Autocomplete includes core globals, services, constructors, common Instance methods, signals, and standard libraries. Diagnostics catch unmatched blocks, common malformed statements, and transpilation errors before a script is applied.
Globals and standard libraries
| Name | Purpose |
|---|---|
game | Current DataModel and service lookup. |
workspace | The Workspace service. |
script | The currently executing script instance. |
Instance | Instance.new(className, parent). |
Vector3, Vector2, Color3, UDim2 | Core value types. |
print, warn | Runtime output. |
task | Client runtime scheduling helpers such as wait, delay, defer, and spawn. |
math | Common numeric functions and constants. |
string | len, lower, upper, sub, find, format, and rep. |
table | insert, remove, sort, concat, find, and unpack. |
tonumber, tostring, type, pairs, ipairs, next | Conversion and iteration helpers. |
assert, error, pcall, xpcall | Error helpers. |
require | Executes and caches a ModuleScript. |
Instance API
Instances expose Name, ClassName, Parent, class properties, named children, and the methods below.
| Method | Behavior |
|---|---|
GetChildren() | Returns direct children. |
GetDescendants() | Returns all descendants. |
FindFirstChild(name, recursive) | Finds a child by name. |
WaitForChild(name, timeout) | Waits for a named child in runtimes that support waiting. |
IsA(className) | Checks the instance class. |
GetFullName() | Returns the hierarchy path. |
Clone() | Deep-clones the instance tree. |
Destroy() | Removes the instance from its parent. |
ClearAllChildren() | Destroys direct children. |
GetPropertyChangedSignal(name) | Returns a property signal. |
Rig classes
Character rigs use Humanoid and Motor6D instances. Current built-in states include idle, walk, jump, fall, swim, climb, and sit. Seat and TrussPart are available for world interaction.
Services
Use game:GetService("ServiceName"). Services are separate from Workspace and are direct children of the DataModel.
| Service | Purpose |
|---|---|
| Workspace | Replicated 3D world and character models. |
| Players | Player session instances, PlayerAdded, PlayerRemoving, GetPlayers, GetPlayerByUserId. |
| Lighting | World lighting configuration. |
| ReplicatedStorage | Shared client/server container and RemoteEvent instances. |
| ServerStorage | Server-only object container. |
| ServerScriptService | Server-only Script container. |
| StarterGui | Developer ScreenGui hierarchy copied into the player UI runtime. |
| CoreGui | Poieia-owned CoreUI. |
| StarterPack | Default Gear copied into each joining player's Backpack. |
| StarterPlayer | Character defaults, StarterPlayerScripts, and StarterCharacterScripts. |
| SoundService | Sound and audio configuration. |
| RunService | Runtime mode and frame/update signals on the client. |
| HttpService | JSON helpers and server-routed outbound HTTP. |
| MarketplaceService | Marketplace integration surface. |
| DataStoreService | Reserved persistent server storage API surface. |
| GroupService | Group integration surface. |
| GuildService | Guild integration surface. |
Players, characters, gear, and hats
When a client joins a live server, the server creates a Player under Players and a Character model under Workspace. The Player references its Character.
Workspace
Adrian
Humanoid
HumanoidRootPart
RootJoint
Head
Neck
Torso
Left Shoulder
Right Shoulder
Left Hip
Right Hip
Left Arm
Right Arm
Left Leg
Right Leg
EquippedGear
Players
Adrian
Backpack
PlayerScripts
StarterPack gear is copied into Backpack. Equipped gear moves into Character. Worn catalog hats are represented in the avatar state. A player can drop a worn hat into the current live server and another nearby player can pick it up for that session.
The renderer poses Motor6D joints for idle, walk, jump, fall, swim, climb, and sit states.
WebSocket multiplayer
Published games use /ws/games/{gameId}. Each connection joins a live server room with its own server ID and max-player limit. If a room is full, the normal Join flow can create another room.
The WebSocket carries joins, leaves, character movement, motion state, gear state, avatar updates, dropped hats, chat, report actions, and RemoteEvent traffic. Sending the explicit leave message removes the Player from the room before the socket closes.
RemoteEvent
Place RemoteEvent objects in ReplicatedStorage. LocalScripts call FireServer. ServerScripts receive OnServerEvent with the Player as the first argument. ServerScripts can call FireClient or FireAllClients.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Event = ReplicatedStorage:WaitForChild("Action")
Event.OnServerEvent:Connect(function(player, value)
print(player.Name, value)
Event:FireAllClients(value)
end)
The bundled room registry is in-process. If you deploy more than one game-server worker or machine, add a shared room/message broker before distributing WebSocket clients across those workers.
Signals and events
Signals support Connect, Once, Wait where implemented, and internal Fire. Instances expose Changed, ChildAdded, ChildRemoved, and property signals. Interactive UI instances expose Activated and MouseButton1Click. Humanoid exposes StateChanged in the player runtime.
local button = game:GetService("StarterGui"):FindFirstChild("PlayButton", true)
if button then
button.Activated:Connect(function()
print("Activated")
end)
end
Developer UI and CoreUI
Developer UI belongs under StarterGui and may use ScreenGui, Frame, TextLabel, TextButton, ImageLabel, and ImageButton. CoreUI is owned by Poieia and provides chat, player list, user toolbar, reports, and Gear hotbar.
Developer UI and CoreUI are separate hierarchies. Experience scripts should not replace CoreUI.
Poieia Studio
Studio uses a desktop-style layout with ribbon tools at the top, Toolbox on the left, Explorer and Properties on the right, document tabs in the center, and Output at the bottom.
| Control | Action |
|---|---|
| Right mouse drag | Orbit the editor camera. |
| Middle mouse drag | Pan. |
| W A S D | Move camera. |
| Q / E | Move camera down/up. |
| Mouse wheel | Dolly camera forward/backward. |
| F | Focus selected object. |
| Test | Runs the current in-memory draft without publishing. |
| Stop | Sends the test player a forced-exit message, closes the test frame, and restores the editor viewport. |
| Save Draft | Stores the editable version only. |
| Publish | Promotes the saved draft to the live version. |
OBJ, glTF, GLB, and STL imports are accepted by the current asset import flow. Accessories, models, UI, scripts, Gear, and ordinary instances all use the same Explorer hierarchy.
HttpService and Cloudflare routing
Browser clients do not directly issue arbitrary external HTTP requests through Poieia's developer HTTP service. Outbound experience requests are routed through the game server, then the Poieia API, then the configured Cloudflare Worker.
POIEIA_GAME_SERVER_KEY=long-random-server-secret POIEIA_CLOUDFLARE_PROXY_URL=https://your-worker.workers.dev POIEIA_CLOUDFLARE_PROXY_SECRET=worker-shared-secret
The Worker validates the shared secret, strips sensitive headers, rejects obvious private/local targets, and limits response size.
Web API
GET /v1/health
GET /v1/instance-types
GET /v1/services
GET /v1/users/{username}
GET /v1/users/id/{user_id}
GET /v1/games
GET /v1/games/{id}
GET /v1/games/{id}/servers
GET /v1/games/{id}/passes
GET /v1/catalog
GET /v1/economy
GET /v1/groups/{id}
GET /v1/guilds/{id}
POST /v1/games/{id}/http
The HTTP proxy endpoint is server-only and requires the internal game-server key.