Results 1 to 4 of 4

Thread: synchronizing scripts -- can it be done?

  1. #1

    synchronizing scripts -- can it be done?

    My turnButton is giving me fits.

    turnButton.init calls showTurns to configure the UI.

    turnButton.startTurns initializes order and curIndex, then calls initGame in global
    initGame immediately calls getCurPlayer() in turnButton.

    I get:
    Game started by cche
    [red]Red, it is your turn[/red]
    StartTurns: curIndex = 1
    getCurPlayer returns 3
    game started by Black, Green is first.

    Why, oh WHY does the call from Global return a different value than turnButton???

    I have put up the mod in the workshop: https://steamcommunity.com/sharedfil...?id=1367205488


    Code:
    order = {"Red", "Blue", "Green", "Orange" }
    curIndex = 2 -- for example; index into order
    
    function getCurPlayer()
        print("getCurPlayer returns: " .. curIndex)
        return order[curIndex]
    end
    
    function endTurn(player)
        local curPlayer = order[curIndex]
    
        if player and player.color ~= curPlayer then
            sayTo(player.color, "cannot end another player's turn (" .. (curPlayer or "nil") .. ")")
            return
        end
        if verbose then
            print("End of ", curPlayer, "'s turn")
        end
        if Global.getVar("onTurnEnd") then
            Global.call("onTurnEnd")
        end
        curIndex = curIndex + 1
        if curIndex > #order then
            curIndex = 1
        end
        curPlayer = order[curIndex]
        if verbose then
            print("Start of " .. curPlayer .. "'s turn.")
        end
        showTurns({color = curPlayer, text = "End " .. curPlayer .. "'s turn"})
        if Global.getVar("onTurnStart") then
            Global.call("onTurnStart")
        end
    end
    
    function initTurns(player) -- set up the buttons with "start the game".
        showTurns({color = "Black", text = "Start the game"})
    end
    
    function showTurns(params)
        buttonXmlTable.attributes.textColor = params.color
        buttonXmlTable.attributes.text = params.text
        buttonXmlTable.attributes.onClick = "endTurn"
        if params.color == "Black" then
            globalXmlTable.attributes.onClick = self.getGUID() .. "/startTurns"
            globalXmlTable.attributes.textColor = "Black"
            globalXmlTable.attributes.text = params.text
            buttonXmlTable.attributes.onClick = "startTurns"
            tbLayout[2].children[3].children=globalXmlTable
        else
            tbLayout[2].children[3].children = {}
            for _, player in ipairs(order) do
                globalXmlTable.attributes.textColor = player
                if player == params.color then
                    globalXmlTable.attributes.onClick = self.getGUID() .. "/endTurn"
                    globalXmlTable.attributes.text = params.text
                else
                    globalXmlTable.attributes.onClick = ""
                    globalXmlTable.attributes.text = player
                end
                table.insert(tbLayout[2].children[3].children, deepCopy(globalXmlTable))
            end
        end
        local baseUI = Global.UI.getXmlTable()
        if turnGlobalPanel then
            for i, item in ipairs(baseUI) do
                if item.attributes.id ~= "turnButton" then
                    table.insert(tbLayout, item)
                end
            end
            if not Global.UI.setXmlTable(tbLayout) then
                print("tbLayout: Error in Global UI")
            end
        else
            local ui = {}
            for i, item in ipairs(baseUI) do
                if item.attributes.id ~= "turnButton" then
                    table.insert(ui, item)
                end
            end
            if not Global.UI.setXmlTable(ui) then
                print("ui: Error in Global UI")
            end
        end
        local dui = {}
        baseUI = self.UI.getXmlTable()
        for i, item in ipairs(baseUI) do
            if item.attributes.id ~= "turnButton" then
                table.insert(dui, item)
            end
        end
        table.insert(dui, buttonXmlTable)
        if not self.UI.setXmlTable(dui) then
            print("turnButton: error in UI")
        end
        -- Wait.frames(function() print(getObjectFromGUID("8fcc45").UI.getXml()) end, 2)
    end

    Code:
    function initGame(who)
        moveNum = 0
        local player = "Black"
        if who then
            player = who.color
        end
        inGame = true
        firstPlayer = turnButton.curPlayer()
        print("game started by ", player, "; ", firstPlayer, " is first.")
        for _, color in ipairs(turnButton.order()) do
            tokens[color .. "_Engine"].call("setMoveNum", { moveNum = 0 })
        end
        deck.deal(5)
    end -- of initGame
    
    function onTurnStart()
        print("start turnButton: ", turnButton, ", player: ", turnButton.curPlayer())
        if inGame then
            print(turnButton.curPlayer(), "'s turn is starting, curIndex is ", turnButton.obj.getVar("curIndex"))
            if not Player[turnButton.curPlayer()].seated then
                -- print(turnButton.curPlayer(), " is not seated.  Skipping")
                -- return
            end
            if turnButton.curPlayer() == firstPlayer then
                moveNum = moveNum + 1
                broadcastToAll("Round " .. moveNum .. " starting", { 1, 1, 1 })
            end
            local e = turnButton.curPlayer() .. "_Engine"
            tokens[e].call("setMoveNum", { moveNum = moveNum })
            tokens[e].call("setMoved", {moved = ""}) -- also changes display, otherwise I would use setVar()
        end
    end
    
    
    function onTurnEnd()
        print("end turnButton: ", turnButton, ", player: ", turnButton.curPlayer())
        if tokens[turnButton.curPlayer() .. "_Engine"].getVar("moved") == "*" then
            sayTo(turnButton.curPlayer(), turnButton.curPlayer() .. " your turn is over.")
            return true
        else
            sayTo(turnButton.curPlayer(), "End Turn ignored: you have not moved")
            return false
        end
    end

  2. #2

    Whew! Found the problem.

    startTurns called from UI.
    calls Global/initGame
    calls startTurns --- illegal or at least broken
    returns junk
    gets junk
    end

    I fixed it by making the UI call Global/initGame, which executes turnButton.start() followed by turnButton.curPlayer()
    This works.

  3. #3

    Argh The problem mutates ...

    I got initGame to work by passing a parameter instead of using a call.

    It is still the case that my global variables in turnButton are taking inconsistent values.

    Here is the code for turnBUtton.

    Code:
    --[[
        -- turn button
        -- Insert this block of code into your global script:
        turnButton = {
            obj = nil,
            init = function() turnButton.obj.call("initTurns") end, -- initialize th turn system
            start = function() turnButton.obj.call("startTurns") end, -- sets order to getSeatedPlayers and chooses a random first player
            curPlayer = function() return turnButton.obj.call("getCurPlayer") end, -- returns the current player
            setOrder = function(list) turnButton.obj.setTable("order", list) end, -- change the order.  This is an array of player colors.  There are no seating requirements.
            order = function() return turnButton.obj.getTable("order") end, -- returns the current order
            passTurn = function(color) turnButton.obj.call("passTurn", {color = color}) end, -- ends the current player's turn as if the end turn button was pressed.  Useful for AIs
            setTurn = function(color) turnButton.obj.call("setTurn", {color = color}) end, -- sets the current player who must be in the order array.
            previous = function() return turnButton.obj.call("prev") end, -- returns the previous entry in order.
            next = function() return turnButton.obj.call("next") end, -- returns the next entry in order.
            reset = function() turnButton.obj.call("onLoad",  '{"curIndex":0}') end, -- clears all turns status
            toggleVerbose = function() turnButton.obj.call("toggleVerbose") end, -- changes whether the button reports on turn changes.
            toggleGlobalPanel = function() turnButton.obj.call("toggleGlobalPanel"), end, -- turn on/off global turns UI
        }
    
        function onLoad()
            for _, obj in ipairs(getAllObjects()) do
                if obj.getName() == "Turn Button" then
                    turnButton.obj = obj
                end
            end
            if not turnButton.obj then
                print("turnButton not initialized.")
            else
                print("TurnButton " .. turnButton.obj.getGUID() .. " Initialized")
            end
        end
    
    ]]
    order = {}
    curIndex = 0 -- control variable, indexed into order for curent player; 0 means turns disabled
    verbose = true
    turnGlobalPanel = true
    tbLayout = {
        {   tag = "Defaults",
            attributes = { class="bordered",  color="#8F8478", outline="#4444dd", outlineSize="2 -2" },
        },
        {   tag = "Panel",
            attributes = { class="bordered",
                id = "turnButton", width = "150", height = "200", color = "#ffffff00", rectAlignment = "UpperRight", offsetXY = "-150 0",
                allowDragging="true", returnToOriginalPositionWhenReleased="false",
            },
            children = {
                {   tag = "Button",
                    attributes = { id="closeButton", width="20", height="20", rectAlignment="UpperRight", color="#990000",
                        textColor="#FFFFFF", text="X", onClick=self.getGUID() .. "/toggleGlobalPanel" },
                },
                {   tag = "Text",
                    attributes = { text="Turn Button", alignment="UpperLeft", fontSize="18", offsetXY="5 0",
                        fontStyle="Bold", color="#FFFFFF" },
                },
                {   tag = "GridLayout",
                    attributes = { id = "orderList", columns = "1", width = "100%", cellsize="150 25", rectAlignment="TopCenter", offsetXY = "0 -20"},
                    children = {},
                },
            },
        },
    
    }
    
    buttonXmlTable = {
        tag = "Button",
        attributes = { id="turnButton",
            width="250", height="120", position="0 0 -11", colors="#cccccc|#dddddd|#444444|#00000000",
            text="Start the Game", fontSize="30", fontStyle="Bold", textColor="Black", onClick = "initTurns",
        }
    }
    
    globalXmlTable = {
        tag = "Button",
        attributes = { id = "playerButton", width = "150", height = "25",
            text = "Start the Game", fontSize = "20", textColor = "Black",
            colors="#cccccc|#dddddd|#444444|#00000000", onClick = self.getGUID() .. "initTurns",
        }
    }
    
    function deepCopy(orig)
        return JSON.decode(JSON.encode(orig))
    end
    
    function startTurns()
        -- order = getSeatedPlayers()
        -- order = {"Red", "Blue", "Green", "Orange"}
        JSONInput = getNotes()
        print("notes: ", JSONInput)
        if JSONInput == "" then
            order = getSeatedPlayers()
        else
            order = JSON.decode(JSONInput)
        end
        curIndex = math.random(#order)
        local curPlayer = order[curIndex]
        sayTo(curPlayer, curPlayer .. ", it is your turn.")
        showTurns({color = curPlayer, text = "End " .. curPlayer .. "'s turn"})
        print("StartTurns: curIndex is ", curIndex, " order is", JSON.encode_pretty(order))
    end
    
    function initTurns() -- set up the buttons with "start the game".
        showTurns({color = "Black", text = "Start the game"})
    end
    
    function showTurns(params)
        print("showTurns ", params.color)
        buttonXmlTable.attributes.textColor = params.color
        buttonXmlTable.attributes.text = params.text
        buttonXmlTable.attributes.onClick = "endTurn"
        if params.color == "Black" then
            globalXmlTable.attributes.onClick = "initGame(Black)"
            globalXmlTable.attributes.textColor = "Black"
            globalXmlTable.attributes.text = params.text
            buttonXmlTable.attributes.onClick = "Global/initGame(Black)"
            tbLayout[2].children[3].children=globalXmlTable
        else
            tbLayout[2].children[3].children = {}
            for _, player in ipairs(order) do
                globalXmlTable.attributes.textColor = player
                if player == params.color then
                    globalXmlTable.attributes.onClick = self.getGUID() .. "/endTurn"
                    globalXmlTable.attributes.text = params.text
                else
                    globalXmlTable.attributes.onClick = ""
                    globalXmlTable.attributes.text = player
                end
                table.insert(tbLayout[2].children[3].children, deepCopy(globalXmlTable))
            end
        end
        local baseUI = Global.UI.getXmlTable()
        if turnGlobalPanel then
            for i, item in ipairs(baseUI) do
                if item.attributes.id ~= "turnButton" then
                    table.insert(tbLayout, item)
                end
            end
            if not Global.UI.setXmlTable(tbLayout) then
                print("tbLayout: Error in Global UI")
            end
        else
            local ui = {}
            for i, item in ipairs(baseUI) do
                if item.attributes.id ~= "turnButton" then
                    table.insert(ui, item)
                end
            end
            if not Global.UI.setXmlTable(ui) then
                print("ui: Error in Global UI")
            end
        end
        local dui = {}
        baseUI = self.UI.getXmlTable()
        for i, item in ipairs(baseUI) do
            if item.attributes.id ~= "turnButton" then
                table.insert(dui, item)
            end
        end
        table.insert(dui, buttonXmlTable)
        if not self.UI.setXmlTable(dui) then
            print("turnButton: error in UI")
        end
        print("showTurns end")
    end
    
    function onLoad(JSONTurnState)
        Wait.condition(function()
            print("turnButton onLoad start")
            if JSONTurnState and JSONTurnState ~= "" then
                local turnState = JSON.decode(JSONTurnState)
                curIndex = turnState.curIndex
                -- print("onLoad: curIndex becomes " .. curIndex)
                if curIndex ~= 0 and Global.getVar("inGame") then
                    order = turnState.order
                    verbose = turnState.verbose
                    turnGlobalPanel = turnState.turnGlobalPanel or true
                    print("The game continues.")
                    showTurns({color = order[curIndex], text = "End " .. order[curIndex] .. "'s turn"})
                else
                    print("No turns")
                    initTurns()
                end
            end
            print("turnButton Onload done")
        end, function() return Global.getVar("inGame") ~= "loading" end, 10, function() print("turnButton onload: Global timed out") end )
    end
    
    function onSave()
        turnState = { curIndex = curIndex, order = order, verbose = verbose, turnGlobalPanel = turnGlobalPanel }
        return JSON.encode(turnState)
    end
    
    function sayTo(color, message)
        broadcastToAll(message, stringColorToRGB(color))
    end
    
    function getCurPlayer()
        -- print("getCurPlayer: curIndex is " .. curIndex, " obj is " .. self.getGUID())
        return order[curIndex]
    end
    
    function next()
        local ix = curIndex + 1
        if ix > #order then
            ix = 1
        end
        return order[ix]
    end
    
    function prev()
        local ix = curIndex - 1
        if ix < 1 then
            ix = #order
        end
        return order[ix]
    end -- of prev
    
    function passTurn()
    endTurn(Player.Black)
    end
    
    function setTurn(params)
        local curPlayer = params.color
        for i, color in ipairs(order) do
            if color == curPlayer then
                sayTo(curPlayer, curPlayer .. ", it is your turn.")
                curIndex = i
                showTurns({color = order[curIndex], text = "End " .. order[curIndex] .. "'s turn"})
                return
            end
        end
        print(curPlayer, " is not in the player list (order)")
    end
    
    function toggleVerbose()
        verbose = not verbose
        return verbose
    end
    
    function toggleGlobalPanel()
        turnGlobalPanel = not turnGlobalPanel
        if turnGlobalPanel then
            Global.UI.show("turnButton")
        else
            Global.UI.hide("turnButton")
        end
        return turnGlobalPanel
    end
    
    function endTurn(player)
        print("turnButton EndTurn start")
        local color = player.color
        local curPlayer = order[curIndex]
        print("turnButton endTurn: ", curPlayer, ", ", color, ", ", curIndex, ", ", #order)
        if player and player.color ~= curPlayer then
            sayTo(player.color, "cannot end another player's turn (" .. (curPlayer or "nil") .. ")")
            return
        end
        if verbose then
            print("End of ", curPlayer, "'s turn")
        end
        if Global.getVar("onTurnEnd") then
            Global.call("onTurnEnd", {curPlayer = curPlayer})
        end
        curIndex = curIndex + 1
        if curIndex > #order then
            curIndex = 1
        end
        curPlayer = order[curIndex]
        if verbose then
            print("Start of " .. curPlayer .. "'s turn.")
        end
        showTurns({color = curPlayer, text = "End " .. curPlayer .. "'s turn"})
        if Global.getVar("onTurnStart") then
            Global.call("onTurnStart", {curPlayer = curPlayer})
        end
        print("end of endTurn")
    end
    And here are the relevant routines from Global:
    Code:
    function initGame()
        print("initGame called")
        moveNum = 0
        local player = "Black"
        inGame = true
        turnButton.start()
        firstPlayer = turnButton.curPlayer()
        print("game started by ", player, "; ", firstPlayer, " is first. order is ", JSON.encode_pretty(turnButton.order()))
        for _, color in ipairs(turnButton.order()) do
            tokens[color .. "_Engine"].call("setMoveNum", { moveNum = 0 })
            deck.deal(5, color)
        end
        print("end of initGame")
    end -- of initGame
    The results:
    turnButton onLoad start
    No turns
    showTurns Black
    showTurns end
    ** I click either game start button **
    StartTurns: curIndex is 1 order is [ "Blue", "Green" ]
    game started by Black; Blue is first. order is [ "Blue", "Green" ]
    end of initGame
    ** I click end turn for whichever player is first **
    turnButton endTurn start
    turnButton endTurn: nil, Blue, 3, 0

    That is, in startTurns, curIndex is 1 and order is {"Blue", "Green" }; in endTurn, curIndex is 3 and order = {}.


    I have put up the mod in the workshop: https://steamcommunity.com/sharedfil...?id=1367205488
    Is there a better approach?

  4. #4
    Eventually I had to move all the turn management code out of the button script and into global. Ugh. At least I have gone around the problem!

Similar Threads

  1. Scripts not running (Mac OS X)
    By veggiet in forum Scripting Bug Reports
    Replies: 5
    Last Post: 05-29-2018, 11:06 PM
  2. Why do I have to be Online to get Lua Scripts from TTS?
    By maximo1984@ymail.com in forum Scripting
    Replies: 2
    Last Post: 02-19-2018, 02:01 AM
  3. Using Variable Across Scripts
    By Pillowkeeper in forum Scripting
    Replies: 2
    Last Post: 06-20-2017, 06:57 PM
  4. Bag related scripts
    By Tumba in forum Scripting
    Replies: 1
    Last Post: 05-29-2017, 12:53 AM
  5. [ADDED] [v6.6] Scripts
    By madmon121 in forum General Discussion
    Replies: 1
    Last Post: 02-15-2016, 04:03 PM

Posting Permissions

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