Closed davidgovea closed 6 years ago
Thanks for reporting this!
The easy fix is to have the client only send actions to the server and not compute any state locally (including the current player).
This is not particularly desirable though because you want to see some state changes without network latency, so we need some mechanism to indicate what is acceptable to compute on the client and what needs to wait for a state update from the server.
All this while still maintaining the abstractions and not forcing the user to really think about client vs server (one of the goals of this framework).
I'll think about this a little more after the weekend and report back with some concrete recommendations!
I think the following should work:
The move reducers are analogous to a player moving their own tokens, and shouldn't rely on secret state. Die rolls can work by having the move just initiate the roll, and the actual value is computed on the server.
@scheijan FYI
Something to take into account for #68
This is now resolved in https://github.com/google/boardgame.io/commit/af3a7b591759ed65d22d27ce036d9d33caaaf4f5 and released in 0.16.7.
Feel free to re-open if this doesn't address your issue!
Wrote this earler, didn't submit.
Just trying to work my head through this.
Player guesses (x, y)
Server hook runs (endTurnIf
or earlier hook)
Both clients are informed of new state.
In this phase, available moves are rollDice
and move
. Or possibly, roll and move are different phases?
Player rolls dice
Server hook runs (endTurnIf
or earlier hook)
Both clients are informed of new state, including dice value
Player moves
endTurnIf
is not for modifying full game state - it seems like moves are the place for that.
Can run-after hooks be defined per-move?
Could this be created using phases? :: requestRoll
phase followed by rollDice
phase? How would the "server move" get initiated?
Die rolls are the tricky bits here. One way to implement them would be:
Game({
moves: {
rollDie: G => ({ ...G, requestDieRoll: true })
}
flow: {
triggers: [
{
condition: G => G.requestDieRoll,
action: G => make die roll
}
]
No need for separate phases (triggers are run whenever a condition is met). This is still not satisfactory IMO. I think a die rolling API should be added that takes care of this more elegantly (but the above should work at the moment).
Ah! Trigger with action is what I was missing here. Thank you!
Hi there!
First, let me just say that this project is really exciting - love the activity and where this is heading. Great work!
I'm working on a variation of the "battleship" game type - choose a secret layout, then guess the opponent's layout. This is working nicely for
multiplayer: false
with the 'phases' feature, and a move reducer that checks the opponents secret layout.Today, I implemented the new
PlayerView.STRIP_SECRETS
player view, but I'm running into some issues:This seems somewhat similar to the 'randomness' work being done (storing a secret RNG seed for dice rolls, etc). For a simple "roll and advance [DICE] spaces" move, the outcome of a roll must be shared with the clients. Similarly, a battleship (x, y) guess must be reported as a HIT or MISS.
Just wanted to start the discussion. Let me know if this belongs somewhere else, or if I'm missing something.
Option brainstorm:
gameEvent
, then use outcome in next actionmoveSpaces(Secret.DICE_ROLL)
, server transforms special argument into real value. Maybe this is the same as previous option..