Closed clementfung closed 5 years ago
This randomness API has been changed in the SDK as of https://github.com/oasislabs/oasis-game-core/commit/9bc0b22624a8e0a0475697f7b081f1f2202cb172.
Now, instead of the seed being a field on the Flow
struct, it's available as a static variable, and can be accessed from any method (in Flow
or in Moves
) with:
let seed: u128 = unsafe { get_seed() };
The seed is incremented after each game move, so it'll be unique when accessed across moves.
Unfortunately, Rust is really strict about mutable static variables (and the seed must be mutable), so accessing it requires an unsafe
call.
*Note: Other attempts at using a safer wrapper structure for the seed (with lazy_static!
) failed due to the static var being pruned during WASM optimization. Without those optimizations, the total code size is too large (~700 KB) and Oasis rejects the transaction. This approach should work reliably, since there's only one thread anyway.
From the battleship_demo, right now the easiest way to get randomness is in the
initial_state
method, fromself.seed
. Once this seed is set, the state of game is deterministic.What if you need randomness in between turns? For example, reshuffling a deck of cards. @andrewosh and I chatted about this and we propose that this should be embedded in the
on_move
flow method.What should happen between moves is: increment the seed array between turns (potentially hashing with the block hash if needed). Pass the seed in the game state, and keep it hidden via
player_filter
. Then, any rng elements can refernce the seed array cleanly in the Moves trait.Note: the above is currently possible to implement manually with the current SDK, but ugly to implement for game developers, and probably common enough that this should be included in the SDK.