aduros / wasm4

Build retro games using WebAssembly for a fantasy console.
https://wasm4.org
ISC License
1.16k stars 171 forks source link

Standard source for entropy #534

Open MaxGraey opened 2 years ago

MaxGraey commented 2 years ago

Given that wasm4 is a rather very discrete system, it may not need access to a proper timer as suggested here: https://github.com/aduros/wasm4/pull/365

Instead of a timer, the vast majority of time user can simply use a game loop counter. In addition, on some systems (e.g. on some Arduino) the timer is simply not available.

But what is really needed is a seed to randomize the initial random state from run to run. Of course, you can use entropy harvesting tricks from user's input, but that's a waste of resources (time & wasm size) IMHO. While this could be delegated to the host via adding according API.

hazeycode commented 2 years ago

It would be neat to have a w4.RANDOM_SEED.

But I'd really like a system clock or timer. There's many cases where this is useful and one doesn't want to assume that the game loop is called at a constant frequency. But I hadn't considered that this would limit compatible devices.

ibillingsley commented 2 years ago

I just use a frame counter to seed the PRNG when the user starts the game from the menu screen. In theory you can restart the cart and press start with precise timing to get the same seed, but in practice it's good enough for most games in my opinion.

MaxGraey commented 2 years ago

I just use a frame counter to seed the PRNG when the user starts the game from the menu screen.

It's a good trick, but what if the developer decides not to do the menu at all, and immediately start the gameplay? And only during it bring the player to context (prehistory, control keys, etc.). Or another story, the developer would like that at each new start menu or splash screen would look different every time?

ibillingsley commented 2 years ago

Fair enough, it would be a nice thing to have.

desttinghim commented 2 years ago

I just use a frame counter to seed the PRNG when the user starts the game from the menu screen.

It's a good trick, but what if the developer decides not to do the menu at all, and immediately start the gameplay? And only during it bring the player to context (prehistory, control keys, etc.). Or another story, the developer would like that at each new start menu or splash screen would look different every time?

You could save the random bits to the disk to allow one player to get a different experience each time.

MaxGraey commented 2 years ago

You could save the random bits to the disk to allow one player to get a different experience each time.

The problem is that it is not clear exactly when to do it. And in a way that is nondeterministic. And the user can close the tab / close app at any time. In addition, it looks very unobvious and hacky.

desttinghim commented 2 years ago

The problem is that it is not clear exactly when to do it. And in a way that is nondeterministic. And the user can close the tab / close app at any time. In addition, it looks very unobvious and hacky.

I would save the random state every frame. The point is to maintain the entropy. It's not non deterministic, but it will make the randomness more varied.

I'm approaching this more from a "how can we work around this limitation" point of view though.

TheRektafire commented 2 years ago

Yeah I'd personally save the time since initial game start to disk every frame, it's about as good as having a timer since it could persist between game loads but doesn't require a hardware timer so it's more compatible I would assume