Optional server scripting
Build elevators, routes, states, buttons and triggers through the plugin interface without writing scripts. The server API is an optional integration for developers who want their own game logic to activate a saved system.
Get started
Build elevators, routes, states, buttons and triggers through the plugin interface without writing scripts. The server API is an optional integration for developers who want their own game logic to activate a saved system.
Before copying an example
Apply your system first. Add a normal Script inside ServerScriptService and test in Play. Use server code for these examples, not a LocalScript.
The API calls stay the same. The model paths and action values must match your own place. The examples do not create or configure a system.
| Example | Replace with |
|---|---|
workspace.MyCabin | The cabin Model you configured and applied as an Elevator |
"5" | The requested floor's position in your configured floor list, written as a string |
workspace.MyDesk | The object you configured and applied with Multiple states |
"Standing" | The exact name of one of that object's saved states |
If your cabin is inside a folder, use its complete path, such as workspace.Building.ElevatorCabin. Names with spaces can use brackets, such as workspace["My Cabin"]. Select the system's target Model or Part, not a decorative part, button or fixed frame.
Request an elevator floor
This example requests the fifth configured floor. Your elevator must already contain that floor. Put this call inside the server event that should start the trip. At the top level of a Script, it runs when that Script starts.
local ServerScriptService = game:GetService("ServerScriptService")
local API = require(ServerScriptService.VoidInteractSystems.SystemAPI)
local cabin = workspace.MyCabin
local accepted, reason = API.activate(cabin, "5")
if not accepted then
warn("Elevator request declined:", reason)
endAn accepted request is not a completed trip. An elevator may queue the request. Use the Arrived event when your next action depends on arrival.
Select a named state
Use the same API module and replace the target and action. Here the saved state is named Standing.
local ServerScriptService = game:GetService("ServerScriptService")
local API = require(ServerScriptService.VoidInteractSystems.SystemAPI)
local desk = workspace.MyDesk
local accepted, reason = API.activate(desk, "Standing")
if not accepted then
warn("State request declined:", reason)
endRead state and listen for arrival
API.getState(target) returns the saved state value, or nil when no matching configuration is found. It does not return a table of floor, queue and door information. Register the listener before requesting a trip if you need to observe that trip's arrival.
local ServerScriptService = game:GetService("ServerScriptService")
local API = require(ServerScriptService.VoidInteractSystems.SystemAPI)
local cabin = workspace.MyCabin
print(API.getState(cabin))
local connection = API.onChanged(function(target, event, value)
if target == cabin and event == "Arrived" then
print("Arrived at floor", value)
end
end)
script.Destroying:Connect(function()
connection:Disconnect()
end)Disconnect the listener when your integration no longer needs it. The example also disconnects it when its Script is destroyed.
Supported actions
| System | Action |
|---|---|
| Elevator | A floor index as a string, such as "5" |
| Multiple states | An exact saved state name, such as "Standing" |
| Multi-step motion | "Open", "Close", "Reverse" or "Next" |
| Connected mechanisms | "Next" |
| Ordered inputs | Submit the action names configured in the required order |
| Player drag interaction | Use the player's drag input instead of API activation |
Requests from players
Pass the actual Player as the third argument to API.activate(target, action, player) when evaluating that player's key or team conditions. Omitting it does not supply a player identity.
Your server integration must validate any RemoteEvent it exposes, including the permitted target, action, player access, distance and request rate. Passing a Player does not replace those checks. Do not forward arbitrary client-selected instances or actions into the API.
Saved runtime scripts remain readable. Updating the plugin does not silently overwrite custom runtime edits.