boardgame.io icon indicating copy to clipboard operation
boardgame.io copied to clipboard

Feature Request: Stages should have their own move limit

Open jorbascrumps opened this issue 4 years ago • 10 comments
trafficstars

It should be possible to define individual move limits per stage. As an example:

  1. In a "draw" phase the player draws 3 cards;
  2. 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?

jorbascrumps avatar Aug 03 '21 19:08 jorbascrumps

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).

delucis avatar Aug 03 '21 20:08 delucis

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?

jorbascrumps avatar Aug 03 '21 20:08 jorbascrumps

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.

delucis avatar Aug 03 '21 20:08 delucis

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 })

delucis avatar Aug 03 '21 20:08 delucis

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

delucis avatar Aug 03 '21 20:08 delucis

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.

jorbascrumps avatar Aug 03 '21 20:08 jorbascrumps

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.

delucis avatar Aug 03 '21 20:08 delucis

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.

jorbascrumps avatar Aug 03 '21 20:08 jorbascrumps

Yeah, I can see why — the naming of these things is never 100% clear. Feel free to ask questions as you go.

delucis avatar Aug 03 '21 20:08 delucis

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.

danny-does-stuff avatar Sep 25 '21 19:09 danny-does-stuff