Prison Architect

Prison Architect

101 ratings
Object scripting with Lua – Prison Architect
By leftbehind and 5 collaborators
An introduction to scripting objects using Lua.
   
Award
Favorite
Favorited
Unfavorite
Introduction
This guide is a work in progress where I hope to document everything relating to Lua scripting of map Objects (things defined in materials.txt).

The guide is incomplete.

As you'll notice, there's lots missing and some sections aren't complete yet. If you have any information that's relevant to this guide, or spot any errors in it, please help by posting what you know in the comments.

Also, this guide is public domain so feel free to share or do whatever else you want with it.
Basic set-up
Step 1: Add Scripted property

To enable scripting on an object, you must first add the Scripted property to the object's definition in your mods/YourMod/data/materials.txt:

Properties Scripted

Step 2: Create script file

Next, create a Lua script of the same name as your object in the mods/YourMod/data/scripts/ folder.

For example, if your object's Name (as defined in materials.txt) is FooBar, the script file you'd create in th scripts folder would be "FooBar.lua" (same capitalisation in filename as the capitalisation used in materials.txt, but the .lua extension should be lowercase).

Note: Many old mods use all-lowercase filenames, however this breaks the scripts on Linux platforms which predominently use case-sensitive filenames. You should use the same capitalisation as the object name from materials.txt.

Step 3: Basic format of script file

The basic layout of your script file will generally look like this:

