problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Game development with Board Game Arena Studio
User avatar
developgame
Posts: 107
Joined: 15 June 2020, 20:56

problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by developgame »

Hi Everyone

Another newbie question - thank you for any help, advice and suggestions
I am creating escape the curse of the temple - a multiplayer real time dice chucking game
Here is the player options:
Image
When one of the options is selected from onUpdateActionButtons bar, connecting method to the option should run only once. However, for my game, Often the method will run multiple time and the game history players sees will show this.
an exapmple, developGames4 selects "remove black mask spell" but the code ' onRemoveDiceSpell' is run twice.
developGames4 2323325 rolls 3 and translated Key
developGames4 2323325 rolls 1 and translated Golden Mask
03:12 PM
when I used this.checkAction() is true in the methods connected to the option button such as ' onRemoveDiceSpell' , I I then always have the following history messages and warning messages
(Generated by: checkAction/moveChamber)
Please wait, an action is already in progress
(Generated by: checkAction/moveChamber)
Please wait, an action is already in progress
(Generated by: checkAction/moveChamber)
Please wait, an action is already in progress
(Generated by: checkAction/moveChamber)
Please wait, an action is already in progress
developGames0 2323321 rolls 2 and translated Torch
Have you run across this?
Here is part of my onUpdateActionButtons

Code: Select all

this.addActionButton( 'roll_btn', _('Roll Selected Dice'), 'onRoll' ); 
if ( num_adventurer > 0 ) {
	this.addActionButton( 'move_btn', _('Enter a Chamber'), 'onMove' ); 
}
if ( num_gold_mask > 0 ) {
	this.addActionButton( 'gold_mask_btn', _('Remove Black Mask Spell'), 'onRemoveDiceSpell' ); 
}
Thanks again for any help!
Attachments
example.png
example.png (48.45 KiB) Viewed 1024 times
User avatar
tchobello
Posts: 693
Joined: 18 March 2012, 13:19

Re: problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by tchobello »

hello,

have you noticed anything in the Javacript console ? F12

you may add some console.log in order to check if your onRoll is called several times in a row.

there might be something wrong with a loop here or the php Roll function, called through ajax, then.
User avatar
Tisaac
Posts: 2736
Joined: 26 August 2014, 21:28

Re: problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by Tisaac »

Is it possible the buttons already exist and calling addActionButton with same id would result in double listeners ?
Anyway, as tchobello said, would be useful to add console.log to see where the issue Come from exactly
User avatar
Badguizmo
Posts: 76
Joined: 11 October 2020, 14:27

Re: problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by Badguizmo »

Tisaac wrote: 14 August 2021, 11:07 Is it possible the buttons already exist and calling addActionButton with same id would result in double listeners ?
Anyway, as tchobello said, would be useful to add console.log to see where the issue Come from exactly
You should focus on that. i.e. : check if the button exists before adding it.

It happens to me multiple times when addind event on the same Id. Same behavior when adding buttons.
Official BGA developper newb :oops:
User avatar
developgame
Posts: 107
Joined: 15 June 2020, 20:56

Re: problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by developgame »

tchobello wrote: 14 August 2021, 07:26 hello,

have you noticed anything in the Javacript console ? F12

you may add some console.log in order to check if your onRoll is called several times in a row.

there might be something wrong with a loop here or the php Roll function, called through ajax, then.
Thanks for your help, tchnbello!
Your suggestion of console is very good.
With console.log, I can see that the problem is with my connect statement

Code: Select all

	denizens.connect( 'onclick', this, 'resolveSelectMeepleCurseDice' );	
from console,
I can see that onRemoveDiceSpell is called only once and 'resolveSelectMeepleCurseDice' is called multiple times simultaneously.

It seems that the first time I choose 'reomve Black Mask Spell', 'resolveSelectMeepleCurseDice' is activated once but there is the error message "escape?table=303461&testuser=2323322:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().'

The 2nd time I choose 'reomve Black Mask Spell', 'resolveSelectMeepleCurseDice' is activated twice but there is no error message "escape?table=303461&testuser=2323322:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().'

first time,
in onRemoveDiceSpell
escape.js?1629046758295:908 after here in denizen length 1
escape.js?1629046758295:920 in resolveSelectMeepleCurseDice id is meeple_2323322
escape.js?1629046758295:665 here in send to server
escape.js?1629046758295:269 Leaving state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: removeBlackMask
escape.js?1629046758295:233 Entering state: removeBlackMask
escape.js?1629046758295:269 Leaving state: removeBlackMask
escape.js?1629046758295:295 here in onUpdateActionButtons: loadMusic
escape.js?1629046758295:233 Entering state: loadMusic
escape.js?1629046758295:269 Leaving state: loadMusic
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:233 Entering state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape?table=303461&testuser=2323322:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
2nd time
escape.js?1629046758295:891 in onRemoveDiceSpell
escape.js?1629046758295:920 in resolveSelectMeepleCurseDice id is meeple_2323323
escape.js?1629046758295:665 here in send to server
escape.js?1629046758295:920 in resolveSelectMeepleCurseDice id is meeple_2323323
escape.js?1629046758295:665 here in send to server
escape.js?1629046758295:269 Leaving state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: removeBlackMask
escape.js?1629046758295:233 Entering state: removeBlackMask
escape.js?1629046758295:269 Leaving state: removeBlackMask
escape.js?1629046758295:295 here in onUpdateActionButtons: loadMusic
escape.js?1629046758295:233 Entering state: loadMusic
escape.js?1629046758295:269 Leaving state: loadMusic
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:233 Entering state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:269 Leaving state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: removeBlackMask
escape.js?1629046758295:233 Entering state: removeBlackMask
escape.js?1629046758295:269 Leaving state: removeBlackMask
escape.js?1629046758295:295 here in onUpdateActionButtons: loadMusic
escape.js?1629046758295:233 Entering state: loadMusic
escape.js?1629046758295:269 Leaving state: loadMusic
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:233 Entering state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
Here is a my code

Code: Select all

		onRemoveDiceSpell: function( evt )
		{
			console.log( " in onRemoveDiceSpell " );
			var denizens = dojo.query( current_chamber ).query( '.meeple' ).addClass( 'selected' );
			denizens.connect( 'onclick', this, 'resolveSelectMeepleCurseDice' );				
		},
		
		resolveSelectMeepleCurseDice: function( evt )
		{
console.log( " in resolveSelectMeepleCurseDice  id is " + event.target.id );

			var target_id = event.target.id;
			this.disconnectAll;
			//this.disconnect( $( target_id ), 'onclick');
			this.performActionNotStock( actionSelected, items );	

			}
		},
Last edited by developgame on 15 August 2021, 18:48, edited 1 time in total.
User avatar
developgame
Posts: 107
Joined: 15 June 2020, 20:56

Re: problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by developgame »

Tisaac wrote: 14 August 2021, 11:07 Is it possible the buttons already exist and calling addActionButton with same id would result in double listeners ?
Anyway, as tchobello said, would be useful to add console.log to see where the issue Come from exactly
Hi Tisaac, for your help and suggestion of checking that the button already exists. Very good suggestions. I now learned about multiple listeners. I realized the problem is with my " denizens.connect( 'onclick', this, 'resolveSelectMeepleCurseDice' " line. I have used this.disconnectAll and I still have the same problem.

It seems that

from console,
I can see that onRemoveDiceSpell is called only once and 'resolveSelectMeepleCurseDice' is called multiple times simultaneously.

It seems that the first time I choose 'reomve Black Mask Spell', 'resolveSelectMeepleCurseDice' is activated once but there is the error message "escape?table=303461&testuser=2323322:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().'

The 2nd time I choose 'reomve Black Mask Spell', 'resolveSelectMeepleCurseDice' is activated twice but there is no error message "escape?table=303461&testuser=2323322:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().'

first time,
in onRemoveDiceSpell
escape.js?1629046758295:908 after here in denizen length 1
escape.js?1629046758295:920 in resolveSelectMeepleCurseDice id is meeple_2323322
escape.js?1629046758295:665 here in send to server
escape.js?1629046758295:269 Leaving state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: removeBlackMask
escape.js?1629046758295:233 Entering state: removeBlackMask
escape.js?1629046758295:269 Leaving state: removeBlackMask
escape.js?1629046758295:295 here in onUpdateActionButtons: loadMusic
escape.js?1629046758295:233 Entering state: loadMusic
escape.js?1629046758295:269 Leaving state: loadMusic
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:233 Entering state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape?table=303461&testuser=2323322:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
2nd time
escape.js?1629046758295:891 in onRemoveDiceSpell
escape.js?1629046758295:920 in resolveSelectMeepleCurseDice id is meeple_2323323
escape.js?1629046758295:665 here in send to server
escape.js?1629046758295:920 in resolveSelectMeepleCurseDice id is meeple_2323323
escape.js?1629046758295:665 here in send to server
escape.js?1629046758295:269 Leaving state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: removeBlackMask
escape.js?1629046758295:233 Entering state: removeBlackMask
escape.js?1629046758295:269 Leaving state: removeBlackMask
escape.js?1629046758295:295 here in onUpdateActionButtons: loadMusic
escape.js?1629046758295:233 Entering state: loadMusic
escape.js?1629046758295:269 Leaving state: loadMusic
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:233 Entering state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:269 Leaving state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: removeBlackMask
escape.js?1629046758295:233 Entering state: removeBlackMask
escape.js?1629046758295:269 Leaving state: removeBlackMask
escape.js?1629046758295:295 here in onUpdateActionButtons: loadMusic
escape.js?1629046758295:233 Entering state: loadMusic
escape.js?1629046758295:269 Leaving state: loadMusic
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:233 Entering state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
Here is a my code

Code: Select all

		onRemoveDiceSpell: function( evt )
		{
			console.log( " in onRemoveDiceSpell " );
			var denizens = dojo.query( current_chamber ).query( '.meeple' ).addClass( 'selected' );
			denizens.connect( 'onclick', this, 'resolveSelectMeepleCurseDice' );				
		},
		
		resolveSelectMeepleCurseDice: function( evt )
		{
console.log( " in resolveSelectMeepleCurseDice  id is " + event.target.id );

			var target_id = event.target.id;
			this.disconnectAll;
			//this.disconnect( $( target_id ), 'onclick');
			this.performActionNotStock( actionSelected, items );	

			}
		},
Last edited by developgame on 15 August 2021, 18:54, edited 1 time in total.
User avatar
developgame
Posts: 107
Joined: 15 June 2020, 20:56

Re: problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by developgame »

Badguizmo wrote: 15 August 2021, 11:01
Tisaac wrote: 14 August 2021, 11:07 Is it possible the buttons already exist and calling addActionButton with same id would result in double listeners ?
Anyway, as tchobello said, would be useful to add console.log to see where the issue Come from exactly
You should focus on that. i.e. : check if the button exists before adding it.

It happens to me multiple times when addind event on the same Id. Same behavior when adding buttons.
Thanks for your very good advice about focusing on the button, Badguizmo! It help me see the importance of looking for double listeners in my code, I can see how easy it is for even very strong programmers to encounter this problem.

I realized the problem is with my " denizens.connect( 'onclick', this, 'resolveSelectMeepleCurseDice' " line. I have used this.disconnectAll and I still have the same problem.

It seems that

from console,
I can see that onRemoveDiceSpell is called only once and 'resolveSelectMeepleCurseDice' is called multiple times simultaneously.

It seems that the first time I choose 'reomve Black Mask Spell', 'resolveSelectMeepleCurseDice' is activated once but there is the error message "escape?table=303461&testuser=2323322:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().'

The 2nd time I choose 'reomve Black Mask Spell', 'resolveSelectMeepleCurseDice' is activated twice but there is no error message "escape?table=303461&testuser=2323322:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().'

