Page 1 of 2 12 LastLast
Results 1 to 25 of 29

Thread: Scripting Examples

  1. #1
    Join Date
    Feb 2015
    Location
    The Internet
    Posts
    1,460

  2. #2
    Join Date
    May 2016
    Posts
    1,072
    I have created an introductory scripting guide to teach the basic functionality of LUA for use with Tabletop Simulator.

    http://steamcommunity.com/sharedfile.../?id=714904631

  3. #3
    Join Date
    May 2016
    Posts
    1,072
    And now I made an intermediate scripting guide to teach intermediate functionality of Lua for use with Tabletop Simulator.

    http://steamcommunity.com/sharedfile.../?id=879449506

    It has a companion workshop table which has various scripting examples included.

    http://steamcommunity.com/sharedfile.../?id=879494019

  4. #4
    Here are some scripting snippets I used in nearly all my mods that others may like !!

    NOTE: - the "code" BBcode screws up the TABS a little!


    Make Objects non-interactable

    This is a great way to make table extensions or other parts of your mod to be locked in place beyond the normal "lock" function. The object will be completely unable to be interactive with by the user, even the host. This includes the "alt+mouseover" zoom view thing. I started using this as I use a lot of custom table extentions and player board, and found that people often accidentally unlocked the table extension and it as well as everything on it falls into the abyss!!

    This script snipet is a GLOBAL script.

    Place this snipet at the top of your global script outside of any function.
    The list here is just an example and The numbers are just GUIDs of objects.
    To get the GUIDs, right click on the objects you want to freeze in your TTS scene and select scripting/guid from the context menu to copy the GUID to clipboard and then paste into the script.
    Code:
    --List for non-intractable objects!
    megaFreezeIT= {  'fc8017', '19d56d', 'a0d75b', 'cbf656', '3d4319', '0b829f', '5c9b8c', '9feb46'}
    Rest of the Code looks like this...
    I have made the actual function separate and called it megaFreeze()
    You need to the megaFreeze() function called fron onLoad()
    Code:
    function onLoad()
    	megaFreeze() -- Make objects non-interactive
    end
    
    function megaFreeze()
    	--megaFreeze ACTIVATE!
    	for i=1, #megaFreezeIT, 1 do
    		obj = getObjectFromGUID(megaFreezeIT[i])
    		if obj ~= nil then
    			obj.interactable = false
    			obj.tooltip = false
    		end
    	end
     end
    Hint!!

    You can break up your megaFreezeIT list with comments to make the GUIDs understandable... like this!!

    Code:
    megaFreezeIT = {  'fc8017', '19d56d', 'a0d75b', -- Table Extensions
    				'cbf656', '3d4319', '0b829f', '5c9b8c', '9feb46' -- Player Boards 1-5
    			 }
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  5. #5
    --== REDUNDANT SO DELETED ==--

    found a much better way to handle what this page was about, so I thought I would delete this to avoid confusion.
    Last edited by Tragic; 09-02-2017 at 01:18 AM.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  6. #6
    @Tragic
    You could rewrite that like:
    Code:
    buttons = {
        DescriptiveName = {
            index = index_DescriptiveName
            click_function = 'buttonFunctionName'
            function_owner = self
            label = 'Press me'
            position = {0, 0.6, 1.5}
            rotation = {0, 0, 0}
            width = 500
            height = =500
            font_size = 200
            },
        AnotherButton = {
            index = index_AnotherButton
            click_function = 'buttonAnotrherFunction'
            function_owner = self
            label = 'Or Me!'
            position = {0, 0.6, -1.5}
            rotation = {0, 0, 0}
            width = 500
            height = =500
            font_size = 200
            }
        }
    
    function createAllButtons()
        for _, button in pairs(buttons) do
            self.createButton(button)
        end
    end
    to save some keystrokes

    By the way, "index" field is ignored when creating buttons. They get a new index value anyway.

  7. #7
    See this asked a lot, so thought I would post Stumps answer here for others.

    How to share Functions and Variables across Objects Scripts.

    Quote Originally Posted by MrStump View Post
    Quote Originally Posted by Tragic View Post
    How can I share variables across different object scripts? I have tried putting things in global, but I still can not access them from other objects.

    Example
    I have a "card list" variable that each player area (I have scripted player boards) needs to access. At the moment I have the entire table copied into every player board script.. so if I ever need to change the variable, I need to change ALL of the copies as well.

    Q1 : How can I set one table variable and have all the boards access it. A "True" Global", so to speak. (Same question for a standard variable)
    Q2: On the same note so the info is in the same area, How would I share a variable / table from one object to another?
    Q3: It would also be cool to be able to share functions.. can they be shared, as a "true global function" or form one object to the other, and if so how?
    getVar or getTable. If you're getting from global, then its Global.getVar(), while an object would be object.getVar()

    A1: Put your table in global. Use Global.getTable('tableNameHere')
    A2: Store the variable somewhere. Then have other scripts access it via getVar or getTable. Failing that, use setVar on all the objects you want to have that variable available and it will inject a variable from one script to other. There is also a setTable.
    A3: That would be the object.call("functionNameHere", parameterTableHere) function. Also works on Global like getVar would.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  8. #8
    Join Date
    Sep 2016
    Posts
    215

  9. #9
    Here are some scripting snippets I used in nearly all my mods that others may like !!

    NOTE: - the "code" BBcode screws up the TABS a little!


    Dynamic Button Index Finding

    When you build a series of buttons upon a single object you need to track the button INDEX values. This is so if you press a button you can edit another button or whatever, and so on.. Each time you have more than 1 button the "index" needs to be reference so it knows which button you are using. The problem is that while indexes are dynamically assigned in acceding numerical order, as you add buttons, delete buttons edit buttons through scripts as well as adding new buttons physically in the code, this "index" order can become rather convoluted.

    This code will dynamically 'find" the index for any given button allowing you to find it and edit whatever button in on your object with ease!

    This code snip-it works like this
    • It will search "self" for all buttons and add them to a list.
    • It will then look at each "button.label" for each button it finds and compare them to the given string. By finding this string it has found the specified button the string is form.
    • It then returns the index of that button


    The Code
    Code:
    function findButtonIndex(label)
        local aButtons = self.getButtons()
        for _, B in pairs(aButtons) do
            --print(tostring(but.click_function))
            if B.click_function == label then
                return B.index
            end
        end
    end
    Usage Example
    Code:
    button_example = {
            click_function = 'addTen',
            function_owner = self,
            label = '10',
            position = {1.2, 0.6, 1.64},
            rotation = {0, 0, 0},
            width = 350,
            height = 800,
            font_size = 650}
    Code:
    button_example = {index=findButtonIndex('addTen'), label = 20}
        self.editButton(button_example )
    • In this example i have only added 1 new parameters, increasing the value of the readout +10 with luck this will make it clear as it is just the way to use the findButtonIndex() function.
    • If you do not know you edit a button by redefining the table you originally used to create it. Change fonts, button sizes, whatever you like AND you need to include the correct index value. The top code is the original button.


    Well, that is that!

    You can now add as many buttons as you like, place them in any order, even copy and paste and move them and you never need to worry about indexs again!

    Hope you like it!
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  10. #10
    Finding Object Tags from ScriptZones and Bags

    Not really sure where I got this code snip from.. I "borrow" a lot from other mods... but i think this is from MrStump...

    Anyway, this is a small function to "find" objects by tag in script zones. You can enter multiple types as well.

    Code:
    function getObjectTypesInZone(zone, ...)
        local foundTypes, tagList = {}, {...}
        for _, object in ipairs(zone.getObjects()) do
            for _, tag in ipairs(tagList) do
                if object.tag == tag then
                    table.insert(foundTypes, object)
                    break
                end
            end
        end
        return foundTypes
    end
    simply call it like this....

    Code:
    getObjectTypesInZone(scriptZone, 'Deck')
    That will return a table with containing any "decks" sound the zone....

    Working Example

    This is a super simple "deal" button using this code...

    Code:
    function deal(num,player,hand,GUID)
        for _, deck in ipairs(getObjectTypesInZone(getObjectFromGUID(GUID), 'Deck', 'Card')) do
            if deck.tag == 'Deck' then deck.deal(num, player, hand)
            elseif deck.tag == 'Card' then
                local prams = {p={0.15, 3.03, -5.67},r={0.00, 180.00, 0.00}}
                deck.setPositionSmooth(prams.p)
                deck.setRotationSmooth(prams.r)
            end
        end
    end
    that is called like this

    Code:
    deal(2,'Green',1,5a4700)
    Last edited by Tragic; 09-06-2017 at 08:00 AM.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  11. #11
    Trimmed down version of Eskanders code - when a card leaves a deck, clones it back to the deck

    Code:
    function onObjectLeaveContainer(container, object)
    	local desc = object.getDescription()
    	if string.find(desc, 'archive') then
    		if container then
    			local params = {}
    			local destination = {}
    			destination = container.getPosition()
    			destination.y = destination.y + 2
    
    			params.position = destination
    			local clone = object.clone(params)
    			desc = string.gsub(desc, 'archive', 'copy')
    			object.setDescription(desc)
    		end
    	end
    end

  12. #12
    Using the inputs to create a search engine for card decks or bags. Type in the search field what you want to look for, click search and it will get it.

    Code:
    function createInput()
    self.createInput({
      input_function = "dud",
      label = "Search",
      function_owner = self,
      alignment      = 3,
      position       = {0,0.2,0},
      width          = 1500,
      height         = 350,
      font_size      = 250,
      color          = {0,0,0},
      font_color     = {1,1,1},
      value = ""
      })
    end
    
    
    function dud() end
    
    
    function createButton()
      self.createButton({
        click_function = "get_Card",
        function_owner = self,
        label = "Search for Card",
        position = {0, 0.2, 1.5},
        width = 2500, height = 350, font_size = 250, color = {0,0,0}, font_color = {1,1,1}
      })
    end
    
    function get_Card()
      local pos = self.getPosition()
      local inputs = self.getInputs()
      for i, v in pairs(inputs) do
        search_param = v.value
      end
      for _, card in ipairs(deck.getObjects()) do
        if card.nickname == search_param then
          deck.takeObject({position = {pos.x, pos.y, pos.z + 4}, guid = card.guid})
        end
      end
    end

  13. #13
    This is my "button creation code"... I find it very easy to use and I use it in nearly every mod.. so I need a place to be able to quickly copy and paste it lol.. so thought this thread would be a good location!

    Code:
    function onload()
        makeButtons()
    end
    
    function makeButtons(set)
        local buttons = {}
    
     -- DEFAULT START BUTTONS    if set == nil then
            button = {
                click_function = 'functionName',
                function_owner = self,
                label = 'Button Lable',
                position = {0, 0.5, 0.5},
                rotation = {0, 180, 0},
                width = 1300,
                height = 350,
                font_size = 200}
            table.insert(buttons, button)
        end
    
     -- Create Buttons
        for _, button in ipairs(buttons) do
            self.createButton(button)
        end
    end
    The way this works is that you have all the button code, which can be really large and ugly, in a function at the bottom of the script nice and out of the way. You place the makeButtons() call in the onload() as normal but can call it at any time.

    The makeButtons() function can take a string input, I use this to allow the same function to be used for all my buttons for that object. I simply can add a "if statement" testing the "set" variable to load different buttons at different times. If nothing is passed as the "set" then it will default to the "== nil" that I have added to this example code.

    Check out my "find button index" code as well for more button madness that I find useful. - Find button index code snippet @Beserk Forum
    Last edited by Tragic; 11-21-2018 at 07:06 PM.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  14. #14
    Thanks for the chess clock script kimiko.

  15. #15
    I wanted to add this code, even though i didn't write it.

    onelivesleft's "wait" function

    This is a cool code snip I was given by the man, the myth, the legend OneLivesLeft.

    Basically it is a "after a time period, do this function"... so ti is another "wait: function.. but little easier to use. Basically add this function anywhere in your object script and then call it as needed.

    Code:
    function after(delay, func, ...)
        local params = {...}
        function after_routine()
            local after_time = os.clock() + delay
            repeat coroutine.yield(0) until os.clock() >= after_time
            func(unpack(params))
            return 1
        end
        startLuaCoroutine(self, 'after_routine')
    end
    example:
    Code:
    after(0.5,self.destruct)
    This code will delete the object after a .05 second delay.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  16. #16


    I'll do you an upgrade, related to this post.

    Code:
    function after(delay, func, ...)
        local params = {...}
        function after_routine()
            if type(delay) == 'function' then
                repeat coroutine.yield(0) until not delay()
            else
                local after_time = os.clock() + delay
                repeat coroutine.yield(0) until os.clock() >= after_time
            end
            func(unpack(params))
            return 1
        end
        startLuaCoroutine(self, 'after_routine')
    end
    Does what the last one did, but can also take a function as the delay parameter; it triggers after the function stops being true.

    So for instance, you can:

    Code:
    -- die is the die object
    die.setPositionSmooth({1, 2, 3})
    after(die.isSmoothMoving, die.roll)

  17. #17
    Remove Duplicates from Table

    I had a terrible time finding this code snipit last night.. much googling and stack exchanged reading until I finally found a bit of code I could get working AND understand lol...

    Code:
    -- Remove duplicates from a table array
    function table_unique(tt)
        function table_count(tt, item)
        	local count
        	count = 0
        	for ii,xx in pairs(tt) do
        		if item == xx then count = count + 1 end
        	end
        	return count
        end
    
    	local newtable
    	newtable = {}
    	for ii,xx in ipairs(tt) do
    		if(table_count(newtable, xx) == 0) then
    			newtable[#newtable+1] = xx
    		end
    	end
    	return newtable
    end
    The above code will go through a table and remove duplicated in that table.... the usage is something like this...

    Code:
    local noDupes = table_unique(tableWithDupes)
    This code is particularly useful when using overlapping scriptzones and getObjects() as an object touching 2 zones will be picked up twice. So you can grab contents off all the scriptzones, then remove duplicates and have a list of only the things you want, and only have them listed once.

    Example Pickup Code



    This mod has a series of script zones on the table that cover all the spots players can place cards.. but the script zones over lap. So cards in two or more zones will get "added" to the table twice.

    Code:
    -- Loop through a series of zones and store data for each "Card" found in a table called "cardPickup".
        local pickupZones = {'06b0c8','ce9f84','85d23e','defe97','f7cae4','5007be','1d0f53'}
        local Y = 1.3
        local cardPickup = {}
        for _, zone in ipairs(pickupZones) do
            for _, obj in ipairs(getObjectFromGUID(zone).getObjects()) do
                if obj.tag == 'Card' then
                    table.insert(cardPickup, obj)
                end
            end
        end
    
        local noDupes = table_unique(cardPickup) -- remove duplicates.
        --Move found cards form cleaned list to discard pile, and increment the Y value between them so they stack well.
        for _, card in ipairs(noDupes) do
            card.setPositionSmooth({14.78, Y, 21.57})
            Y = Y + 0.3
        end
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  18. #18
    script snip that was in THIS reply ( not the one above) has been removed

    --- Found a bug after some more testing... shouldn't have been so quick to post!
    Last edited by Tragic; 01-07-2018 at 02:34 PM.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  19. #19
    @Tragic
    That table_unique function is doing a lot of unnecessary iteration. Try something like
    Code:
    function table_unique(orig)
        local out = {}
        local present = {}
        for _,v in ipairs(orig) do
            if not present[v] then
                out[#out+1] = v
            end
            present[v] = true
        end
        return out
    end
    That's for arrays (number keyed tables).

  20. #20
    Last edited by Confederate In Blue; 04-02-2018 at 08:14 AM. Reason: Added Configurable Clock

  21. #21
    @Tragic, in your megaFreeze() function, do you really need to set obj.tooltip = false?

    It has been my experience that once obj.interactable = false, the tooltip is not displayed even if obj.tooltip is set to true (and there is tooltip text defined, of course).

  22. #22
    no not anymore.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  23. #23

    Laying things out in rows and columns; a cautionary tale

    I am occasionally caught by Lua's table handling...
    When I wrote this in a naive way, I wrote:
    Code:
    function spread(player)
        local deck = Player[player].getHoverObject()
        local anchor = deck.getPosition()
        local pos = anchor
        local offx = 4
        local offz = 0
    
        for i, _ in ipairs(deck.getObjects()) do
            pos.x = anchor.x - offx
            pos.z = anchor.z + offz
            deck.takeObject({position=pos})
            offx = offx + 4
            if offx > 32 then
                offx = 4
                offz = offz + 6
            end
        end
    end
    this puts each card farther over than the last rather than placing them evenly.
    Reason is, tables are references, not values. changing pos.x is also changing anchor.x.

    I had to use variables, like this.

    Code:
    function spread(player)
        local deck = Player[player].getHoverObject()
        local anchor = deck.getPosition()
        local basex = anchor.x
        local basez = anchor.z
        local pos = {x = 0, y = anchor.y, z = 0}
        local offx = 4
        local offz = 0
    
        for i, _ in ipairs(deck.getObjects()) do
            pos.x = basex - offx
            pos.z = basez + offz
            deck.takeObject({position=pos})
            offx = offx + 4
            if offx > 32 then
                offx = 4
                offz = offz + 6
            end
        end
    end

  24. #24
    Reverse a Table

    Code:
        --Reverses a table
        function reverseTable(t)
            local reversedTable = {}
            local itemCount = #t
            for k, v in ipairs(t) do
                reversedTable[itemCount + 1 - k] = v
            end
            return reversedTable
        end
    Shuffle a Table
    make sure you use math.randomseed(os.time())

    Code:
        --shuffle
    function shuffle(tbl)
      for i = #tbl, 1, -1 do
        local j = math.random(i)
        tbl[i], tbl[j] = tbl[j], tbl[i]
      end
      return tbl
    end
    Last edited by Tragic; 11-22-2018 at 03:42 PM.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  25. #25
    Your shuffle mutates the input table *and* returns a copy of it; it should really only do one or the other.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •