multiplayer: isCurrentPlayerActive() and checkAction()

Game development with Board Game Arena Studio
Post Reply
User avatar
RicardoRix
Posts: 630
Joined: 29 April 2012, 23:43

multiplayer: isCurrentPlayerActive() and checkAction()

Post by RicardoRix » 10 October 2019, 00:28

Inside .JS, For a multiplayer action. I am noticing some strange behaviour with 'active' player functions.
I am trying to implement some 'user changes their mind' functionality.

1.
within: onEnteringState: function( stateName, args )

the this.isCurrentPlayerActive() is not set to true during normal game flow.
If the page is refreshed via F5, then this.isCurrentPlayerActive() does come back as true, and all works ok.

2.
Also, the this.checkAction('action_name') works fine when the player is active, but if the player is not active then this returns false.
The wiki doc suggests that this checks the game state, and doesn't say anything about the player being active or not. I can't find anything specific for checking the game state for JS.

fafa-fr
Posts: 121
Joined: 22 December 2013, 21:58

Re: multiplayer: isCurrentPlayerActive() and checkAction()

Post by fafa-fr » 11 October 2019, 16:41

Hi,
RicardoRix wrote:
10 October 2019, 00:28
I can't find anything specific for checking the game state for JS.
Maybe this.gamedatas.gamestate.name is what you're looking for?

User avatar
RicardoRix
Posts: 630
Joined: 29 April 2012, 23:43

Re: multiplayer: isCurrentPlayerActive() and checkAction()

Post by RicardoRix » 11 October 2019, 20:26

fafa-fr wrote:
11 October 2019, 16:41
Maybe this.gamedatas.gamestate.name is what you're looking for?
Yes, thanks!

Turns out as well the this.gamedatas.gamestate.multiactive is empty during the onEnteringState event.
There is also a multiactive array as part of the 'args' to the event, again it is empty.
Hit F5 - refresh and both arrays are now full of all the player ids'

I've come up with the following work-arounds for multiplayer states.

Code: Select all

checkActionMulti: function(state)
		{
			return (this.checkActionMulti(state, false));
		},
		
		checkActionMulti: function(state, noMessage)
		{
			var isState = (this.gamedatas.gamestate.name == state);
			
			if ((!noMessage) && (!isState))
				this.checkAction(state);
			
			return isState;
		},
		
		isCurrentMultiPlayerActive: function()
		{
			//return (this.gamedatas.gamestate.multiactive.length == 0) || (this.isCurrentPlayerActive.gamestate.multiactive.includes(String(this.player_id)));
			
			return ((this.gamedatas.gamestate.multiactive.length == 0) || this.isCurrentPlayerActive());
		},		

User avatar
Victoria_La
Posts: 311
Joined: 28 December 2015, 20:55

Re: multiplayer: isCurrentPlayerActive() and checkAction()

Post by Victoria_La » 12 October 2019, 00:23

Check this thread about multiactive and onEnteringState
viewtopic.php?f=12&t=12193

checkAction would return false only for activate player because if player is not activate action is not allowed, only activate players can do actions

User avatar
RicardoRix
Posts: 630
Joined: 29 April 2012, 23:43

Re: multiplayer: isCurrentPlayerActive() and checkAction()

Post by RicardoRix » 12 October 2019, 13:31

1.
On entering the state, both players should be active.

Code: Select all

        onEnteringState: function( stateName, args )
        {

			//debugger;
			if (args.multiactive != null)
				this.log( 'Entering state: '+ stateName + ':' + args.multiactive.length + ':' + this.isCurrentPlayerActive() + ':' + this.gamedatas.gamestate.multiactive.length );	
When entering the state via normal game flow.
Entering state: playCards:0:false:0

Without doing anything, Pressing F5 / page refresh:
Entering state: playCards:2:true:2

2.
If the 'checkAction()' is reliant on a player being active, then there should be a checkState() or at-least some alternative which is not player active dependent. fafa-fr has suggested this.gamedatas.gamestate.name which works well.

I think it's quite common in multiplayer mode actions, that users may like to change their mind. The only way to stop the clock is to make the player inactive. What is the preferred way to deal with a player's actions in this player inactive condition?

User avatar
sourisdudesert
Administrateur
Posts: 3864
Joined: 23 January 2010, 22:02

Re: multiplayer: isCurrentPlayerActive() and checkAction()

Post by sourisdudesert » 18 October 2019, 10:31

On client side, you can use the following:

Code: Select all

            if( ! this.checkPossibleActions( 'chooseCard' ) )
            {   return; }
It does the same than "checkAction", but it does not test if current player is active. Thus, you can check that you are on the right game state, but it does not take active player into account.


In addition, on server side, you can use the following:

Code: Select all

        $bChangeMind = false;
        if( self::checkAction( 'chooseCard', false ) )
        {
        }
        else
        {
            $this->gamestate->checkPossibleAction( 'chooseCard' ) ;       
            $bChangeMind = true;
        }
It works exactly the same way than on JS side, plus it allows you to determine if this is a "changing my mind" action or a normal "first action".

User avatar
RicardoRix
Posts: 630
Joined: 29 April 2012, 23:43

Re: multiplayer: isCurrentPlayerActive() and checkAction()

Post by RicardoRix » 18 October 2019, 10:58

sourisdudesert wrote:
18 October 2019, 10:31
On client side, you can use the following:

Code: Select all

            if( ! this.checkPossibleActions( 'chooseCard' ) )
            {   return; }
That's great!

checkPossibleActions() is not documented on the wiki:
http://en.doc.boardgamearena.com/Game_i ... amename.js


Do you have any information about the difference with the multiactive, in onEnteringState my point 1.

Code: Select all

onEnteringState: function( stateName, args )
        {

			//debugger;
			if (args.multiactive != null)
				this.log( 'Entering state: '+ stateName + ':' + args.multiactive.length + ':' + this.isCurrentPlayerActive() + ':' + this.gamedatas.gamestate.multiactive.length );	
When entering the state via normal game flow.
Entering state: playCards:0:false:0

Without doing anything, Pressing F5 / page refresh:
Entering state: playCards:2:true:2

User avatar
sourisdudesert
Administrateur
Posts: 3864
Joined: 23 January 2010, 22:02

Re: multiplayer: isCurrentPlayerActive() and checkAction()

Post by sourisdudesert » 18 October 2019, 11:26

RicardoRix wrote:
18 October 2019, 10:58
Do you have any information about the difference with the multiactive, in onEnteringState my point 1
During a multiplayer state, players activity is managed dynamically by you DURING the state. In general, you active all the player in the "stYourFunction" method associated to the state.

This is why when "entering" into a state, the players are not active yet. When you do a F5 afterwards the situation has evolved and of course your players are active.

TL;DR: isCurrentPlayerActive is not reliable during onEnteringState for multipleplayers state. You must use onUpdateActionButtons, which is called for each player activation/unactivation during a multiplayer state.

User avatar
RicardoRix
Posts: 630
Joined: 29 April 2012, 23:43

Re: multiplayer: isCurrentPlayerActive() and checkAction()

Post by RicardoRix » 18 October 2019, 11:47

I'm not sure why this should work differently for a multiplayer state than an single turn-by-turn state. Maybe they are both the same?

The state machine normally goes, play state followed by a transitional resolve state

So currently I do set everyone active in the play state:

Code: Select all

function stPlayCards()
	{		
		$this->gamestate->setAllPlayersMultiactive();        
	}
but are you saying it is necessary or possible to do this on a previous state ?

Is that a bug?

or just use onUpdateActionButtons for everything multiplayer and single player states, and ignore onEnteringState.

Is there a picture /timing diagram for the state machine?

User avatar
sourisdudesert
Administrateur
Posts: 3864
Joined: 23 January 2010, 22:02

Re: multiplayer: isCurrentPlayerActive() and checkAction()

Post by sourisdudesert » 18 October 2019, 11:59

This is not a bug. activePlayer is mean to be simple, and multipleActivePlayer is mean to give you a lot of flexibility. So the way they are working are slightly different.

In a classic "activePlayer" state:

  • You cannot change the active player DURING the state
  • This is to ensure that during 1 activePlayer state, only ONE player is active
  • As a consequence, you must set the active player BEFORE entering the activePlayer state
  • Finally, during onEnteringState, on JS side, the active player is signaled as active and the information is reliable and usable.

In a "multiplePlayer" state:

  • You can (and must) change the active players DURING the state
  • During such a state, players can be activated/desactivated anytime during the state, giving you the maximum of possibilities.
  • You shouldn't set actives player before entering the state. I'm not sure this is allowed or not but you shouldn't do this.
  • Finally, during onEnteringState, on JS side, the active players are NOT actives yet so you must use onUpdateActionButtons to perform the client side operation which depends on a player active/unactive status.

Post Reply

Return to “Developers”