boardgameio / boardgame.io

State Management and Multiplayer Networking for Turn-Based Games
https://boardgame.io
MIT License
10.04k stars 709 forks source link

Random shuffle always gives the same result #133

Closed viranch closed 6 years ago

viranch commented 6 years ago

I'm trying to shuffle a deck of cards in my code at setup time:

const game = Game({
  setup() => {
    const G = {
      deck: Random.Shuffle(Array(52).fill().map((_, idx) => idx)),
    };
    return G;
  }
});

But when I look at the resultant array in the debug view, I keep getting the same result on every page refresh and even after yarn server restart. I want to avoid setting up my own seed.

Am I missing something?

Stefan-Hanke commented 6 years ago

No, you don't miss anything. The problem is that for setup, the PRNGState is not set, so undefined is being used as seed.

viranch commented 6 years ago

@Stefan-Hanke does that mean if I do call Random.Shuffle inside a phase instead of setup it will do the real thing?

I can initialize my deck as an empty array in setup, and then the first phase can shuffle the deck inside onPhaseBegin, and endPhaseIf deck length is greater than 0. Would that work or will that have the same problem?

viranch commented 6 years ago

Looks like onPhaseBegin does get a random seed in ctx, but the shuffle output is always the same across reloads no matter the seed value.

See https://codepen.io/viranch/pen/EQqQdb

Stefan-Hanke commented 6 years ago

This runs into the same problem: The call to setup and the calls to startPhase/startTurn happen before the initial call to PRNGState.set(). Unfortunately the PR is wrong - it should read PRNGState.set({seed: game.seed}). However, this now breaks more than one test...

This behaviour is only when using Random inside setup and the first phase/turn. In all other cases, the Random stuff should work as expected, because there are proper calls to PRNGState in place. See here.

viranch commented 6 years ago

Is there a way I can call PRNGState.set() inside setup or onPhaseBegin for it to work?

Stefan-Hanke commented 6 years ago

PRNGState is not exported, so currently don't use Random in setup or the first turn/first phase.

viranch commented 6 years ago

How do I pull this fix into my project?

nicolodavis commented 6 years ago

You'll have to wait for a release, or clone this repo and use the code directly.

nicolodavis commented 6 years ago

This is now released in v0.20.1.

viranch commented 6 years ago

Thanks for the heads up! Can confirm this issue fixed in v0.20.1.

nicolodavis commented 6 years ago

https://github.com/google/boardgame.io/commit/89694336d119a2c8f09c14b6b2aabe48b13bc1c1 was another fix related to this that will be in the next release.