TASEmulators / TASEmulators/BizHawk
[Request] Adding custom TAStudio columns in Lua is very slow; a faster way to do this is needed
Nobody has claimed this yet.
- 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)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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