[Solved] Scenario Lua not loading first time

Discussion in 'Programming' started by RyvyLo, Jun 23, 2016.

  1. RyvyLo

    RyvyLo
    Expand Collapse

    Joined:
    May 15, 2014
    Messages:
    438
    Here's the problem : If I load my scenario from the Scenario menu, the lua script won't activate. But, if I reset the scenario then the lua will work. I would like the lua to work since I select the scenario from the Scenario menu.

    Here's how I tell the extension to load in the .json : "extensions": [ "race","test" ],

    Here's a simplified version of the lua ( the file is test.lua and is in Documents\BeamNG.drive\lua\scenario) :
    Code:
    local M = {}
    print("Hello world")
    return M
    I also noticed a message on the console that might help to solve the problem : (it only shows up after a restart of the scenario, when the lua script actually works)
    Code:
    GELua.lua.utils|{
    GELua.lua.utils|    name = "maze1"
    GELua.lua.utils|    optional = true
    GELua.lua.utils|}
    (maze1 is the name of the prefab and the .json loaded in this scenario)

    If you can't see the problem from these indications, please ask me for the files I'll PM them to you ( I don't want these posted in public to not spoil my next mod update )
     
  2. Scepheo

    Scepheo
    Expand Collapse

    Joined:
    Feb 10, 2015
    Messages:
    601
    That console message simply displays the attempt to load the optional "maze1" Lua extension: that attempt is what causes a Lua file with the same name as the scenario to be automatically loaded.

    Try checking the log instead of the console for the output of your script: there's a bug in the console that causes it to not display all output written to it, but the log does contain it (this is easily reproduced by executing "print(1)" a few times in vehicle Lua).

    That said, this would be a lot easier to analyse with your code. I'm not sure why you're worried about spoilers, as A) you already posted what you were doing elsewhere and B) most people can't understand Lua anyway, but feel free to PM me the files.
    --- Post updated ---
    Your scenario Lua gets loaded fine. Your problem is that you're executing code when the scenario Lua is executed, which happens before the map is even loaded. This is why it works when you reset: it re-executes the Lua, then restarts the scenario.

    You want to execute your code in a hook that happens somewhere near the start of the scenario: onRaceInit (or onScenarioChange, as long as you only execute when state == 'pre-start') will probably do.
     
    • Like Like x 1
  3. RyvyLo

    RyvyLo
    Expand Collapse

    Joined:
    May 15, 2014
    Messages:
    438
    Thank you very much for the clear explanations

    I had trouble making the hook, so I just took (a lot) of inspiration from one of your function in your random tour scenario. Here's the final code :
    Code:
    local function functionName()
         [the function]
    end
    
    local function onScenarioChange(scenario)
        if scenario and scenario.state == 'pre-start' then
            log('I', 'mazes.onScenarioChange', 'Scenario started, starting set-up')
            functionName()
            log('I', 'mazes.onScenarioChange', 'Scenario set-up complete')
        end
    end
    
    return {
        onScenarioChange = onScenarioChange
    }
    It's working, but I have difficulties understanding how the hook works. I understand the function onScenarioChange, but the "return onScenarioChange = onScenarioChange" seems a little counter-intuitive for me. Do you have any idea of what it does ?
     
  4. Scepheo

    Scepheo
    Expand Collapse

    Joined:
    Feb 10, 2015
    Messages:
    601
    If I didn't, I wouldn't have typed it. What you'll see in many official scripts is something like the following (with comments, to explain what's happening):
    Code:
    -- Create an empty object M
    local M = {}
    
    -- Declare a function
    local function doStuff()
        doCoolStuff()
        doMoreStuff()
    end
    
    -- Assign our function to a field on the object called 'onScenarioChange'
    M.onScenarioChange = doStuff
    
    -- Return our object
    return M
    Now when this is executed, the extension manager looks at all the fields on the returned object and remembers them. Then, some part of the game Lua calls extensions.hook('onScenarioChange'), the extension manager looks at all fields called "onScenarioChange", finds ours, and calls the function.

    What I do is simply another way of building the object: instead of declaring an empty object, I declare one with a field called "onScenarioChange" that has the value "doStuff":
    Code:
    -- Create our object
    local M = {
        onScenarioChange = doStuff
    }
    
    -- Return our object
    return M
    Except instead of first assigning it to M, I directly return it. There's many other ways to create the object, you could use the indexing syntax instead of the field syntax:
    Code:
    local hookName = "onScenarioChange"
    M[hookName] = doStuff
    or you can create the whole object in one go:
    Code:
    return {
        onScenarioChange = function()
            doCoolStuff()
            doMoreStuff()
        end
    }
     
    • Like Like x 1
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice