Log In  

I have discovered a pretty frustrating bug related to header.lua, resume and menuitem()

Have a look:

It seems that trying to use a menuitem after editing ANYTHING using IMMEDIATE MODE Crashes pico-8 with the error ATTEMPT TO CALL UPVALUE "_SUPERYIELD" (A NIL VALUE).

It says its being called in FLIP(), so lets look at header.lua...

You can see _SUPERYIELD() being called if the pause menu is supposed to stay open. no problem here, right? WRONG!

All of these "special" functions, like _SUPERYIELD() Are "Jettisoned" after they have done their jobs. that means they are all set to nil, so the user isnt able to ruin the device. We can see this at the end of header.lua. Here we can see all the original functions being reset. They still work only in header.lua though, because theyve been set to local variables for use in the header only.

No big deal, though, right? WRONG AGAIN! You might think that it should be fine as we can clearly see them all being reset at the START of header.lua:

But in reality, Header.lua is ONLY ran when you RUN the cart! that means if you exit the cart and change a value in immediate mode, and resume the cart, suddenly, all those special functions are all nil! This breaks a few functions, most notably, MENUITEM(). Menuitem, when its function returns true, sets a special variable that FLIP() uses to tell pico-8 not to close the menu. it also calls _SUPERYIELD... Im sure you can see the issue here. The local function its tying to use is nil because it got reset at the end of the header, and we cant change it in code because its, well, a local function.

Im not sure what could be done to fix this @zep, im thinking something like calling header again on resume, removing local, or something similar?

P#147679 2024-04-30 21:51 ( Edited 2024-04-30 21:53)

1

Why are they even being reset after the header runs? they're all local to the header because it's wrapped in a do ... end statement, so it shouldn't be possible to access them outside of the header anyway (lexical scoping).

P#147681 2024-04-30 21:58

@Soupster it only flushes out the global versions. _superyield is the local that used to exist, __superyield is the global that was jettisoned, and presumably overwrote the local at some point

P#147682 2024-04-30 22:08

Tbh my explanation here sucks, feel free to rephrase it bc I got a few things wrong and can't revise rn

P#147684 2024-04-30 22:36
1

Wait... Why is _superyield (1 underscore) nil? At the start of header.lua it's set to __superyield (2 underscores), and at the end, __superyield (2 underscores) is set to nil. But _superyield (1 underscore) should still be a function, as the function itself wasn't changed. The only way _superyield (1 underscore) would be nil would be if header.lua was run again, while __superyield (2 underscores) was nil...

P#147686 2024-04-30 23:17

[Please log in to post a comment]