-- Code outside of functions will run immediately when the script is loaded -- This is useful for defining local variables local foo = "bar" -- Creates a local variable 'foo' and set it's value to "bar" function Create() -- The game will run code here when your object has been fully constructed on the map end function Update( elapsedTime ) -- Code here will be run every update (very, very regularly) -- It's strongly recommended to 'despam' this function (see later) end -- Helper functions are usually defined at the bottom of the script function Boo() -- Some stuff end -- Note that such functions won't be available until the whole script has been compiled; -- if you tried to access the function Boo() at top of script (outside of a function) -- you'd get an error (function doesn't exist yet). This doesn't affect Create() and -- Update() as they won't get called until after the whole script has been compiled.

Despamming the Update() function

Because Update() is called dozens, if not hundreds of times, per second, you should try and put as little code in there as possible otherwise your mod will cause the game to lag really bad.

But even reducing the amount of code often won't be enough (or feasible depending on the requirements of your object scripting). Ideally we also need to reduce the number of times the code gets run, for example running it once per second (rather than once per Update() invocation). Here's a simple way to achieve that:

-- despam Update() local Time = Game.Time; local Delay = 1; -- game seconds local Ready = Time(); function Create() -- stuff end function Update() if Time() > Ready then PerformUpdate( Delay ) Ready = Ready + Delay end end function PerformUpdate( elapsedTime ) -- put your update code here end

Even with this despamming you should still run as little code as possible in the PerformUpdate() function. You could, for example, run half of your code at a time by doing something like this:

local FirstChunk = true; function PerformUpdate( elapsedTime ) if FirstChunk then -- run first chunk of your code here else -- run second chunk here end FirstChunk = not FirstChunk -- optional: code here will be run every PerformUpdate() end

Basically, anything you can do to reduce the number of times your code runs, or reduce the amount of code that's run per PerformUpdate(), is a good thing: It will reduce lag, especially on bigger prisons.
Event handlers
These functions are automatically triggered upon certain events...

Create()

This function is called when an object has been fully spawned (eg. built) on the map.

It is called only once per object.

All top-level code (any code that's not within a function) in your script will run before Create() is invoked.

Update()

This function is called dozens (hundreds?) of times per second and should be despammed as described in Basic Set-up section earlier.

JobComplete_<JobName>

Whenever a job is completed, the applicable JobComplete function will be invoked.

For example, if you create a job called EatLard then when that job is finsihed the JobComplete_EatLard function will be invoked.

See also: Object.CreateJob(), this.CreateJob().
Lua features
_VERSION states that PA is using Lua 5.1 as of Alpha34 release.

Most of the standard Lua featuers are available to your scripts...

Global functions
  • assert() and error()
  • getfenv() and setfenv()
  • getmetatable() and setmetatable()
  • next(), ipairs() and pairs()
  • load() and loadstring()
  • module(), but sadly no require()
  • pcall() and xpcall()
  • rawequal()
  • rawget() and rawset()
  • select()
  • tonumber(), tostring()
  • type()
  • unpack()
math library

The 'math' library contains useful functions[lua-users.org] for working with numbers[lua-users.org].

string library

The 'string' library contains useful functions[lua-users.org] for working with strings[lua-users.org].

table library

The 'table' library contains useful functions[lua-users.org] for working with tables[www.lua.org].
Game library
The Game library provides different sets of functions depending on the context in which your script is running. For example, in a campaign script or grant script there would be lots of additional functions.

However, for in-game objects (things defined in materials.txt), there's only two functions currently provided:

Game.Time()

This returns the current "game time", or more specifically the amount of time the user has been playing the current prison.

local now = Game.Time();

As of Alpha 34 the time will still increase even when the game is paused (#6178[bugs.introversion.co.uk]).

Game.DebugOut()

This outputs text to the error.txt and/or debug console.

Game.DebugOut( "wibble" );

Note that the normal Lua print() function is not avialable in PA's Lua environment. Calling print() will cause a scripting error forcing the debug window to appear in game (which can be a really useful way to open the debug window).
Local vs. External vs. Imported objects
Before we continue let's clarify some stuff regarding local vs. external objects. I don't know if these are the correct technical terms, but they'll do for now.

Local objects

By local object I mean the specific map object instance that your script instance is running against.

For example, if you've developed a "SmokeDetector" object, it's corresponding script would be "smokedetector.lua". Every SmokeDetector you place on the map will get it's own separate instance of the smokedetector.lua script. (It could actually be separate environments of the same script instance, but for sake of simplicity let's just treat them as separate instances of the script).

Within each of those script instances there will be a global variable called 'this'. It's a table containing the properties of the object the script instance relates to (ie. one specific SmokeDetector).

Interacting with the local object, therefore, is done via 'this'. Some examples:

this.Pos.x = this.Pos.x + 1; -- move the object 1 tile to the right this.delete(); -- delete your object (and it's script instance) from the game

External objects

By external objects I mean every other object on the map, excluding the specific object instance your script instance is related to.

For example, if you place a bunch of SmokeDetector objects on the map, they each get their own script instance. In one of those script instances there's the local 'this' which refers to one specific SmokeDetector object on the map. From the perspective of that script instance, all the other SmokeDetectors are external objects.

Interactions with external objects are done using the Object library. Some examples:

Object.SetProperty( someObj, "Pos.x", Object.GetProperty( someObj, "Pos.x") + 1 ); Object.Delete( someObj );

As you can see, working with remote objects is somewhat cumbersome.

Tip: You can create shortcuts to functions to make using them a bit easier...

local Get, Set = Object.GetProperty, Object.SetProperty; Set( someObj, "Pos.x", Get( someObj, "Pos.x" ) + 1 );

Now, there should be one burning question on your mind...

What is this 'someObj' you speak of?

Before you can do anything with an external object, you need a reference to it... I'm just using someObj to depict that reference. But how do you get it?

The most widely used method is to use this.FindNearbyObjects(). It searches for a given type of object within a set range of your local object, and returns a list of any it finds. If your local object is the same type as the objects you're searching for, it too will be included in the returned list.

The list (well, technically it's a table) contains key = value pairs, where the key is a reference to the external object and the value is the distance between that object and your local object.

Let's say we wanted our SmokeDetector to magically extinguish nearby fires (external objects), we could do something like this:

local fires = this.GetNearbyObjects( "Fire", 10 ); -- get all fires within 10 tiles of local object for obj, dist in pairs( fires ) do Object.Delete( obj ); end

All the documentation I've seen states that GetNearbyObjects() returns names of objects. However this isn't the case. What it's actually doing is...

Importing objects

If you open the script debugger and go in to Explore mode, you'll see that there's now a bunch of new global variables floating around in your script instance. On further inspection, you'll find that they contain the full object tables of the fires that were found by GetNearbyObjects(). This means you can interact with them directly. So all the stuff you can do via 'this.' for your local object, you can now do for the external objects by directly interacting with their imports; you just replace 'this.' with the reference of the imported object. For example:

local fires = this.GetNearbyObjects( "Fire", 10 ); for obj, dist in pairs( fires ) do obj.Pos.x = obj.Pos.x + 1; obj.Delete(); end
Entity types
This is a reference of the various entity types (people - eg. prisoners, guards, etc) found in the game.

Prisoners

All prisoners are type "Prisoner", but you can determine what security level they are from their .Category property.

Guards
  • Guard
  • ArmedGuard
  • DogHandler
  • Dog
Workers
  • Cook
  • Doctor
  • Gardener
  • Janitor
  • Workman
Administrative
  • Warden
  • Cheif
  • Foreman
  • Psychologist
  • Accountant
  • Lawyer
Call-ins
  • Soldier
  • RiotGuard
  • ArmedGuard
  • Fireman
  • Paramedic
Other / Special
  • ExecutionWitness
  • Actor
  • Avatar (if you lose the game, you will become an 'avatar' in your own prison)
  • Teacher
  • SpiritualLeader
  • ParoleOfficer
  • ParoleLawyer
  • AppealsLawyer
  • AppealsMagistrate
  •  TruckDriver
  • Visitor
Object library
The Object library contains a number of useful methods for interacting with objects on the map.

While you can use this library to interact with your local object (the one your script is managing) it's generally better to access that via the 'this' table (see later in this guide). It will make the intent of your code clearer, because anything starting with 'this.' is relating to the local object and anything starting with 'Object.' is relating to some external object.

In all the functions below that have an 'object' parameter, if you omit that parameter the function will act on your local object (ie. 'this') instead.

Object.ApplyVelocity( object, x, y, rotate )

Apply a velocity and, optionally, a rotation to an object. This is useful for custom objects that produce some sort of item, for example in a gardening mod a plant could spawn fruit and then apply some velocity to make it move away from the plant slightly (giving a sort of 'fruit drop' effect).

local x, y = this.Pos.x, this.Pos.y; local fruit = Object.Spawn( "MyFruit", x, y ); Object.ApplyVelocity( fruit, 0, -1, false ) -- make fruit move south slightly fruit.ApplyVelocity( 0, -1, false ) -- alternate way

Note: If you don't specify a value for the 'rotate' parameter, it will default to true. When true, the object will rotate around it's axis a little. It's not possible to set rotation direction or speed, it's random.

I've not done enough testing to know whether the x,y values relate to time or distance or both. The documentation with the game (lua_function.txt in main.dat) states "velocity" so I assume both, but some experimentation will be required to determine what velocity would be required to move 1 tile vs 10 tiles or move a certain distance in given time. For example, do objects with a 'Weight' property behave any different?

Object.ClearRouting( object )

Obviously, this function is primarily for use with entities.

This cancels any current pathfinding route for an object. You can set pathfinding route using Object.NavigateTo(). Note that the player can override a pathfinding route with the mouse (select an entity and then right-click the map IIRC). Also, most entities will be moving around anyway due to having jobs or going for food, etc. It's not clear whether jobs will be cancelled if you clear routing for the entity currently doing the job (I would assume so).

Object.ClearRouting( somePrisoner ) somePrisoner.ClearRouting()

Object.CreateJob( object, jobName )

This creates a job called 'jobName' on the object specified. It's lilkely that for this to do anything meaningful you'll have to define the job in production.txt, but I've not done enough testing in this area to know for sure. A good mod to look at as an example would be Gary's Drink Mod where he sets jobs for filling water dispensers, repairing air conditioning fans and so on.

Object.CreateJob( someObject, "MyJob" ) someObject.CreateJob( "MyJob" ) this.CreateJob( "MyJob" ) -- create job on local object

There are quite a few issues with the way jobs work in terms of the API. For example, there's no way to get a list of all currently active jobs, which in turn means there's no way to know which entity is assigned to a specific job. The JobId property could possibly be used to link an entity doing a job to the object providing the job, but in many cases it seems that the JobId property isn't properly updated (eg. a guard assigned to open a door won't have a JobId and neither will the door). There also doesn't seem to be any clear way to cancel a job.

Object.Delete( object )

Deletes the specified object from the map; removes them instantly from map. Unsure what effects it has on anything they were carrying or any job they were doing.

Object.Delete( somePrisoner ) -- delete somePrisoner somePrisoner.Delete() -- alternate to delete somePrisoner Object.Delete() -- delete local object (ie. 'this') this.Delete() -- alternate to delete 'this'

Object.GetMaterial( x, y )

Get's the material (floor or wall type) at the specified location.

Returns a string with the name of the material (as defined in materials.txt).

-- get material that's directly below local object... local material = Object.GetMaterial( this.Pos.x, this.Pos.y ); if material == "Grass" then -- whatever end

Materials that Entities can not walk on include:
  • "Water"
  • "BuildingConcrete"
  • "BuildingFrame"
  • "ConcreteWall"
  • "BrickWall"
  • "PerimeterWall"
  • "Fence"
  • "BurntWall"
  • "Roof"
Object.GetNearbyObjects( originObject, targetType, range )

This is one of the most heavily used functions in the entire API, because it's currently the only real way to get access to external objects (it's also the only way I know of to import them so they can be accessed by the local object script).

local prisoners = Object.GetNearbyObjects( someObj, "Prisoner", 10 ) for prisoner, range in pairs(prisoners) do -- prisoner = a prisoner object -- range = distance between prisoner and someObj end

Note: Prior to Alpha36 the range value was returned as a string. That bug should now be fixed (and will certainly be fixed for 1.0 release).

Object.GetProperty( object, propertyName )

Get's the value for the corresponding 'propertyName' (see "<whatever> property" sections later in this guide for list of all the property names) on the specified 'object'.

If you don't specify an object, then the 'local object' (ie. 'this') will be used.

You can use dot-notation paths to specific properties within a property. For example, "Pos.x" would get the value 'x' property from the 'Pos' property:

local myPosX = Object.GetProperty("Pos.x");

Due to the amount of typing, most modders create shortcuts to this function (and the corresponding 'SetProperty' function) as follows:

local Get = Object.GetProperty; local Set = Object.SetProperty; local myPosX = Get("Pos.x"); -- now we have less typing to do :) local myPosX = this.Pos.x -- alternate way to get same property value local somePrisonerX = Get( somePrisoner, "Pos.x" ) local somePrisonerX = somePrisoner.Pos.x -- alternate way

Object.SetProperty( object, propertyName, propertyValue )

Similar to GetProperty() only this one sets a new value for the property. Note that some properties use different types for getting and setting (eg. GetProperty() might return a string whereas SetProperty() might expect a number) so be sure to check the details of the property later in this guide.

Object.SetProperty( somePrisoner, "Damage", 1 ) -- kills somePrisoner somePrisoner.Damage = 1 -- alternate way

Note that each object has something called a "script state blackboard". If you set a property that doesn't normally exist on an object, you will in effect create a new custom property. As long as that property is using a very primitive data type (mainly number, string or boolean) it will usually be persisted when saving a game and recreated when that game is later loaded again. Note, however, that this can be a bit 'hit and miss' - some property names are 'reserved' and SetProperty() won't allow you to set them. A good example, at time of writing, is "Or" property on custom door objects.

Continued below...
Object Library - continued...
Object.Sound( object, soundTable, soundId )

This plays a sound eminating (usually) from the specified object. Sounds are defined in sounds.txt where you can find their soundTable (see OBJECT lines) and soundId (see EVENT lines) values.

Note: Currently it's not possible to play sounds that are defined in your mod (you can only play sounds that come with the vanilla game). Bug #9504[bugs.introversion.co.uk].

Object.Spawn( objectType, X, Y )

This lets you create a new object on the map, so long as you know it's 'objectType'. Luckily, object type names are defined in http://steamcommunity.com/sharedfiles/filedetails/?id=497117126 so it's fairly easy to find them. However, there's no way to get a list of object types via the Lua API so you can't, for example, make your script find new object types added by other mods.

local x, y = this.Pos.x, this.Pos.y; -- a quick way to GetProperty() for the local object Object.Spawn( "Fire", x, y ) -- start a fire on my object

Note: It's often worth doing a Object.GetMaterial() first to check that you're not spawning on a wall or lake or something.

Object.NavigateTo( object, x, y )

This instructs an object to navigate to a new location. That means the pathfinder will calculate a route between the current position and specified x,y position, and if the object can get there they'll start travelling along that path. You can clear a path using Object.ClearRouting() function.

Object.NavigateTo( somePrisoner, this.Pos.x, this.Pos.y ) -- make prisoner navigate to me

The documentation (lua_function.txt in main.dat) states that this can only be used on entity objects. An epic example of this function in use can be found in the Aviation mod, which adds helicopter entities and navigates them from their map-edge spawning points to helipads in your prison.
me table
The 'me' table contains the Id's of the local object. Every object in the game has two Ids - an index and a unique index. In the 'me' table they're called:
  • me.id-index
  • me.id-uniqueId
That's butt-munchingly annoying, because if you try and reference them directly Lua will think you're trying to do a subtraction between two values. To reference them you need to use this syntax:

var i, u = me["id-index"], me["id-uniqueId"];

When using functions in the Object library, if you omit the 'someObj' parameter it will default to "me" (a named string reference to the 'me' table) which will effectively redirect the function to interact with the local object.

Trivia: The values of these keys can also be found lurking within 'this':
  • me.id-index is equivalent to this.id-index and this.Id.i
  • me.id-uniqueId is equivalent to this.id-uniqueId and this.Id.u
As you can see this.Id provides a much nicer way to access the Ids, eg. this.Id.i rather than me["id-index"].

Creating proxy objects for Object library functions?

It might be possible to create proxy objects for use with functions such as Object.GetProperty() and Object.SetProperty(), however there are reports that this doesn't work in practice.

somePrisoner = { ["id-index"] = 745, ["id-uniqueid"] = 3484 } prisonerPosX = Object.GetProperty( "somePrisoner", "Pos.x" )
this table – function library
In your script, 'this' is a table that relates directly to the local object that your script is currently running against.

The table contains numerous properties (see "<whatever> property" sections later in this guide) and also a small library of pre-defined functions as listed below:

this.LeaveMap()

Instructs the object to leave the map:

this.LeaveMap();

Other functions

The following functions work the same way as their Object library counterparts, but with the 'someObj' parameter removed.
  • this.ApplyVelocity()
  • this.ClearRouting()
  • this.CreateJob()
  • this.Delete()
  • this.GetNearbyObjects()
  • this.NavigateTo()
  • this.Sound()
Various timer properties
There are numerous timer properties associated with objects...

Timer property

For Entity ojbects (people such as prisoners, guards, etc) the purpose of this property is currently unknown.

For VisitorTable objects the purpose of this property is currently unknown.

CloseTimer and OpenTimer properties

These properties seem specific to Door objects and appear when the door is either closing (CloseTimer) or opening (OpenTimer).

CellIdTimer and SectorTimer properties

These properties seem specific to Door objects and from what we gather they determine when the Door object will re-check what rooms or sectors it links to.

OperationTimer property

This property is specific to LogicCircuit objects and when it reaches zero the object will recalculate its Result property.

See also: Operation property, Result property.

WallCheckTimer property

This property seems specific to CCTV Camera (Cctv) objects. It's likely that when the timer reaches 0 the camera will recheck its Walls property to see if nearby walls have changed. The rotation angle of the camera is affected by nearby walls, from a maximum of 180º sweep angle when placed against a flat wall to a 90º angle when placed in a corner and a minumum of 45º if it has walls on three sides.
Active property
This property seems specific to a CCTV Camera (Cctv) object and defines whether the camera is active (due to being connected to a CCTV Monitor).

The vlaue is boolean true or false. When true, the camera will rotate from side to side clearing an arc in the fog of war. When false, the camera will be stationary and not clear the fog of war.

See also: RotateDir, WallCheckTimer
Age property
This property denotes the age of an object.

In the case of Garbage and Tree objects, it's the game time that the object has existed for.

Note: The property also exists on Prisoner entities but I haven't had time to check.

See also: Garbage property, Weight property
AnimateRotation property
Further investigation required. It's highly likely that this property directly relates to Object.ApplyVelocity() and this.ApplyVelocity() functions when the rotation parameter is set.
AnimateVelocity property
Further investigation required. It's highly likely that this property directly relates to Object.ApplyVelocity() and this.ApplyVelocity() functions.
Attacker property
(Thanks to Themias for discovering this property)

This property is (probably) specific to entities and defines the entity (or weapon/object?) that most recently attacked the object.

Need to do more testing to determine what it's value is; either an object or an Id pair.

Can potentially be used to perform a counter attack = custom weapons, turrets, punishments, etc.
BodyArmour property
Note: English spelling of Armour (not Armor).

This property defines what sort of armour is being worn by an Entity object (a person, eg. Guard or Prisoner).

The value is a string defining the type of armour, for example StabVest.
BoilingPoint property
This property is specific to Prisoner objects and defines how mad they are.

Value is a number, seems to be in range 0..100?

Needs further investigation.
Carried property
This property seems to be available on all objects but it's purpose is not yet known.

It's likely a boolan indicating if an object is currently being carried.

Further investigation requried.

See also: CarrierId property, Carrying property
CarrierId property
This property seems applicable to all object types and denotes which external object (most likely an Entity, but possibly also things like Vehicles?) is carrying the object being inspected.

The value is a table with two properties:
  • i = index of the external object that is carrying the inspected object
  • u = unique index of the external object that is carrying the inspected object

The external object will have it's Carrying property set to the indexes of the object being carried, thus forming a two way reference between the objects.

By setting the relevant property values on both objects you can programatically make an Entity carry any object. A good example of this is Chad's Drink Mod.

See also: Carrying property, JobId property, Slot0 .. Slot7 properties, Object.CreateJob(), this.CreateJob().
Carrying property
i, u
Category property
Relates to Prisoner objects where it defines their security level category.

When getting the value, a string is returned (shown in quotes below). When setting the value, you have to use a number (shown in brackets below).
  • "Protected" (not checked yet - either 5 or 0?)
  • "MinSec" (1)
  • "Normal" (2) -- aka Medium Security
  • "MaxSec" (3)
  • "SuperMax" (4)
  • "DeathRow" (6)
Note that you can't alter clemency, etc., for DeathRow prisoners as that info is stored in the bio and currently the Lua API doesn't give access to the bio. Thanks to Trixi for this info.
CellId property
This property indicates which cell an object, such as a door, is associated with.

For example, a SolitaryDoor object would use this property if its being used as the door to a cell, holding cell or solitary cell.

Note: Prisoners likely have a CellId property, but I've not had chance to check yet.

The value is a table with two properties: i (index) and u (unique index).

Further investigation is required to find a way to quickly retrieve the referenced cell object.

See also: CellIdTimer property.
Connections property
Note: I've never been able to get access to this property via Lua scripts.

This property is specific to Wired objects, particularly devices such as CCTV Monitor, Phone Tap and Door Control. It lists the outgoing wire connections to devices the object is connected to.

The value is a table which is used as an array.

It's Size property (#) defines the number of connections.

Each index in the array represents a connection; the connection is a table containing the following properties:
  • To.i = the index of the external object the connection links to
  • To.u = the unique index of the external object the connection links to
  • Triggered = a boolean true or false denoting whether the connection is triggered
  • TimeIndex = likely the game time at which the Triggered state of the connection last changed
Further investigationis required to try and get access to the Connections property from a script, and also to find a way to list incoming connections.

See also: Triggered property, TriggeredBy property, TriggerTime property
Contents property
This property seems specific to Box and Stack objects and defines what's in them.

The value is a string defining the object type, for example "RemoteDoor" or "Light" etc.

A Box object can only contain a one unit of the specified item, whereas a Stack object can contain multiple units of the specified item.

See also: Quantity property
Damage property
This property can apply to most objects, most notably Entity objects (people, eg. Guard and Prisoner), which indicates how damaged the object is.

The value can be either nil (which equates to false, no damage) or a number in the range 0 .. 1.

Still investigating range of number values.
Dest property
This property seems specific to Entity objects (people such as staff, guards, prisoners, etc) and defines the entity's current destination.

The value of the property is a table containing two properties: x and y (the cordinates of the destination).

To set the values, use this.NavigateTo() for local object or Object.NavigateTo() for external objects.

To clear the path, use this.ClearRouting() for local object or Object.ClearRouting() for external objects.

See also: Object.NavigateTo(), Object.ClearRouting(), Object.ApplyVelocity(), this.NavigateTo(), this.ClearRouting(), this.ApplyVelocity(), Pos property, Vel property, Or property.
Door property
This property seems specific to Servo objects and contains the Id of the door the servo is linked to.

The valye of the property is a table containing the Ids of the door, or nil (property won't exist) if no door attached.

local door_i = Object.GetProperty( someServo, "Door.i" ); local door_u = Object.GetProperty( someServo, "Door.u" );

Note: Further testing is required to see if servos will automatically detect custom door objects.

See also: RemotelyOpenable property, Open property
Energy property
This property is specific to Entities (probably only employees – workers, guards, administrators, etc) that defines how much energy they have left.

The value is a number, which seems constrained to the range 0 .. 100. A value of 0 means they are exhausted, a value of 100 means they are fully rested.

Below a certain value (not sure what) the entity will go to a specific room/object to rest. The room/object depends on the entity type (and is most likely hard-coded in to the game). For more details see the "Properties – DoesNotTire" section in Materials.txt – Entities.

See also: RestState property
Equipment property
This property is specific to Entity objects (people such as guards, prisoners, staff, etc) and defines what equipment they are carrying (eg. Clipboard or Baton).

Further testing is required to see what happens when an entity is carrying multiple items of equipment.

Each piece of equipment has an assigned number.
eg. Object.setProperty(objectName, "Equipment", 2) gives the entity objectName a baton.

Below is a list of all equipment:
  1. Fists
  2. Baton (the one the guards use)
  3. Club (the improvised weapon)
  4. Shank
  5. Knife
  6. Fork
  7. Gun (revolver)
  8. Spoon
  9. Needle
  10. Medicine
  11. Scissors
  12. Booze
  13. Poison
  14. Cigs
  15. Saw
  16. JailKeys
  17. MobilePhone
  18. Lighter
  19. Screwdriver
  20. Drugs
  21. Sheers
  22. Mop
  23. Rake
  24. Hose (does not turn people into firefighters)
  25. Spatula
  26. WoodenSpoon
  27. CleaningBrush
  28. Hammer
  29. Clipboard
  30. Drill
  31. PianoWire
  32. Shotgun
  33. Iron (clothes iron)
  34. MoneyBag
  35. DogLeash
  36. DogBite (what dogs use instead of fists)
  37. Tazer
  38. GuardUniform (not an actual uniform)
  39. PrisonerUniform (not an actual uniform)
  40. StabVest (not wearable)
  41. Torch (flashlight)
  42. Rifle (sniper)
  43. Axe
  44. Spade (shovel)
  45. AssaultRifle (M16)
  46. SubMachineGun (Mac10)
  47. WoodenPickAxe
  48. BatteringRam
  49. Megaphone
  50. Book
  51. BookClosed
  52. CbRadio (walkie-talkie)
  53. Magazine
  54. Snack
  55. Soap
  56. Photo
Anything greater then 56 gives None, making the NPC hold their hand out with nothing in it. 0 does not do anything (clears current equipment?).
ExternalPower property
UPDATE: This property always seems to return boolean false, even when there are powered electric cables running direct to the object. Bug #9507[bugs.introversion.co.uk].

This property seems to be available on all objects and likely indicates whether there's a direct connection to power cables (rather than the smaller automatically added power wires).

Further investigation required.

See also: Powered property
FollowerId property
This seems specific to Prisoner entity objects and possibly has something to do with when they are being escorted. (thanks to Dubpub for finding it)

The property value is a table containing 'i' and 'u' id values of the object that's following or being followed (not sure which).

There's possibly also a correponding property on the other object, something like FollowedBy or FollowingId?
Gang property
This property applies to Prisoner entities and defines their gang status.

Its value is a table with the following properties:
  • Gang.Id – an integer id of the gang the prisoner belongs to (it's 0 if they are not in a gang)
  • Gang.Rank – a string representing their rank in the gang (it's "None" if they are not in a gang)
  • Gang.Recruitment – a floating point number between 0 and 1 that defines how close they are to being recruited to a gang (0 = no recruitment, 1 = fully recruited)
Gang.Id

Steam user Trixi provided following infos about Gang.Id:
  • 0 or nil – no gang affiliation
  • 1 – White (guards gang)
  • 2 – Red (prisoner gang)
  • 3 – Green (prisoner gang)
  • 4 – Blue (prisoner gang)
  • Any other value – does not work
Setting a prisoner to be a member of the Guards gang does seem to have some effect (eg. their cell turns white) but hasn't been fully tested.

Gang.Rank

Reddit user Oddzball listed the values of this propery as: "Solider", "Leuitenant", "Leader". If the entity is not a gang member the property will return an empty string or nil.

However, when setting the value you need to use numeric values (Bug #9741[bugs.introversion.co.uk]): 1 (Soldier), 2 (Leuitenant) or 3 (Leader). (Thanks to Trixi for finding this out)

Notes

Steam user Trixi reports that there's currently no way to access or change the prisoner Repuation "GangMember".
Garbage property
This property indicates that the object is classifed as Garbage.

The value is nil (not garbage) or boolean true (garbage).

See also: Weight property, Age property
Id property
i,u
JobId property
This property defines the Id of a job that the object provides or is assigned to.

The value is an integer representing the Job Id.

In the case of an Entity object (people, such as guards and prisoners) the property indicates that the Entity is assigned to that job. In the case of all other object types the property indicates the job the object requires an extenal Entity object to perform.

Furhter investigation is required to find out how to obtain further details of the job, and how to link an Entity doing a job to the object providing the job.

See also: Object.CreateJob(), this.CreateJob().
Loaded property
This property appears on all objects but seems to be primarily utilised on Stacks.

It's value is a boolean true or false. When not loaded, the value seems to be nil (the property does not exist), which equates to false.

It's likely the property gets set to true when the object is attached to a Slot on some external object, for example when ingredients get placed on a cooker the Loaded property would likely get set to true?

Further investigation is reqired to fully asses what this property does.

See also: Slot0 .. Slot7 properties, Object.CreateJob(), this.CreateJob(), JobId property
Locked property
UPDATE: This property always seems to return nil (tested with: manual lock door, lockdown) Bug #9508[bugs.introversion.co.uk].

This property seems to be available for all objects, but it's not clear what it's use is.

It's possible that it only has effect on doors, when a door is locked open or closed? Or it could refer to prison lockdown? Or lockdown witin a specific sector/zone?

Further investigation required.

See also: Mode property
Misbehavior property
This property seems specific to Prisoner objects and defines how they are currently misbehaving.

When getting the value, it's either nil (if no misbehavior) or a string defining how the prisoner is misbehaving:
  • "Escaping"
  • "Spoiling"
  • "Rioting"
When setting the value, a numeric id must be used:
  1. "Spoiling"
  2. "Escaping"
  3. "Destroying"
  4. Seems to be a random mix of fighting, spoiling, and destroying
  5. Also seems to be a mix of fighting, spoiling, and destroying
  6. "Rioting"
  7. Hostage Taking (they don't actually take hostages since this isn't implemented yet)
  8. (Prisoners put their hands in fighting position but no misbehavior status is shown, they do not commit any acts of violence, but guards still attack them and they fight back)
A value of 0 likely clears any misbehavior. Anything 8 and higher does the same as 8.
Mode property
This property seems specific to Door ojbects and defines their current mode as indicated on the door's info panel in-game.

When getting the value a string will be returned: "LockedOpen", "LockedShut" or "Normal":

-- for local object: local doorMode = this.Mode; - for external objects: local doorMode = Object.GetProperty( someObj, "Mode" );

When setting the value, however, you must use a number: 0 (for Normal), 1 (for LockedShut) or 2 (for LockedOpen):

-- for local object: this.Mode = 1; -- 1 = LockedShut - for external objects: Object.SetProperty( someObj, "Mode", 2 ); -- 2 = Normal

See also: Open property, OpenTimer property, CloseTimer property, OpenDir property, RemotelyOpenable property
Name property
This property is available on all objects but it's purpose is not yet tested.

It's likely a string name of the object as shown on screen when hovering mouse over object.

Further investigation requried.

See also: Type property.
Needs property
This property appears on "Prisoner" entity objects and contains a table listing the needs of the prisioner[prison-architect.wikia.com].

The following properties are currently known to exist (they are defined in needs.txt, list below is correct as of Alpha36):
  • Alcohol
  • Bowels
  • Bladder
  • Clothing
  • Comfort
  • Drugs
  • Environment
  • Excercise
  • Family
  • Food
  • Freedom
  • Hygiene
  • Literacy
  • Privacy
  • Recreation
  • Safety
  • Sleep
  • Spirituality
Note that not all needs will be available on every prisoner. For example, the Alcohol and Drugs needs will only appear on prisoners with addictions. In addition, most needs have a 'chance' property defined in needs.txt which determines the chance that new prisoners will have the need.

Need values are numeric. A value of 0 means the need is completely satisfied.

Example:

if somePrisoner.Needs.Bowels == 0 then -- that prisoner does NOT need to use the toilet for a while end

Further investigation is required to determine maximum value (likely 100?), and also what values will cause need icons to appear or trigger need-related events (such as increasing heat if need not met).

Thanks to hoosdatGuy for his mods (particularly Pied Pooper) showing the use of the property.
Office property
This property seems specific to administrative employees such as lawyers, accountants, warden, psychologist, etc. It defines which office they are assigned to.

The value is a table containing two properties: i and u; the index and unique index of the office room.
On property
This property determines whether an electrical device is switched on.

As of Alpha34 it's somewhat pointless as there's no way to provide the UI to allow users to turn custom objects on or off (#6883[bugs.introversion.co.uk]).
Open property
This property seems specific to doors and indicates how 'open' the door currently is.

A value of 1.0 means the door is completely open, a value of 0.0 or nil means the door is completely closed.

-- for local object: local op = this.Open; - for external objects: local op = Object.GetProperty( someObj, "Open" );

Values between 1.0 and 0.0 indicate that the door is opening or closing (you can usually determine which by looking for an OpenTimer or CloseTimer property on the door object).

local op = Object.GetProperty( someObj, "Open" ); local doorState; if not op or op == 0 then doorState = "Closed"; elseif op == 1 then doorState = "Open"; elseif Object.GetProperty( someObj, "CloseTimer" ) then doorState = "Closing"; elseif Object.GetProperty( someObj, "OpenTimer" ) then doorState = "Opening"; else doorState = "Somewhere between open and closed"; end

You can set the property to open or close a door:

this.Open = 1; -- open the door this.Open = 0.5; -- door is half open or half closed Object.SetProperty( someObj, "Open", 0 ); -- door is closed

Further testing is required to see if merely setting the OpenTimer or CloseTimer properties will cause the game engine to automatically transition the door to fully open or closed state.

See also: Mode property, OpenDir property, OpenTimer property, CloseTimer property, RemotelyOpenable property.
OpenDir property
This property seems specific to doors and defines the direction in which the door will open.

The property value is a table with two properties: x and y.

local openx, openy = this.OpenDir.x, this.OpenDir.y;
Depending on the values of OpenDir.x and OpenDir.y, the door will open in one of four directions:
  • North: OpenDir.x == 0 and OpenDir.y == -1
  • East: OpenDir.x == 1 and OpenDir.y == 0
  • West: OpenDir.x == -1 and OpenDir.y = 0
  • South: OpenDir.x == 0 and OpenDir.y == 1
Note that one or both of the values can be nil, which should be treated as 0.

if not this.OpenDir.x then -- this.OpenDir.x = 0 end

Custom door objects don't seem to get this property, and furthermore the scripting environment prevents you from creating the poperty unless you use rawset(). Bug #9503[bugs.introversion.co.uk].

See also: Open property, Or property, OpenTimer property, CloseTimer property, Mode property.
OpenOnTrigger property
This property is specific to Servo objects and defines whether, upon being triggered, they should open or close the door they are associated with.

The value is either nil (possibly close door when triggered?), boolean true (open when triggered) or boolean false (close when triggered).

See also: Door property, RemotelyOpenable property, Triggered property, TriggeredBy property, TriggerTime property.
Operation property
This property is specific to LogicCircuit objects and defines the currently selected operation (set by right-clicking the object on the map).

The value is a string and can be:
  • Not
  • And
  • Or
  • Xor
  • ....?
Futher investigation is required to determine all the possible values, in particular the valye for the '=' Equal operation.

See also: OperationTimer property, Result property
Or property
This property is found on most objects and defines the orientation of the object (which way it's facing). When placing objects on the map, you can press the R key to change their orientation.

The value of the property is a table containing two values, x and y:

local orx, ory = this.Or.x, this.Or.y

Possible values for Or.x are:
  • nil or 0 = facing north/south (see Or.y)
  • -1 = facing west
  • 1 = facing east
Possible values for Or.y are:
  • nil or 0 = facing east or west
  • -1 = facing north
  • 1 = facing south
Note that 0 values sometimes are sometimes represented by really small values. As such, it's best to check a value is not -1 and not 1 in order to determine if the value is 0. For example:

if (not this.Or.x) or ( this.Or.x == 0 ) or ( this.Or.x > -1 and this.Or.x < 1 ) then -- this.Or.x is 0 end

While there are 8 possible combinations (North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest) the game seems limited to just 4 directions[forums.introversion.co.uk] (North, East, South, West):
  • North: Or.y = -1 (Or.x values ingored)
  • East: Or.x = 1 and Or.y = 0
  • West: Or.x = -1 and Or.y = 0
  • South: Or.y = 1 (Or.x values ingored); or both Or.x = Or.y = 0

The sprite associated with each orientation is determined by the RotateType setting[forums.introversion.co.uk] used in the object's Sprite setting in materials.txt.

See also: Pos property, SubType property, OpenDir property.
Patrol property
(Thanks to Themias for discovering this property!)

This property is specific to entiteis and contains information about the patrol a guard, armed guard or dog handler is assigned to.

Its value is a table with the following properties:
  • Patrol.Active – Boolean (true or false or nil); is the entity assigned to a patrol?
  • Patrol.LastPos – Table (with x and y properties); the previous position on their patrol path
  • Patrol.ThisPos – Table (with x and y properties); the current position on their patrol path
Example:

if this.GetProperty("Patrol.Active") ~= true then -- not assigned to a patrol end

Not sure what happens if the properties are set (for example, does setting Patrol.Active to false remove them from the patrol?) – if you find out post a comment to let us know!
PlayerOrderPos property
This property seems specific to Guard entity objects. (thanks to Dubpub for finding and testing it)

The property value is a table containing 'x' and 'y' co-ordinates. Setting them has similar effect to Object.NavigateTo() function, the main difference being that a green line is drawn between the objects.

local spawnee = Object.Spawn( "Guard", this.Pos.x, this.Pos.y ) for guard in next, this.GetNearbyObjects( "Guard", 50 ) do guard.PlayerOrderPos.x = spawnee.Pos.x guard.PlayerOrderPos.y = spawnee.Pos.y end

Here's a video of it in action.
Pos property
The Pos property is a table that defines the current x,y position of an object on the map.

-- to get position of your object: local x = this.Pos.x; local y = this.Pos.y; local x, y = this.Pos.x, this.pos.y; -- to set position of your object to 5,6: this.Pos.x = 5; this.Pos.y = 6; this.Pos.x, this.Pos.y = 5, 6; -- to get position of some other object: local x = Object.GetProperty( obj, "Pos.x" ) local y = Object.GetProperty( obj, "Pos.y" ) -- to set position of some other object: Object.GetProperty( obj, "Pos.x", 5 ) Object.GetProperty( obj, "Pos.y", 6 )

When setting the position, the object will respect map borders (it will not go off the edge of the map).

See also: this.ApplyVelocity(), Object.ApplyVelocity() and this.NavigateTo(), Object.NavigateTo().
Powered property
As of Alpha34 this property seems to be completely broken (#9436[bugs.introversion.co.uk]).
Quantity property
This property is specific to Stack objects and defines how many units of the contained item are present.

The value is an integer from 0 .. MaxStackSize (as defined in materials.txt).

See also: Contents property.
RemotelyOpenable property
This property seems specific to doors, in particular SolitaryDoor objects.

Its value will be either nil (property won't exist), 4 or 5.

Further testing is required to determine the effects of this property. It's possible that relates to the OpenOnTrigger property of an associated Servo object?
RestState property
(Thanks to Themias for discovering this property!)

This property is specific to entities (probably not Prisoners though?) and provides information about their rest (tiredness) state.

Its value is a string and can be one of the following:
  • "RestStateRequired" – they are tired and need rest
  • "RestStateResting" – they are currently resting
  • (need to confirm this one) "RestStateOK" – they don't currently need rest
Example:

if this.GetProperty("RestState") == "RestStateResting" then -- the entity is currently resting end

Not sure yet what happens if the property is set – if you test it please comment and let us know!

See also: Energy property
Result property
This property is specific to LogicCircuit objects and defines the calculated result based on the Operation that's applied to the incoming connections.

The value is a boolean true or false.

The Result property is recalculated when the OperationTimer property reaches 0.

Further investigation is required to determine how the LogicCircuit object obtains a list of its incoming connections.

See also: Operation property, OperationTimer property
RotateDir property
This property is specific to CCTV Cameras (Cctv) objects and defines the current rotation of the camera (direction in which it's pointing).

The value is a number in the range -1 .. 0 .. 1.

From the perspective of the camera a value of -1 means the camera is turned fully left, a value of 0 means it's looking straight ahead, and a value of 1 means it's turned fully right.

See also: Active property, WallCheckTimer property
Slot0 .. Slot7 properties
Slots are like docking stations for objects. Most object types seem to have the slot properties (there are eight of them, numbered from Slot0 to Slot7).

Each Slot property contains a table that itself has two properties:
  • i = the index of the object assigned to the slot
  • u = the unique index of the object assigned to the slot

Jobs

When a job is being carried out against an object, for example because you used the Object.CreateJob() or this.CreateJob() function, the Entity object (prisoner, cook, guard, etc) that's doing the job will 'dock' with Slot0.

Processors

Slots are particularly important for processors (such as a cooker which processes ingredients in to food). Each processor uses the first three slots as follows:
  • Slot0 = input stack (eg. ingredients)
  • Slot1 = processing entity (eg. a cook)
  • Slot2 = outputstack (eg. meals)

Markers and Orientation

Slots can be given coordinates by defining Markers in your object definition in the mods/MyMod/data/materials.txt file. Each Marker should have an Index property which defines the slot number. For example:

BEGIN Marker x 0.2 y 0 orientation.x 0 orientation.y 0 Index 0 END BEGIN Marker x 0.5 y 0.8 orientation.x 0 orientation.y 0 Index 1 END BEGIN Marker x 0.8 y 0 orientation.x 0 orientation.y 0 Index 2 END

Whatever goes in a slot can also have it's orientation defined, for more info on that see this guide[forums.introversion.co.uk].

See also: NumSlots object property in materials.txt and MaxSlotId in production.txt.
Station property
Seems applicable to entity objects and denotes some external object (most likely static object or utility station?) that they are assigned to or working on.

The property value is a table containing 'i' and 'u' ids of the object.
StatusEffects property
This property is applicable to "Prisoner" entity objects and contains a table of status effects[prison-architect.wikia.com] (such as suppressed) which are applicable to the prisoner. Some status effects will affect other prisoners nearby, for example the calming effect can spread from a spiritual prisoner on to other nearby prisoners.

Currently known properties include:
  • angst – caused by prisoners ready for parole not getting a hearing, increases threat level (Angry)
  • calming – caused by prisoner having completed a Spiritual Guidance reform program, will spread calm to nearby prisoners.
  • drunk – caused by alcohol use, prisoner stumbles around and can be punished for intoxication
  • goodfood – caused by eating good quantity/variety meals, decreases threat level (Well Fed)
  • high – caused by drug use, prisoner is woozy and can be punished for intoxication
  • overdosed – sometimes caused by drug use, prisoner is unconscious and dies when the effect ends if not cured by a doctor, guards will rush the prisoner to an infirmary
  • suppressed – caused by armed guards and solitary, unhappy prisoners have less effect on threat level
  • surrendered – caused by nearby gunfire from armed guards/soldiers, prisoner raises hands and will not move for the duration of the effect (armed guards never attack surrendered prisoners, soldiers do if the prisoner has been spotted before they surrender)
  • tazed – caused by tazers, prisoner is unable to move for the duration of the effect
  • virus – caused by random event or proximity to infected prisoners, prisoner turns green and shows symptoms of a disease (Sick)
  • virusdeadly – same as above, but symptoms will be fatal if not treated (Sick)
  • withdrawal – caused by critical drug or alcohol needs, prisoner vomits and desperately seeks out the drug/alcohol they are addicted to
  • wounded – caused by the workshop accident random event, prisoner loses health over time and may die if not treated (Bleeding)

Example:

local suppression = somePrisoner.StatusEffects.suppressed;

Furhter research is required to get a big list of status effect properties and determine the applicable numeric range for their values, whether they can be set, and the values at which events occur.

Originally posted by "hoosdatGuy:
...one thing I would like to point out regarding the status effects is that the maximum values can be wildly different. For example, fully tazed is around 60, while 1000 doesn't even completely fill the suppressed bar. I think the numbers have to do with duration. It might be possible that you could for example make someone tazed for 1000, in which case the bar would be full for a long time. So the game seems to take the duration, divide it by the game's default "max" duration for the effect, and convert that into the plus signs it shows.

Note: Some effects can occur due to reform programs (see reform_programs.txt) that include a 'ProgressEffect', most notably 'calming' effect of Spiritual Guidance program.

Thanks to hoosdatGuy who posteed a full list of the effects!
SubType property
This property defines which sprite to use for your object.

Sprites are zero-indexed, meaning that the first sprite defined in materials.txt has index 0, the second has index 1, etc. For example, to set the second sprite you'd use:

-- for local object this.SubType = 1; -- for external objects Object.SetProperty( someObj, "SubType", 1 )

Sprites are defined in materials.txt. By default the first sprite (SubType 0) will always be used – both for the toolbar icon and also for your object when it's placed on the map.

Here's an example of what multiple sprite definitions (six in this case) looks like in the materials.txt; the first one is SubType 0, the second is SubType 1 and so on utnil the last one which is SubType 5.

BEGIN Sprite x 0 y 0 h 2 w 2 RotateType 4 END BEGIN Sprite x 2 y 0 h 2 w 2 RotateType 4 END BEGIN Sprite x 4 y 0 h 2 w 2 RotateType 4 END BEGIN Sprite x 6 y 0 h 2 w 2 RotateType 4 END BEGIN Sprite x 8 y 0 h 2 w 2 RotateType 4 END BEGIN Sprite x 10 y 0 h 2 w 2 RotateType 4 END

You can immediately change the sprite of your object as soon as it's constructed by changing its SubType within the Create() function:

function Create() this.SubType = 2; -- select the *third* sprite end

You can implement animations by cycling through sprites on sucessive calls to the Update() function. For example, if you had an animation with three frames, corresponding to SubTypes 3, 4 and 5, you could do something like this:

local Animation = { [1] = 3, [2] = 4, [3] = 5 } local Frame = 1; function Update() this.SubType = Animation[Frame]; Frame = Frame + 1; if Frame > #Animation then -- #Animation = length of Animation array = 3 Frame = 1; end end

Notes:

The SubType of a Tree object can be used to determine what type of tree it is.

The SubType of Prisoner entity objects determines the body size of the prisoner. Valid values range from 0 to 3.

In materials.txt, the "SpriteVariants" property will cause a random SubType to be chosen when an object is created. In the example above that shows 6 sprites being defined, if you added "SpriteVariants 4" then the game would choose randomly from the first 4 sprites when the object is created. The remaining two sprites could only be set from script.

Changing SubType also updates slot markers. So if you have a subtype that defines 2 slot markers and another that defines 3, you could effectively change the number of available slots on the object by changing the SubType - for example, you could potentially allow objects to be 'upgraded'.

Stack, Box and similar objects have a base sprite (eg. the box) on to which another sprite is overlaid (as defined by obj.Contents and obj.Quantity).

See also: Type property, Or property, Walls property, Slot0 .. Slot7 properties
TargetObject property
This property seems to be specific to Prisoner entity objects and possibly has something to do with jobs (the object providing the job) or attacking (the object being attacked)? (thanks to Dubpub for finding this property)

It's value is a table with 'i' and 'u' ids of the target object.
Tooltip property
This property sets the tooltip for your object, which is useful if you want to relay additional information to the user.

Common typo: Only the first letter is capitalised, if your Tooltips aren't working make sure you've not spelt it ToolTip.

-- for local object: this.Tooltip = "tooltip_object_status"; -- for external objects: Object.SetProperty( someObj, "Tooltip", "tooltip_object_status" );

You'll then need to add an entry to the /language/base_language.txt file (doing things this way ensures the text can be localised):

tooltip_object_status Yay, it's working!

In-game, it looks like this:

<pic>

To remove the tooltip, set it to an empty string:

this.Tooltip = "";

For details on adding additional languages, see the Localisation Guide.
Triggered property
This is a property of wired objects (things you can add connector wires to). It defines their output state.

The value can be either nil (equivalent to false), false, true, 2, 4 or 5 (2,4,5 are equivalent to true).

Common logic objects use a value of 2 to denote true wheras objects such as CCTV cameras use values such as 4 or 5. Further investigation is required to determine why, although most likely it's probably to prevent users activating cameras with power switches etc.

-- for 'false' output, use: this.Triggered = 0; -- for 'true' output, use: this.Triggered = 2; -- to get current output, use: local t = this.Triggered; -- and for external objects use: local t = Object.GetProperty( someObj, "Triggered" );

I have no idea why they didn't just use boolean values. To make life easier for myself I created a couple of helper functions:

function toWired( bool, trueVal ) if bool then return trueVal or 2 else return 0 end end this.Triggered = toWired( true ); -- this.Triggered == 2 this.Triggered = toWired( true, 5 ); -- this.Triggered == 5 function fromWired( paLogic ) if not paLogic or paLogic == 0 then return false else return paLogic end end local t = fromWired( this.Triggered ) -- t == 2 or 5 (both equate to boolean true)

Note that your object definition in mods/YourMod/data/materials.txt will need the Wired property to enable connections to/from your object:

Properties Wired

Further testing is required to see if this property can be used with object types such as Enity, Vehcle, Material, etc. It is assumed that such objects will not support the property.
TriggeredBy property
This property seems specific to Wired objects (as defined in materials.txt) and contains the Ids of the external object that most recently changed the Triggered property of the object being inspected.

The value is a table that has two properties: i and u (the index and unique index of the external object which triggered the object being inspected).

See also: TriggerTime property, Trigger property.
TriggerTime property
This property is specific to Wired objects (as defined in materials.txt) and specifies the game time at which the Triggered property was last updated (either by the local object or an external object as defined by the TriggeredBy property).

The value is a number representing the game time in seconds.

See also: Triggered property, TriggeredBy property.
Type property
This property is available on all objects and defines the object type, which is just its Name from its definition in the mods/MyMod/data/materials.txt file.

The value is a string.

See also: SubType property
Vel property
This property can appear on most object types and defines the velocity of the object (speed its moving in both the x and y axis).

The value of the property is a table containing two properties: x and y.

A non-zero value for eiether Vel.x or Vel.y indicates that the object is moving, and the speed that it's moving.

For Vel.x, a positive number indicates east, a negative number indicates west.

For Vel.y, a positive number idicates south, a negative number indicates north.

The values appear to be constrained to the range -1 .. 0 .. 1.

See also: Object.SetVelocity(), this.SetVelocity(), Object.NavigateTo(), this.NavigateTo(), Object.ClearRouting(), this.ClearRouting(), Pos property, Or property.
Walls property
This property seems to be available on every type of object and indicates whether the object has walls next to it.

The value is a table with two properties: x and y.

local wallx, wally = this.Walls.x, this.Walls.y

Walls.x values can be:
  • 0 = no walls on the left or right
  • 1 = walls on the right?
  • -1 = walls on the left?
Walls.y values can be:
  • 0 = no walls above or below
  • 1 = walls below?
  • -1 = walls above?
Further testing is required to see what happens to Walls.x when there are walls on both sides, and Walls.y when there are walls both above and below. Also, it's possible this property has some interaction with the AttachToWall and/or BuiltOnWall object properties in materials.txt.

You could potentially use this property to create self-aligning objects that automatically choose (within the Create() function) the correct SubType depending on which sides of the object has walls. In particular this approach could be used to choose a diagonal sprite when an object is placed in the corner of a room.

A further use of this property could be to alter parameters sent to GetNearbyObjects(). For example, if you know there's a wall behind your object you could potentially offset the point of origin for the search and update the range accordingly so as to avoid searching behind the wall.

See also: SubType property, Or property, Pos property.
Weight property
This property is specific to Garbage objects and defines the weight of the object.

The value is a positive number.

It is assumed that garbage truck vehicles have a maximum weight capacity and thus each truck can only load so many garbage objects.

See also: Garbage property, Age property.
Wired property
UPDATE: This property always seems to return nil Bug #9509[bugs.introversion.co.uk].

This property is present on all objects but likely only applies to Wired objects (as defined in materials.txt).

Its purpose is currently unknown, but at a guess it might be a boolean indicating if there is one or more connections to/from the object.

Further investigation required.

See also: Triggered property, TriggeredBy property, TriggerTime property, Connections property.
WorldObject property
Since 1.0 release, this property contains a bunch of metatables that have getters and setters for object-specific properties, and also the function library for the object. Much investigation required - already found about 30 new properties on Prisoner entitiy objects, and it seems each type of object will have some unique properties that are worth experimenting with.
65 Comments
Unknown Feb 12, 2022 @ 8:01am 
What size do the sprites need to be? Is there a set size? I am attempting to make some objects for my self to play around with. Can someone give me some tips thanks. Good guide though.
Rinus Jan 24, 2021 @ 11:32am 
added this to my bookmarks, this works wonders as a documentation.
t1a2l May 21, 2020 @ 10:38am 
How can I tell if a specific saff is on a break? RestState is not the answer if staff needs is on.
murgh Dec 16, 2018 @ 3:26am 
Looks like the TimeWarpFactor is made readably for scripting, so instead of calculating it, you can now simply use timePerUpdate = 1 / World.TimeWarpFactor to let a script run once every game minute.
murgh Dec 15, 2018 @ 8:41am 
To calculate the current season do math.mod(currentDay,28)
When the outcome is 0 then it's the first day of spring, 7 wiil be summer, 14 = autumn and 21 is the start of winter.

currentDay = math.ceil(World.TimeIndex/1440)

NextSpringStartsOnDay = (currentDay + (28 - math.mod(currentDay,28)))

daysUntilNextSpring = NextSpringStartsOnDay - currentDay
murgh Sep 7, 2018 @ 9:31am 
Implemented the custom reports as a walk through guide for the limo garage installer so you can see it in action in a finialized way:
https://steamcommunity.com/sharedfiles/filedetails/?id=1465161615
Looking sweet :)
murgh Sep 5, 2018 @ 4:37am 
New modding feature: custom reports tab for objects!
I've included a demo on how that works into the TimeWarpFactor mod, link below.
murgh Aug 25, 2018 @ 6:46am 
I've made a template to calculate the TimeWarpFactor in order to let scripts run in sync with the game speed. Check it out over here: https://steamcommunity.com/sharedfiles/filedetails/?id=1492313959
murgh May 4, 2018 @ 6:18am 
Different map sizes have different time speeds, which makes scripts run faster or slower. In order to get each script to run at the same time, you need to calculate the TimeWarpFactor by yourself, since this value is present in the savedgame, but not accessible to lua yet.
When you make a script which needs to follow very strict time rules, then follow these tips:
murgh May 2, 2018 @ 6:02am 
Some more calculations for lazy coders:
if Get(this,"TimeWarp") > 0 then
if this.TimeWarp == 0.75 then -- medium map
-- timePerUpdate = 6.666666 -- 5 minutes in game needs 5/0.75 = 6.6
-- timePerUpdate = 10 -- 7.5 minutes needs 7.5/0.75 = 10
-- timePerUpdate = 13.333333 -- 10 minutes in game needs 10/0.75 = 13.3
timePerUpdate = 20 -- 15 minutes needs 15/0.75 = 20
-- timePerUpdate = 40 -- 30 minutes needs 30/0.75 = 40
elseif this.TimeWarp == 0.5 then -- large map
-- timePerUpdate = 10 -- 5 minutes needs 5/0.5 = 10
-- timePerUpdate = 15 -- 7.5 minutes needs 7.5/0.5 = 15
-- timePerUpdate = 20 -- 10 minutes needs 10/0.5 = 20
timePerUpdate = 30 -- 15 minutes needs 15/0.5 = 30
-- timePerUpdate = 60 -- 30 minutes needs 30/0.5 = 60
end
else -- small map
-- timePerUpdate = 5 -- game time runs at same speed
-- timePerUpdate = 7.5
-- timePerUpdate = 10
timePerUpdate = 15
-- timePerUpdate = 30

end