Log In  


I'm thinking this is a problem.

Try out this simple program. Run it. It runs correctly.

-- error with local time()

function _init()
  cls()
  ?"*"
  timeout(1)
  ?"*"
end

function timeout(n)
local t=time()
  while time()-t<n do
    flip()
  end
end

Now right then type in immediate mode: timeout(1) followed by ENTER.

It HANGS. I was thinking I was doing something wrong in the code I've been working on the past month now and no, it's something Pico-8 is doing ...

This does work correctly if you run it in immediate mode in Pico-8 v0.2.0. So it is something that has changed in the system since then, @zep.



I got a bit long winded (as usual) but this reddit thread has a potential solution for you. Basically flip() eats up a frame's worth of time. Assuming immediate mode is updating at 30 fps then you can delay for one second by calling flip() 30 times in a loop. Multiply by however many seconds you want to wait.

My long winded speculation about why your existing code stopped working:


According to the manual:

> TIME()
> T()

> Returns the number of seconds elapsed since the cartridge was run.

>This is not the real-world time, but is calculated by counting the number of times _UPDATE or @_UPDATE60 is called. Multiple calls of TIME() from the same frame return the same result.

So even though you're not defining _update(), presumably when you run the cart Pico-8 is providing you with a default one anyway. But when you call your timeout() function in immediate mode Pico-8 doesn't provide you with an _update() function, time() never updates and you're stuck in an infinite loop.

However:

  1. Even if you define a dummy _update() function that doesn't do anything, timeout() still hangs in immediate mode. (Also the program doesn't terminate when run because of _update() but that's a different problem.)
  2. Even if you call _update() in timeout(), it hangs in immediate mode so "calculated by counting the number of times _UPDATE or @_UPDATE60 is called" doesn't tell the whole story.

As far as what changed between v0.2.0 and now, I can't say. I skimmed through the changelog and nothing obvious jumped out at me so this is just speculation:

Obviously the _update() functions we write in Lua are just hooks called by a more complex update type function which is part of the Pico-8 runtime and which, among other things, updates the value reported by time().

So we can imagine something like this (but probably written in C or whatever):

-- a bunch of code updating all sorts of stuff in the Pico-8 runtime....
update_time_value()
if not IMMEDIATE_MODE then
    _update()
end
-- a bunch more code updating all sorts of stuff in the Pico-8 runtime....

So if we're not in immediate mode _update() will always exist because either we defined it or we were provided with one as a default. If we are in immediate mode _update() may or may not exist but it will never run. Notice though that in this setup, update_time_value() is always being called even if _udpate() isn't. Now consider this small change:

-- a bunch of code updating all sorts of stuff in the Pico-8 runtime....
if not IMMEDIATE_MODE then
    update_time_value()
    _update()
end
-- a bunch more code updating all sorts of stuff in the Pico-8 runtime....

The update_time_value() will only be called if the cart is actually run. Importantly, it's only being called if _update() is also called. I'd guess something like that is happening.


That's ... quite the answer, @jasondelaat, and thanks for responding.

I was just pointing out that timeout() works correctly in Pico-8 v0.2.0 but not the version past that.

If it's something @zep wants to fix, that's fine. If not, for instance, it is running correctly NOW the way it is supposed to where it hangs, then that is also fine.

It does get confusing sometimes though when you can do one thing in a version and have it fail in later versions.



[Please log in to post a comment]