I'm wondering if there are any community-established methods for profiling performance of a PICO-8 program. It's come to my attention that a game I'm working on lags substantially on less-new hardware and I'd like to have some way of profiling which functions are taking the longest to run, so I don't waste my time optimizing the wrong parts of the program.
Any tips? Thanks! :)
Check out the stat() function in the manual! :) You can use it to display CPU and memory usage and FPS. Odds are the limitations you're running into are built into Pico-8, though, and not the host system; the speed is artificially limited, for consistency with the retro theme and other limitations.
Not sure the issue is built into PICO-8 - the program runs great on my new computer and phone, but not on my friend's older computer and phone.
Thanks for the tip on using stat()
! I'll check it out.
Hm - I checked out stat but I'm not sure it gives me exactly what I'm looking for. Rather than checking system performance in general I would like to know specifically which functions are taking longer to run than others.
PICO est a virtual console, it runs at constant speed unless the host is severely underpowered.
I suspect pico on your friend's computer is running at 30 fps and your game uses _update60 (e.g. 60fps). That would explain the general 'it's slow' feedback.
Hey, thanks for the response. Indeed we are using _update60() - the game is running on the other machine maybe close to 30 fps but drops down to maybe 5 or 10 when "exciting" stuff is happening.
I simply think we're doing too many things on each cycle (maybe during update, not draw?) and the older hardware doesn't keep up.
What would help me is a tool to tell me which functions are taking a long time to run. I was hoping something might already exist, but if not I might try to develop something myself. :)
I use multiple stat(1) calls and commenting out function calls to do what you're asking. Which is not to say that that's ideal but I'm used to working with minimal IDE support(an equivalent question would be - print statements instead of a debugger).
Note that stat(2) is like stat(1) but only measures time spent inside of API calls. For most games, the bulk of API call time is drawing, so it can help you compare overall time to time spent drawing.
I'm used to print statements over debugging - in fact I prefer it (It's my JavScript bias showing), but even in JavaScript land where I never use a fancy IDE I always use the Chrome profiler to debug speed issues. It's much easier than guessing.
But I think these tips are pretty valuable - That's a good point @triplefox that using stat in combination with commenting out code should probably help me zero down pretty quickly - and thanks @Felice for pointing out stat(2) (seems not to be documented?). I'll try this out and see where I land! :)
Hi Ben,
To piggyback on @freds72 's comment...
Pico8 itself actually taxes a lot of older hardware. Remember, pico8 is pretending to be a primitive set of instructions, but it actually is much more resource intensive than it lets on.
You can really see this on old raspberry pi's or pocketCHIP. I was playing 8venture on pocketchip, and scenes with lots of graphics (the snowy area) lagged like crazy, even though they ran smoothly on my pc and in a browser.
There are two messages here - 1, your friend's computer is probably pretty weak, and is struggling to go as fast as pico8 wants it to.
- I don't think you will be able to troubleshoot this inside pico8. Maybe someone more knowledgeable can correct me, but the stat commands will probably say the same things on your pc and your friend's, even though it appears to run worse on your friend's pc. pico8 artificially slows down certain functions so you can't draw too much or do to many calculations, so there is an upper limit on how fast you can do things. However, these artificial limits are often faster than older hardware can handle, and there's not much you can do about it except for commenting out certain effects and just watching it. Your friend's computer may even say 60 fps when it clearly isn't.
Anyways, I hope this helps. Please correct me if I am wrong.
Even if the stat command displays the same information it's fine - what's important is that I can find the comparatively longest running functions and optimize them to be faster. :)
P.S. I have begun an attempt at a program that will wrap all functions in a pico-8 program with another function than measures the running time of the inner function and saves it. The trouble is (or probably will be) that the time() function isn't exact enough to deliver meaningful measurements. I could be wrong though! If an inner function is taking multiple milliseconds to run, that's a good sign of something to optimize.
Given the time investment required in writing this program though, I'll probably resort to just using the stat() function in the short term.
Yeah, stat(1) measures the fantasy cpu clock. I think even if your real cpu were a C64 running the app at 2 frames per day, you'd still get the same stat(1) value.
C'mon now, the C64 could get far more than 2 frames per day. I'm leaving it at that though before I go porting pico-8 to C64. I know myself well enough to stop when I'm ahead.
I agree with you, stat(1) is the way to go. It's pretty much all I use to optimize.
I usually start by saving stat(1) at the beginning and end of my _draw(), then printing both. Ie:
function _draw(): b4_drawing = stat(1) ... (all my draw code)... after_drawing = stat(1) print(b4_drawing) print(after_drawing) end |
More likely than not, after_drawing will be huge, and you'll want to start sticking other ones in there to see exactly where the hitch is. It's worthwhile to put one at the beginning, though - you may be looping through data structures alot or checking unnecessary collisions or something, driving up your update usage. Most of my game optimization has come down to fine-tuning the update step.
[Please log in to post a comment]