Jump to content

Need Advice from Experienced Lua Programmer


Recommended Posts

Can someone experienced with Lua explin why this bit of code isn't doing what it is supposed to be doing?

    local DaysPassed = GLOBAL.GetClock():GetNumCycles()
        -- should set variable "DaysPassed" to number of days passed in game. Assuming Cycles == Days
    if GetSeasonManager() then local ThisSeason = GetSeasonManager():GetSeason() end
        -- should set variable "ThisSeason" to current season
    if ThisSeason == SEASONS.SPRING then local LeekSeason = 0.03 else local LeekSeason = 0 end
        -- If "ThisSeason" is spring this should set variable "LeekSeason" to 0.03, any other season the variable is set to 0
    local LeekChance = (( 1 / ( 1 +( DaysPassed*0.1)) * 0.05 ) + LeekSeason )
        -- should set "LeekChance" variable based on DaysPassed and LeekSeason variables
 

Link to comment
Share on other sites

  1. If the clock isn't loaded yet, then it can't tell you the right time. I merely assume this is the problem here.
  2. Same as above.
  3. You should ideally declare "leekseason" outside of the if-block, other than that the line should be working.
  4. LeekSeason is just being added at the end of the calculation (instead of, say, multiplication), is this your intention? Also, the chance never stops rising, which is fine when comparing it with math.random(), but not ideal for further calculations.
Link to comment
Share on other sites

10 hours ago, Mobbstar said:
  1. If the clock isn't loaded yet, then it can't tell you the right time. I merely assume this is the problem here.
  2. Same as above.
  3. You should ideally declare "leekseason" outside of the if-block, other than that the line should be working.
  4. LeekSeason is just being added at the end of the calculation (instead of, say, multiplication), is this your intention? Also, the chance never stops rising, which is fine when comparing it with math.random(), but not ideal for further calculations.

Thank you @Mobbstar
1 & 2> So how would I load the clock?
3> Ok I will move it.
4> Yes, Leek season should add a  flat increase. But I plan to revise the final formula once I get it working.

Actual Final Formula

Spoiler

(0.03 + (1 / ( 1 + (DaysPassed * 0.1) ) * 0.05 ) + LeekSeason )
Should give a result of 0.075 on day 1 dropping rapidly over the first 30 days to 0.04 and then approaching but never quite reaching 0.03.
During Spring or 'LeekSeason' the chance increases by a flat 0.03 in all situations.

 

Link to comment
Share on other sites

5 minutes ago, Mobbstar said:

You don't "load the clock", you wait until the clock is loaded. "AddSimPostInit" functions run after loading.

So does that mean this idea won't work? In testing the mod, the chances never seem to change
I even tried: if (DaysPassed) <= 3 then <produce effect> ...Which should have a 100% chance of producing the effect until day 3, at which it should have stopped, but it seemed to just keep going. (of course It may have been due to a different problem)

I should have explained earlier I have no formal training in any programming language, and my only knowledge of lua is self taught from digging through the forums here and exploring the game files, and also quite a bit of 'lets see what happens when I do this' modding.

 

Link to comment
Share on other sites

15 minutes ago, MidrealmDM said:

So does that mean this idea won't work? In testing the mod, the chances never seem to change
I even tried: if (DaysPassed) <= 3 then <produce effect> ...Which should have a 100% chance of producing the effect until day 3, at which it should have stopped, but it seemed to just keep going. (of course It may have been due to a different problem)

where do you call the code? in modmain or a component or... ?

Link to comment
Share on other sites

Yes, sorry  @Mobbstar - the code is in modmain.lua and adds a function to the core game's 'grass' prefab

to spawn a modded prefab "garleek" when the grass is picked.

It works fine if I simply use a math.random() < xx chance to spawn the item.
But what I was trying to do is to have the chance affected by days played and current season.

Attempt #1 - Based on Days Played

Spoiler

AddPrefabPostInit("grass", function(inst)
    inst:ListenForEvent("picked", function(inst, data)
            if GetClock():GetNumCycles() <=3 then -- if days played is less than 3 produce garleek prefab
                SpawnLeek(inst, "garleek")
       end
    end)
end)

RESULT: Crash when grass is picked - error: "attempt to call global 'GetClock' (a nil value)"

=-=-=-

Attempt #2 - Based on Days Played

Spoiler

AddPrefabPostInit("grass", function(inst)
    inst:ListenForEvent("picked", function(inst, data)
            if GLOBAL.GetClock():GetNumCycles() <=3 then -- if days played is less than 3 produce garleek prefab
                SpawnLeek(inst, "garleek")
       end
    end)
end)

RESULT: Game does not crash, but leeks continue to spawn after day 3, function is not getting accurate day count

=-=-=-

Attempt #3 - Based on Season

Spoiler

