TASEmulators / TASEmulators/BizHawk

[Request] Adding custom TAStudio columns in Lua is very slow; a faster way to do this is needed

Open
#4,756 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

re: Lua API/scripting Repro: Affects 2.11.1 Tool: TAStudio
Dominant language
C#
Stars
2.8k
Forks
468
PR merge metrics
No merged PRs in 30d

Description

I have made a script to show the current game engine time (for TASing Worms Armageddon in the DOSBox-X core), shown below.

It works, but using tastudio.onqueryitemtext, it redraws the entire visible portion of the input roll after every frame. This makes it quite slow, and the larger the TAStudio window is, the slower it is. Without the custom column, the core (set to 120 fps) runs at about 27 fps, but with it, at the window size I usually want TAStudio to be, it drops to 7 fps. For long fast forwards (if 22% of realtime speed can count as a fast forward) I've been resizing TAStudio down to its minimum height, or minimizing it, as a workaround to avoid the slowness.

I would suggest providing a different way to output to a custom column. Probably the best way would be to provide two built-in tastudio Lua functions, one to write a given string to a given row, and one to read the string from a given row. (I'm guessing you can't just expose the custom column as a Lua array, one element per row, which, when written to by the script, can be trapped by BizHawk to trigger an automatic redraw of that row and column.)

On another note, I'd also like a built-in function to do memory searches, because using a Lua loop to do this is very slow. In the script below it takes about 9 seconds even when the search is successful. (Though it only has to be done once per started game round.) Should I file this as a separate issue?
Edit: Issue now filed.

addr = 0

tastudio.addcolumn("time", "Time", 60)
local cache = {}

local id
id = event.onframeend(function()
    local needle0 = 0x5755D0
    local needle1 = 0x800

    if memory.read_u32_le(addr, "Physical RAM") ~= needle0 then -- or memory.read_u32_le(addr+4, "Physical RAM") ~= needle1 then
        local data = memory.read_bytes_as_array(0, 0x03000000, "Physical RAM")

        addr = 0
        for i = 0, #data - 8, 4 do
            local w0 = data[i+1] + (data[i+2] << 8) + (data[i+3] << 16) + (data[i+4] << 24)
            if w0 == needle0 then
                local w1 = data[i+5] + (data[i+6] << 8) + (data[i+7] << 16) + (data[i+8] << 24)
                if w1 == needle1 then
                    addr = i
                    console.log(string.format("Found at: 0x%08X", addr))
                    break
                end
            end
        end
    end
    if addr == 0 then
        event.unregisterbyid(id)
    else
        local value = memory.read_u32_le(addr + 8, "Physical RAM")
        msg = string.format("%d.%02d", value // 50, (value % 50) * 2)
        cache[emu.framecount()] = msg
        gui.text(1, 27, msg)
    end
end)

tastudio.onqueryitemtext(function(frame, column)
    if column == "time" then
        return cache[frame] or "?"
    end
end)
Image

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with TAStudio's custom-column handling and the tastudio.onqueryitemtext entry point, then reproduce the Lua example at the reported TAStudio window size. Done means custom-column values no longer redraw the entire visible input roll on every frame, with the proposed row read/write behavior resolved and the reported slowdown verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua
Domain
desktop, performance, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.