Hello!
I'm trying to use typescript with boardgame.io and I get stuck with this error:
Uncaught Error: Move state is not JSON-serialiazable.
See https://boardgame.io/documentation/#/?id=state for more information.
My problem seems to be, that I'm adding an array of very primitive Objects to the state:
export class Card {
suit: string;
rank: number;
shortname: string;
constructor(suit: string, rank: number) {
this.suit = suit;
this.rank = rank;
this.shortname = this.suit + this.rank;
}
}
export type Hand = Card[];
...
export interface SpadesGameState {
bids: string[];
score: number[];
hands: Hand[];
currentTrick?: Trick;
lastTrick?: Trick;
dealer: number;
isSpadesOpen: boolean;
}
...
return { ...G, isSpadesOpen: false, currentTrick: undefined, lastTrick: undefined, hands: [[new Card("d", 1),new Card("d", 4)], [], [], []] as Hand[]}
Is it really true that I cannot have a GameState that has a typed ("classed") property inside or should I search for the error elsewhere..?
matchData
object with isConnected: true
Certain events are double-firing inappropriately, and I'm at a loss for why. I have a phase in which most turns are automatic. In the exceptions, I shunt players into a stage to make a move before ending the turn. An onEnd
hook for the turn then fires. My problem is that, sometimes, that onEnd
hook fires twice. It seems to happen when either the phase ends or the event needs to call another move function. At least in the latter case, the top of the call stack looks like: (my onEnd
hook) > wrapFn
> produce
> wrapFn
, where both wrapFn
s come from the Immer plugin. This seems weird, and calls to mind this old bug: boardgameio/boardgame.io#544. But I don't know how to fix or work around it.
Appreciate any help you can give.
Hello, I have an array (called 'selection') in my game state (G). I want a react component to refresh when an item is added/removed to/from this array. The problem is that my 'useEffect' function does not trigger.
export function MyBoard({ ctx, G, moves }) {
const [selection, setSelection] = useState([]);
useEffect(() => {
setSelection(G.selection);
}, [G.selection]);
... }
Here is the code (in my moves) that adds an element to the array (I avoid using 'push' as it does not change the array) :
G.selection = [...G.selection, item];
Thank you for your help !
Hi i just posted a new issue here : boardgameio/boardgame.io#1100
"Hi ! i have a custom lobby mechanism on my project which implement basic matchmaking between players.
When sufficient players have joined the lobby i create the match from my api and send an event to all the players to redirect them to the match page.
When the match page load, an http call occurs to log the user to the game server.
It seems that the boardgame implementation cannot handle simultaneous connection changes properly.
When someone logs into the match (https://github.com/boardgameio/boardgame.io/blob/main/src/master/master.ts#L400)
the match metadata is fetched from my database, modified to include the new metadata, sent to all clients and then saved to the database.
When 2 players joins the match simultaneously, this logic is called 4 times simultaneously and it looks like that some players are overriding the metadata changes of previous users.
For example:
Player 1 is redirected to match page
Player 2 is redirected to match page
Player 1 onConnectionChange method start and fetch metadata
Player 2 onConnectionChange method start and fetch metadata
Player 1 onConnectionChange method modify metadata and save it to the database
Player 2 onConnectionChange method modify metadata and save it to the database
as Player 2 fetched the metadata before Player 1 finished modifying and saving it to the database, when Player 2 modify and save the metadata into the database, the data is outdated and does not contain Player 1 isConnected and credentials values. Player 2 is correctly logged into the match but Player 1 stay on the "Connecting..." screen indefinitely and the match get stuck when his turn start...
Sometimes everything plays nicely in the correct order but most of the time, for example in a 4 players match, a player stay on the loading screen and the match is blocked, this is really critical for my project, how can this be fixed ?"
Does anyone has encountered the same behavior ? and maybe found a solution for it ?
Hello! I'm currently wrapping my head around the difference between stages and phases.
I get that a stage works within the concept of a turn, i.e. that it retains the concept of the current player, and that a phase is a lot broader in scope, where you can change turn order, current player, etc.
One unique thing that a stage provides that a phase does not on its own is the ability for other players to makes moves during the current player's turn, i.e. other players can make moves without modifying the value of the "current player".
In fact, to me, this is the killer feature of stages - the ability to have more that one player making moves. I say this because if you take this feature out of consideration, then there's not much a difference between stages and phases, is there? Am I wrong about that?
In particular, if you don't need the ability for other players to make moves on someone else's turn, then I imagine you can just treat phases like stages - especially if the phases all have a turn order of CONTINUE (i.e. the current player in the next phase is the one who ended the previous phase). With phases all having a turn order of CONTINUE, and if we don't need other players to make moves during the current player's turn, is there really a difference between phases and stages?
I was wondering whether anybody could give me an opinion on my lobby/site to play games.
It's https://cuberail.games, and the source is on https://github.com/lkingsford/CubeRailDotGames. The one game on it is on https://github.com/lkingsford/EmuBayOnlineClient
Going to thread to describe what I've got happening with the lobby (and more precisely, what I'm wondering if there's a better way to do)
I'm trying to run some game state tests using:
let client = Client({ game: customGameSetup, playerID: '0', multiplayer: Local() });
when I run the tests I get CONSOLE ERROR messages:
ERROR: invalid value returned by turn.order.first — expected number got object “null”.
which seems to be coming from bgio not my source... any idea what causes this issue? Likely I'm misusing the Client instance but not sure how.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at <url>. (Reason: CORS request did not succeed). Status code: (null).
. I currently have the origins on the server set as origins: [Origins.LOCALHOST]
, and I may change the setup to two servers.
The answer to this is probably obvious, but I'm missing it completely. I've got a turn order setup that I can't quite make work. :
phases: {
setup: { // some moves that can only be made by player '0' at the start of the game, before they use a move that manually ends the phase
start: true,
turn: {order: TurnOrder.CONTINUE},
next: 'phaseA',
moves: {
other_stuff: (...),
progress_to_phase_a: ({events}) => {events.endPhase()}
}
},
phaseA: { // normal play, starting with player '0'.
turn: {
order: TurnOrder.CONTINUE,
moveLimit: 1,
},
next: 'phaseB',
moves: {
other_stuff: (...),
progress_to_phase_b: ({events}) => {events.endPhase()}
}
},
phaseB: { // should start with the player AFTER the player who used progress_to_phase_b, and end BEFORE the player who used progress_to_phase_b. e.g., in a 3 player game, if player '1' ended phaseA, player '2' and player '0' should get a turn, at which point the phase should end
turn: {
order: TurnOrder.ONCE,
moveLimit: 1
},
moves: {...}
}
}
Every combination of TurnOrder
and next
I've tried has either ended with player '1'
always starting phaseA, or player '0'
always starting phaseB. Please help.