AddPrefabPostInit("grass", function(inst)
    local ThisSeason = nil
    if GLOBAL.GetSeasonManager() then local ThisSeason = GLOBAL.GetSeasonManager():GetSeason() else end

    local LeekSeason = 0    
    if ThisSeason == SEASONS.SPRING then local LeekSeason = 1 else end

     inst:ListenForEvent("picked", function(inst, data)
            if math.random() <= LeekSeason then -- should be 100% chance of garleek in spring, 0% all other season
                SpawnLeek(inst, "garleek")
        end
    end)
end)

RESULT: No Crash - but spring does not produce leek when grass is picked

Link to comment
Share on other sites

"Cycles" are completed days, not started ones.

The third one does not work because in spring you make a new "local leekseason" that does not leave the if-block. Instead, refer to the previous one (remove the "local").

Link to comment
Share on other sites

First @Mobbstar, thank you again for your patience and assistance.

Ok - That worked somewhat, I can get the day count portion working
Although I can't seem to make another variable to equal the day count,
I can simply use "( GLOBAL.GetClock():GetNumCycles() )" in mathmatical formulas.


As for the seasonal - I simplified it down to this...

Spoiler

AddPrefabPostInit("grass", function(inst)
    local LeekSeason = 0    
    local season = GetSeasonManager():GetSeason() -- Line 551
           if season == SEASONS.SPRING then LeekSeason = 1 else end

     inst:ListenForEvent("picked", function(inst, data)
           if math.random() <= LeekSeason then SpawnLeek(inst, "garleek") else end
-- should be 100% chance of garleek in spring, 0% all other season
    end)
end)

-- I get an error
../mods/waiter-381565292/modmain.lua:551: attempt to index global 'GetSeasonManager' (a nil value)

I checked the code against that from the Birchnut Tree (the part that controls the leaf colors changing)

Spoiler

        local season = GetSeasonManager():GetSeason()
        if season == SEASONS.AUTUMN then
            inst.target_leaf_state = "colorful"
        elseif season == SEASONS.WINTER then
            inst.target_leaf_state = "barren"
        else --SPRING AND SUMMER
            inst.target_leaf_state = "normal"
        end

?? Its the same bit of exact code, but mine crashes

Link to comment
Share on other sites

17 hours ago, Mobbstar said:

You're doing this in modmain, you need to add "GLOBAL." in front of it. Because reasons.

Ahh - ok - Gotta love them reasons

Attempt#1

Spoiler

AddPrefabPostInit("grass", function(inst)
    local LeekSeason = 0    
    local season = GLOBAL.GetSeasonManager():GetSeason()
        if season == GLOBAL.SEASONS.SPRING then LeekSeason = 1 else end

     inst:ListenForEvent("picked", function(inst, data)
            if math.random() <= LeekSeason then -- should be 100% chance of garleek in spring, 0% all other season
                SpawnLeek(inst, "garleek")
        end
    end)
end)

Game started in Spring Time, Function seemed to work properly - dropping Garleek prefap 100% of the time
I changed the season with console command "GetSeasonManager():StartAutumn()" and Garleek continued dropping.
It should have 0% chance.

Attempt#2

I decided that LeekSeason was not being changed to 0 when season changed from spring to other season.

Spoiler

AddPrefabPostInit("grass", function(inst)
    local LeekSeason = 0    
    local season = GLOBAL.GetSeasonManager():GetSeason()
        if season == GLOBAL.SEASONS.SPRING then LeekSeason = 1 else LeekSeason = 0 end

     inst:ListenForEvent("picked", function(inst, data)
            if math.random() <= LeekSeason then -- should be 100% chance of garleek in spring, 0% all other season
                SpawnLeek(inst, "garleek")
        end
    end)
end)

Game started in Spring Time, Function seemed to work properly - dropping Garleek prefap 100% of the time
I changed the season with console command "GetSeasonManager():StartAutumn()" and Garleek continued dropping even in other seasons.

Tried again, starting a game in Autumn and nothing dropped, changed to spring time and still nothing.

So, it only worked based on the initial starting season...

This led me to conclude that it was only checking for leek season once at game startup, and not when the grass was picked.

Attempt #3

Spoiler

AddPrefabPostInit("grass", function(inst)
    local LeekSeason = 0    
    
    inst:ListenForEvent("picked", function(inst, data)
    local season = GLOBAL.GetSeasonManager():GetSeason()
        if season == GLOBAL.SEASONS.SPRING then LeekSeason = 1 else LeekSeason = 0 end
        if math.random() <= LeekSeason then -- should be 100% chance of garleek in spring, 0% all other season
                SpawnLeek(inst, "garleek")
        end
    end)
end)

Moved the part to check the season into the listen for picked event, so it would check the season when picked - and Perfection!

Thank you @Mobbstar

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...