first time,
in onRemoveDiceSpell
escape.js?1629046758295:908 after here in denizen length 1
escape.js?1629046758295:920 in resolveSelectMeepleCurseDice id is meeple_2323322
escape.js?1629046758295:665 here in send to server
escape.js?1629046758295:269 Leaving state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: removeBlackMask
escape.js?1629046758295:233 Entering state: removeBlackMask
escape.js?1629046758295:269 Leaving state: removeBlackMask
escape.js?1629046758295:295 here in onUpdateActionButtons: loadMusic
escape.js?1629046758295:233 Entering state: loadMusic
escape.js?1629046758295:269 Leaving state: loadMusic
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:233 Entering state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape?table=303461&testuser=2323322:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
2nd time
escape.js?1629046758295:891 in onRemoveDiceSpell
escape.js?1629046758295:920 in resolveSelectMeepleCurseDice id is meeple_2323323
escape.js?1629046758295:665 here in send to server
escape.js?1629046758295:920 in resolveSelectMeepleCurseDice id is meeple_2323323
escape.js?1629046758295:665 here in send to server
escape.js?1629046758295:269 Leaving state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: removeBlackMask
escape.js?1629046758295:233 Entering state: removeBlackMask
escape.js?1629046758295:269 Leaving state: removeBlackMask
escape.js?1629046758295:295 here in onUpdateActionButtons: loadMusic
escape.js?1629046758295:233 Entering state: loadMusic
escape.js?1629046758295:269 Leaving state: loadMusic
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:233 Entering state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:269 Leaving state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: removeBlackMask
escape.js?1629046758295:233 Entering state: removeBlackMask
escape.js?1629046758295:269 Leaving state: removeBlackMask
escape.js?1629046758295:295 here in onUpdateActionButtons: loadMusic
escape.js?1629046758295:233 Entering state: loadMusic
escape.js?1629046758295:269 Leaving state: loadMusic
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
escape.js?1629046758295:233 Entering state: playerTurn
escape.js?1629046758295:295 here in onUpdateActionButtons: playerTurn
Here is a my code

Code: Select all

		onRemoveDiceSpell: function( evt )
		{
			console.log( " in onRemoveDiceSpell " );
			var denizens = dojo.query( current_chamber ).query( '.meeple' ).addClass( 'selected' );
			denizens.connect( 'onclick', this, 'resolveSelectMeepleCurseDice' );				
		},
		
		resolveSelectMeepleCurseDice: function( evt )
		{
console.log( " in resolveSelectMeepleCurseDice  id is " + event.target.id );

			var target_id = event.target.id;
			this.disconnectAll;
			//this.disconnect( $( target_id ), 'onclick');
			this.performActionNotStock( actionSelected, items );	

			}
		},
User avatar
robinzig
Posts: 459
Joined: 11 February 2021, 18:23

Re: problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by robinzig »

So your onRemoveDiceSpell adds the click handler - but where is this called from? (From the name I guess it's itself a handler for some player action.) Are you removing those handlers between calls to this function? If not then you are going to get exactly what you're seeing - more and more identical handlers added to the same event as the game goes on. You'll need to disconnect at the appropriate places if doing it this way. (Typically in onLeavingState if this action is only associated with a particular game state.)
User avatar
tchobello
Posts: 693
Joined: 18 March 2012, 13:19

Re: problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by tchobello »

hi
I think it's better to add your event listeners once for all in the JS setup.

Code: Select all

dojo.query( '.hero_wrap' ).connect( 'onclick', this, 'onClickOnHero' );
and stop the event listener once the function is called.
you can then check your actions, add or remove classes...

Code: Select all

onClickOnHero: function(evt)
{
    evt.preventDefault();
    dojo.stopEvent(evt);
    var hero_selected = evt.currentTarget.id;
    if( dojo.hasClass( hero_selected, 'selected' ) )
    {...
    if( this.checkAction( 'placeDisc', true ))
    {...
when removing a curse, you can check if a meeple is selected when there are several in the same room before triggering when hitting the button
or trigger it with no selection needed if there is only one meeple.
User avatar
developgame
Posts: 107
Joined: 15 June 2020, 20:56

Re: problem with .js - onUpdateActionButtons - when button options selected, option often repeats multiple times

Post by developgame »

tchobello wrote: 16 August 2021, 00:09 hi
I think it's better to add your event listeners once for all in the JS setup.

Code: Select all

dojo.query( '.hero_wrap' ).connect( 'onclick', this, 'onClickOnHero' );
and stop the event listener once the function is called.
you can then check your actions, add or remove classes...

Code: Select all

onClickOnHero: function(evt)
{
    evt.preventDefault();
    dojo.stopEvent(evt);
    var hero_selected = evt.currentTarget.id;
    if( dojo.hasClass( hero_selected, 'selected' ) )
    {...
    if( this.checkAction( 'placeDisc', true ))
    {...
when removing a curse, you can check if a meeple is selected when there are several in the same room before triggering when hitting the button
or trigger it with no selection needed if there is only one meeple.
Thank you tchobello for the very sound advice of putting all the connects at the setup or when the element is created and then stopping the event listener once the function is called. This will really save me alot of headaches and bugs later!


Thanks also for the codes to stop the events when the function is called.
Post Reply

Return to “Developers”