boardgame.io
boardgame.io copied to clipboard
Feature Request: Stages should have their own move limit
It should be possible to define individual move limits per stage. As an example:
- In a "draw" phase the player draws 3 cards;
- In a "play" phase the player then plays a single card from their hand
I know this is possible to handle in userland but I feel this could be a good addition. Thoughts?
I think you mean something like:
stages: {
draw: {
moveLimit: 3,
moves: { draw },
},
play: {
moveLimit: 1,
moves: { play },
},
},
Sounds like a good idea! Probably the value in the stage configuration should be overridden if an alternative moveLimit is passed in activePlayers or setActivePlayers (also taking account of the “advanced” move limit options).
That is the exact API I was thinking. I looked briefly into the implementation and it doesn't look like there are any existing systems in place for handling stage "state" (ie, no hooks for determining if the stage should end). Am I correct in thinking that the only way to currently end a stage is to call setStage or if turn.moveLimit is reached?
Yes, stages currently can end/change via the setStage, endStage or setActivePlayers events (or when a turn/phase ends as that always wipes stages) and when the move limit is reached. There’s no endIf for stages currently.
Ah, wait, not turn.moveLimit — we count moves in the ctx._activePlayersNumMoves map and each update compare that to ctx._activePlayersMoveLimit, which maps playerIDs to the limit (each of these looks something like { '0': 2, '1': 1 })
Here’s the logic run each move to see if the move limit is reached:
https://github.com/boardgameio/boardgame.io/blob/bff1d29492858842a3c38c8c4dca72e2888dca73/src/core/flow.ts#L668-L673
Ok, so we'll need a way to track number of moves within a stage in addition to the entire turn. We could add additional keys to ctx (ctx._activePlayersStageNumMoves and ctx._activePlayersStageMoveLimit - terrible example names), or we could convert the existing keys into objects ({ turn: 1, stage: 1 }). The former obviously has a smaller footprint but doesn't scale as nicely.
We’re already tracking them! That’s exactly what _activePlayersNumMoves does. It is set to zero each time a player enters a stage, increments each time that player makes a move, and if it hits the limit stored in _activePlayersMoveLimit, we end the stage. To support this feature we just need to add stages[stageName].moveLimit as a fallback source for the move limit (it’s currently only set via the moveLimit arguments to the setActivePlayers event and turn.activePlayers config.
Oh! I thought _activePlayerNumMoves was global for the turn - my bad. Knowing this I'll take a peak and see what I come up with.
Yeah, I can see why — the naming of these things is never 100% clear. Feel free to ask questions as you go.
This would be awesome to have! I think it would be more intuitive than just needing to remember that move limit gets reset after every stage.