Tabletop Simulator – script action by placing a game piece on a tile + Troubleshoot

Tabletop Simulator – script action by placing a game piece on a tile + Troubleshoot 1 - steamlists.com
Tabletop Simulator – script action by placing a game piece on a tile + Troubleshoot 1 - steamlists.com

Instead of using a button to trigger a script action, simulate the board game environment by triggering a script action by placing a game piece on a tile.
 
 
This intermediate guide assumes basic knowledge of lua scripting.
 
 
Usually, a mod will use a button to trigger a script action. This works well, but is not in keeping with TTS as a simulation of a board game.
 
 
Another approach is to use a custom tile or token. The player can trigger a script action by placing a specific game piece on the tile.
 
 

Basic Approach

This approach uses the onCollisionEnter() function. If this function is included in the object script attached to the tile, it will be called every time a game piece makes contact with the tile.
 
 
The onCollisionEnter() function must be in the object script for the tile. It will not work if it is in the global script.
 
 
A simple function looks like this:
 
 
Tabletop Simulator - script action by placing a game piece on a tile + Troubleshoot - Basic Approach - 1A12261
 
 

function onCollisionEnter(collision_info)
 -- collision_info table:
 -- collision_object Object
 -- contact_points Table {Vector, ...}
 -- relative_velocity Vector
 local piece = 'guidaa' -- the guid of the piece that triggers the action
 local guid = collision_info.collision_object.getGUID()
 if guid == piece then
 return Global:call('desiredAction') -- string name of the function to be called
 end
end

 
 
Note that the function is called any time that any object makes contact with the tile, so the first step of the function must be to check if the object making contact is the one that should trigger the action.
 
 
Instead of using the guid to identify the object making contact, you could use the object’s name, description or gmnotes using getName(),getDescription() or getGMNotes() in place of getGUID().
 
 
 

Different Pieces Trigger Different Actions

To take this approach a step further, you could set up different game pieces that trigger different actions when they are placed on the tile.
 
 
Use a function like this:
 
 
Tabletop Simulator - script action by placing a game piece on a tile + Troubleshoot - Different Pieces Trigger Different Actions - 7A65C03
 
 

function onCollisionEnter(collision_info)
 local piece = {['guidaa'] = 1, ['guidbb'] = 2, ['guidcc'] = 3}
 -- guids as keys in the table are easier to check
 local guid = collision_info.collision_object.getGUID()
 local somedata
 -- somedata to pass to the Global script, 
 -- e.g. the action to trigger
 -- include somedata as values in piece{}
 if piece[guid] then
 somedata = piece[guid]
 -- pass somedata to the Global script
 return Global:call('desiredAction', {somedata})
 end
end

 
 
 

Trigger Different Actions by Location Placed

Going further, you could also set up the tile so that the player can trigger different actions by placing a game piece on different places on the game tile.
 
 
For example, you could design the image for the tile to be divided into four quadrants.
 
 
This function triggers different actions depending on which quadrant of the tile is contacted.
 
 
Tabletop Simulator - script action by placing a game piece on a tile + Troubleshoot - Trigger Different Actions by Location Placed - F1650B7
 
 

function onCollisionEnter(collision_info)
 local piece = 'guidaa'
 -- shorthand reference to the contacting obj
 local obj = collision_info.collision_object 
 local guid = obj.getGUID()
 local somedata
 if guid == piece then
 -- find the midpoint between contact points
 local hit1 = self.positionToLocal(obj.contact_points[1] or obj.contact_points[3])
 local hit3 = self.positionToLocal(obj.contact_points[3] or obj.contact_points[1])
 -- use 'or' in case the piece is not entirely on the tile
 local hitx = (hit1.x+hit3.x)/2
 local hitz = (hit1.z+hit3.z)/2
 -- typically, you could divide the tile into quarters using the x and z coordinates
 if hitz < 0 then
 if hitx > 0 then
 somedata = 1
 else
 somedata = 2
 end
 else
 if hitx > 0 then
 somedata = 3
 else
 somedata = 4
 end
 end
 -- pass somedata to the Global script
 return Global:call('desiredAction', {guid, somedata})
 end
end

 
 
This last step can be tricky, because it is not always intuitive how the x,y,z coordinates in TTS are determined. For example, it can depend on how the tile is rotated or flipped. You may need to experiment a bit. You could add the line log(hitx..” “..hitz) to the function to output the values to the console as you experiment.
 
 
 

Variation

The purpose of the approach described here is to trigger a game action when a player places a relevant piece on the tile. That is why this approach uses the onCollisionEnter() function.
 
 
If instead you want the function to activate only when it is called in the script, you could use a slightly different approach. For example, you may want the script to check an option that a player has chosen. The guide linked below describes that approach.
 
 
https://steamcommunity.com/sharedfiles/filedetails/?id=2791840686 – [steamcommunity.com] 
 
 
 

Troubleshoot

The onCollisionEnter() function may be triggered multiple times if a piece jostles against the tile. A fix for this is to avoid triggering the function if not enough time has passed since the tile was last contacted. To do this, include this code at the beginning of the function.
 
 
Tabletop Simulator - script action by placing a game piece on a tile + Troubleshoot - Troubleshoot - 77F5B9E
 
 

if Time.time - (seconds or 0) < 1 then
 return
else
 seconds = Time.time
end

 
 
Note that the variable for seconds has to be a global variable. If it is not, it may be reset every time the function is called. Watch out for conflicts with other global variables.
 
 

 
 

Written by CareyMcDuff

 
 
I hope you enjoy the Guide we share about Tabletop Simulator – script action by placing a game piece on a tile + Troubleshoot; if you think we forget to add or we should add more information, please let us know via commenting below! See you soon!
 
 


Be the first to comment

Leave a Reply

Your email address will not be published.


*