Skip to content

Workaround for Lua execution time limit in 1.15.9 Hardcore #379

Description

@esuvii

I also ran up against the Lua execution time limit in an addon I was developing this month. I solved this using coroutines.

The issue is that there is a hard limit on the execution time allowed for scripts per frame rendered to the screen - to prevent the game freezing up while a long script executes.

The fix is relatively simple. Turn your slow function into a coroutine, then call coroutine.yield() to pause it during the slow part of the script (e.g. inside a loop or wherever).

Then you want to make a handler, say stepCoroutine(), that steps through your slow function (now coroutine), let's call it myCoroutine(). You build the step-through handler something like this:

local myCoroutine = nil
local function stepCoroutine()
    -- if coroutine is finished
    if not myCoroutine or coroutine.status(myCoroutine) == "dead" then
        myCoroutine = nil
        return
    end
    
    -- step the coroutine
    local success, error = coroutine.resume(myCoroutine)
    if not success then
        -- some error here, handle it however you like (e.g. combat lockdown)
    end

    -- if coroutine isn't finished step it on next game frame
    if coroutine.status(myCoroutine) ~= "dead" then
        C_Timer.After(0, stepCoroutine)
    else
        -- we finished!
    end
end

To actually start the coroutine wherever it needs to be in your code you would do something like:

myCoroutine = coroutine.create(function()
    -- some code here

    for _, item in ipairs(mySlowLoop) do
        -- do some stuff then pause
        coroutine.yield()
    end

    -- do more stuff
end)
-- then just call the step-through function to actually start it:
stepCoroutine()

This is just a basic skeleton / example, of course you can fully tailor it to your needs. In my addon I also tracked combat lockdown and had a frame register for when it ended to resume my coroutine etc, but that is not at all required if you aren't doing anything that could cause tainted execution.

Anyway, that is how I would suggest getting around the execution time per frame limit.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions