api to skip frames
for games, it's often more important to provide a constant game speed than drawing every single frames. it would be nicer for wasm4 to provide a mechanism for skipping frames. especially for graphics-heavy games on slow hardware.
eg. a simple timestamp (maybe in fps) on the shared memory area.
static unsigned int n = 0;
update()
{
if (TIMESTAMP > n++) {
/* somehow reduce computation for this frame */
}
}
You could set the SYSTEM_PRESERVE_FRAMEBUFFER flag in SYSTEM_FLAGS and then skip drawing depending on frame number.
Example drawing at 30fps:
#include "wasm4.h"
const size_t FRAME_SKIP = 2; // Draw every 2nd frame
void start() {
*SYSTEM_FLAGS |= SYSTEM_PRESERVE_FRAMEBUFFER;
}
size_t frame = 0;
void update() {
frame++;
if ((frame % FRAME_SKIP) == 0) {
// Regular processing here
rect(10, 10, 32, 32);
}
}
if you know the system is fast enough to handle 30 fps, maybe it works. otherwise, maybe not.
also, i prefer an api to allow 60 fps on the first machine.
btw, i think it can be useful to provide a way for the update callback to tell wasm4 that it made no user-visible changes to the frame buffer/palette/etc. so that wasm4 can skip its entire graphic processing for the frame.
I suppose in addition to SYSTEM_PRESERVE_FRAMEBUFFER there could be SYSTEM_SKIP_RENDERING for skipping the screen-blit completely. 🤔
There could also be a SYSTEM_REQUEST_LOW_FRAMERATE that is set by the runtime rather than the game, letting the game detect it and then use the SYSTEM_SKIP_RENDERING flag however often it wants. Games that don't support it would simply ignore it.
Though... I'm not sure if devices that can't even blit the framebuffer to screen at 60fps are in scope for WASM-4, since that's part of its design, and working around it introduces this kind of complexity.
Instead, I would suggest looking into transpiling the WASM to your hardware and running games natively instead. There this cool project called wasm4-aot specifically for that you could take a look at!
I suppose in addition to
SYSTEM_PRESERVE_FRAMEBUFFERthere could beSYSTEM_SKIP_RENDERINGfor skipping the screen-blit completely. 🤔 There could also be aSYSTEM_REQUEST_LOW_FRAMERATEthat is set by the runtime rather than the game, letting the game detect it and then use theSYSTEM_SKIP_RENDERINGflag however often it wants. Games that don't support it would simply ignore it. Though... I'm not sure if devices that can't even blit the framebuffer to screen at 60fps are in scope for WASM-4, since that's part of its design, and working around it introduces this kind of complexity.Instead, I would suggest looking into transpiling the WASM to your hardware and running games natively instead. There this cool project called wasm4-aot specifically for that you could take a look at!
well, i also want to reduce power consumption eg. when playing non-realtime games like puzzles on a phone.
I like the idea of SYSTEM_SKIP_RENDERING being settable by the game. We could also have it be settable by the runtime for frames that it knows won't be rendered anyways, such as during a netplay rollback fast-forward.
We could also have a system flag settable by the game to skip the entire update next frame, basically opting into 30hz update mode?
I also agree with @JerwuQu though that we probably shouldn't go crazy with supporting devices that can't run at 60hz. Not sure!