Pluto API Documentation
FAQ
Q: What is Pluto?
A: Pluto is a superset of Lua with a focus on general-purpose programming.
More On Pluto
Q: Where are Pluto scripts stored?
A: You can place Pluto script files (.lua, .pluto) here:
%appdata%/spooky/scripts/
and start them from Settings -> Pluto
Q: How do I learn Pluto?
A: You can learn Lua first which will teach you 90% of Pluto
Learn Lua
Q: Where do I get started?
A: You can base your first scripts off of developer made example scripts
View Example Scripts
Q: Why did my old loop script suddenly stop?
A: Scripts now run on the game thread, one step per frame, and cooperate with the game. A script that loops without ever calling Yield() is aborted after roughly 100ms so it can never freeze the game. Add Yield() inside any long loop.
Functions
LOG(?number LogState = LogState.Info, string Content)
Log(?number LogState = LogState.Info, string Content)
allows you to print information to the console, LogState can be any of the following:
LogState.Brand or 1,
LogState.Info or 2,
LogState.Error or 3,
LogState.Event or 4,
LogState.Warning or 5
Content is a string that contains your message.
void LOG(LogState.Info, "Hello World!")
Notify(string Content, ?number Duration = 3)
allows you to notify information to the screen, will appear in the top right.
Content is a string that contains your message, Duration is how long (in seconds) it stays on screen.
void Notify("Hello World!")
void Yield(?number milliseconds = 1)
cooperatively pauses the script: it hands control back to the game and resumes after the provided number of milliseconds (or on the next frame if none is provided).
Because scripts run on the game thread, use Yield() inside any long or repeating loop, otherwise the script is aborted after ~100ms.
while true do
-- do a little work
Yield(100) -- resume in 100ms
end
string GetGameVersion()
returns the current Phasmophobia version as a string
string GetSpookyVersion()
returns the current Spooky version as a string
number GetAccountTier()
returns the Spooky account tier of the current user as any of:
AccountTier.Premium or 0,
AccountTier.Standard or 1,
AccountTier.Free or 2
string GetAccountName()
returns the Spooky account nickname of the current user
bool IsGameLoaded()
returns a boolean corrosponding to if the game is properly loaded in, we recommend using this before interacting with world objects or trying to find them, otherwise crashes can occur.
bool IsInMainMenu()
returns if you are currently in the main lobby / main menu
bool AmIHost()
returns if you are the host of the current Phasmophobia room
string GetSceneName()
returns the name of the currently active Unity scene
string GetMapName()
returns the friendly name of the current map (e.g. "6 Tanglewood Drive")
number GetPing()
returns your current latency to the Photon server, in milliseconds
number GetPlayerSanity()
returns your current sanity (0 to 100)
void SetPlayerSanity(number sanity)
sets your current sanity (0 to 100)
number GetTimeScale()
void SetTimeScale(number scale)
get / set the Unity time scale (1 is normal speed)
number GetDeltaTime()
returns the current frame delta time in seconds
void Teleport(number x, number y, number z)
void Teleport(Vector3 position)
teleports the local player to the given world position
userdata GetObjectByName(string Name)
returns a CComponent userdata (see below) by finding an object that contains the provided name string
userdata GetObjectByTypeName(string TypeName)
returns a CComponent userdata (see below) by finding the first object of the provided component type, e.g. "Player"
table GetObjectsOfType(string TypeName)
returns a table containing every object of the provided component type, e.g. "Door"
for _, door in ipairs(GetObjectsOfType("Door")) do
if door:IsValid() then
LOG(LogState.Info, door:GetName())
end
end
userdata GetLocalPlayer()
returns a CComponent userdata (see below) that contains the local players world object
table GetPlayerList()
returns a table of tables, one per player in the room, each containing:
player.Name, -- string
player.ActorNumber, -- number
player.IsHost, -- bool
player.IsMe, -- bool
player.IsDead, -- bool
player.Position -- Vector3
string GetServerAddress()
returns the current Photon server IP Address, or an empty string
void SetCursorVisible(bool visible)
sets if the Phasmophobia cursor should be visible
void SetCursorLockState(number state)
sets if the Phasmophobia cursor should be restricted to the window, or even the centre of the screen, state can be any of:
LockStates.Non or 0, -- can be moved anywhere
LockStates.Locked or 1, -- locked to the centre of the screen
LockStates.Confined or 2 -- locked to the window
number GetCursorLockState()
returns the current cursor lock state (see above)
UserDatas and Tables
Vector3
a Vector3 table contains 3 floats (x, y, z) that typically represent a position
Vector
The Vector class contains functions to assist with Vector math
All Vector math functions can be used with any Vector type as they are dynamic
For example if your table contains just one "x" field, it will do the math just for it.
If your table contains "x", "y", "z", and "w", it will do the math for all of them.
If the second vector does not contain any/some of those elements then that element will be skipped
VectorType Vector.GetType(table Vector)
VectorType.Non or 0, -- not a vector
VectorType.V1 or 1, -- vector containing x
VectorType.V2 or 2, -- vector containing x and y
VectorType.V3 or 3, -- vector containing x, y, and z
VectorType.V4 or 4, -- vector containing x, y, z, and w
table Vector.New(?number x = 0, ?number y = 0, ?number z = 0, ?number w = 0)
table Vector.Add(table VectorA, table VectorB)
If the second vector is smaller than the first, the first's elements will be added, example:
local VecA = Vector.New(1, 0, 1)
local VecB = Vector.New(5, 0)
Notify(Vector.ToString(Vector.Add(VecA, VecB))) -- Result: X: 6, Y: 0, Z: 1
table Vector.Multiply(table VectorA, table VectorB)
Similar logic to Add
table Vector.Multiply(table VectorA, number Multiplier)
table Vector.Divide(table VectorA, table VectorB)
Similar logic to Add
table Vector.Divide(table VectorA, number Divisor)
Quaternion
a Quaternion table contains 4 floats (x, y, z, w) that typically represent a rotation
CComponent
a CComponent userdata represents an object or an objects component in the world, it has the following functions:
string GetName()
returns the name of the object, or nil if the object no longer exists
bool IsValid()
returns true while the underlying object still exists, always check this before using a handle you stored a while ago
userdata GetTransform()
GetTransform returns a CTransform userdata (see below)
userdata GetGameObject()
returns a CGameObject userdata (see below)
userdata GetComponent(string TypeName)
returns a CComponent userdata for the first component of the given type on this object, or nil
table GetComponents(string TypeName)
returns a table of every component of the given type on this object
void SetName(string NewName)
renames the object
void Destroy()
destroys the object
any CallMethod(string MethodName, ...)
invokes a method on this component and discards the return value. It accepts up to 3 arguments, each a number, bool, string, or another object userdata.
number CallMethodFloat(string MethodName, ...)
number CallMethodInt(string MethodName, ...)
bool CallMethodBool(string MethodName, ...)
string CallMethodString(string MethodName, ...)
the same as CallMethod, but return the method's result as the matching type. Use these for in-game getters (e.g. renderer:CallMethodBool("get_enabled")).
you should consult game data to find these methods, and ensure the arguments you pass and receive are valid.
CGameObject
a CGameObject userdata represents a game object in the world (returned by CComponent:GetGameObject()), it has the following functions:
string GetName()
bool IsValid()
userdata GetTransform()
userdata GetComponent(string TypeName)
table GetComponents(string TypeName)
bool GetActive()
void SetActive(bool active)
any CallMethod(string MethodName, ...)
number CallMethodFloat / number CallMethodInt / bool CallMethodBool / string CallMethodString
as with CComponent, the CallMethod family invokes an in-game method (up to 3 arguments) and the typed variants return the result.
CTransform
a CTransform userdata is a type of component which holds an objects position, scale, and rotation, it has the following functions:
string GetName()
userdata GetGameObject()
GetGameObject returns a CGameObject userdata (see above)
userdata GetComponent(string TypeName)
Vector3 GetPosition()
void SetPosition(number x, number y, number z)
void SetPosition(Vector3 position)
Vector3 GetLocalPosition()
void SetLocalPosition(number x, number y, number z)
void SetLocalPosition(Vector3 position)
Quaternion GetRotation()
void SetRotation(number x, number y, number z, number w)
void SetRotation(Quaternion rotation)
Vector3 GetScale()
void SetScale(number x, number y, number z)
void SetScale(Vector3 scale)
userdata GetParent()
returns the parent CTransform, or nil if there is none
userdata GetRoot()
returns the top-most CTransform in the hierarchy
number GetChildCount()
userdata GetChild(number index)
returns the child CTransform at the given index, or nil
any CallMethod(string MethodName, ...)
as with CComponent, you can invoke any in-game method on the transform (e.g. t:CallMethod("LookAt", player:GetTransform())), and the typed variants return the result.