Add new states/buttons etc. (Russian Railroads)

Game development with Board Game Arena Studio
Post Reply
User avatar
Tikhonov
Posts: 14
Joined: 24 June 2020, 13:08

Add new states/buttons etc. (Russian Railroads)

Post by Tikhonov »

Hello,

after a short break I wanted to have another look at Russian Railroads and try to implement or correct some suggestions/bugs reported by the community. For example, if I now use the automatic pass when no actions are available (saves a lot of time in turn-based games), this works without problems when using the existing "onPass" action. But since it is a special case, I would like to output other log notifications etc. for which I want to trigger a new action (e.g. "onMustPass").

My problem is now, that

Code: Select all

this.addActionButton('button_pass', _('Pass'), 'onMustPass');
still triggers onPass and I just cannot figure out why. If I rename the button to button_mustPass, I get an error that the move is not authorized (now it seems that onMustPass was finally called). But again, I do not get what the issue is because I added "mustPass" to the possible actions array in the *.states.php file:

Code: Select all

       
        'playerTurnPlaceWorker' => array (
                "type" => "activeplayer",
                "description" => '${actplayer} must select an action or pass',
                "descriptionmyturn" => '${you} must select an action or pass',
                "possibleactions" => array (
                        "placeWorker(alphanum worker_ids,alphanum place_id,alphanum choices?)",
                        "pass",
>>>                  "mustPass",
                ),
                "transitions" => array (
                        "next" => "gameTurnNextPlayer",
                        "endbonus" => "playerTurnSelectEndBonus",
                ) 
        ),
Then, on http://en.doc.boardgamearena.com/Game_i ... amename.js you say that buttons I add via "addActionButton" must use an ID that is unique in my HMTL DOM file. But when I clone the project, I don't have an html file where I can define the object specifications or where something has already been defined. Where can I find this file or do I really need it?

I've also tried other approaches, like checking if the next player can still make moves while the next player is being determined and then let him pass immediately, or adding a new state to the state machine where the current player automatically passes. It all comes down to the fact that I can't perform the actions with the error message reported above. So I guess that the state machine is not updated properly. Is there anything else I need to do? Many thanks for your help!
User avatar
Tisaac
Posts: 2736
Joined: 26 August 2014, 21:28

Re: Add new states/buttons etc. (Russian Railroads)

Post by Tisaac »

Could you provide the code of onMustPass ? And the corresponding action on the php side ?
User avatar
Marcuda
Posts: 25
Joined: 21 September 2015, 00:36

Re: Add new states/buttons etc. (Russian Railroads)

Post by Marcuda »

Like Tisaac said it's hard to know without seeing more code. I implemented a similar feature in the state that determines the next player. I ran into two problems:

1. My "onPass" action calls "checkAction('pass')" on the server. This cannot be done in the 'game' type state so I had to separate out the player action from the pass logic. For auto-pass I don't call the same action function, just the second part of it.

2. I had to add another transition to my "nextPlayer" game state that loops back on itself. When auto-pass happens it uses this state instead.
User avatar
Tikhonov
Posts: 14
Joined: 24 June 2020, 13:08

Re: Add new states/buttons etc. (Russian Railroads)

Post by Tikhonov »

Tisaac wrote: 30 July 2020, 16:05 Could you provide the code of onMustPass ? And the corresponding action on the php side ?
Yes, sure. In principal I just copied the existing "pass" functions and removed the parts I do not need for auto-pass:

russianrailroads.js:

Code: Select all

    onPass : function(event) {
        var id = this.onClickSanity(event, false);
        if (id == null) return;
        var worker = this.findHomePiece(this.player_color, 'meeple');
        if (worker) {
            this.confirmationDialog(_('Are you sure you want to pass with workers left? You can always use Black/Gray Track Advancement Action.'),
                                                dojo.hitch(this, function() {this.ajaxAction(id, {});}));
             return;
         }
         this.ajaxAction(id, {});
    },
    onMustPass : function(event) {
        var id = this.onClickSanity(event, false);
        if (id == null) return;
        this.ajaxAction(id, {});
    },
russianrailroads.action.php:

Code: Select all

    public function pass() {
        self::setAjaxMode();
        $this->game->action_pass(  );
        self::ajaxResponse( );
    }
    
    public function mustPass() {
        self::setAjaxMode();
        $this->game->action_mustPass();
        self::ajaxResponse();
    }
russianrailroads.game.php:

Code: Select all

    function _action_pass($action_name, $notif_msg) {
        $this->checkAction($action_name);
        $this->notifyAllPlayersWithActive('playerLog', clienttranslate($notif_msg));
        $player_id = $this->getActivePlayerId();
        $disc = $this->getOrderPiece($player_id);
        $this->dbSetTokenState($disc, 1);
        $pos = $this->getPlayerPosition($player_id);
        $count = $this->getPointsForPosition($pos);
        $this->dbScoreIncFrom('position', $count, clienttranslate('${player_name} earned ${inc_resource_name} for current turn order position'));
        $this->gamestate->nextState('next');
    }

    function action_pass() {
        $this->_action_pass('pass','${player_name} passed');
    }

    function action_mustPass() {
        $this->_action_pass('mustPass', '${player_name} could not complete any actions and therefore had to pass');
    }
User avatar
Victoria_La
Posts: 665
Joined: 28 December 2015, 20:55

Re: Add new states/buttons etc. (Russian Railroads)

Post by Victoria_La »

You don't need any extra transitions to implement this, turn processing is done in st* functions so you can switch player there, you just process conditions and instead of doing nextPlayer you do their turn for them in the same state function.
I did not implement this request on purpose before just for sake on consistency.

Basically the only thing you would need to add

Code: Select all

    function st_gameTurnNextPlayer() {
        $next_player_id = $this->activeNextPlayerCustom();
        while ( $next_player_id != null && $this->playerCanOnlyPass($next_player_id) ) { // implement this function
            $this->notifyAllPlayersWithActive('playerLog', clienttranslate('${player_name} has no legal moves, therefore they must pass'));
            $this->_action_pass(); // same as acIon_pass but without check for action and state transition
            $next_player_id = $this->activeNextPlayerCustom();
        }
        ...
User avatar
Tikhonov
Posts: 14
Joined: 24 June 2020, 13:08

Re: Add new states/buttons etc. (Russian Railroads)

Post by Tikhonov »

Edit: You edited your initial post, didn‘t you, @Victoria_La? I will try it again with „_action_pass“ and report my result later :)

Victoria_La wrote: 03 August 2020, 14:53 You don't need any extra transitions to implement this, turn processing is done in st* functions so you can switch player there, you just process conditions and instead of doing nextPlayer you do their turn for them in the same state function.
I did not implement this request on purpose before just for sake on consistency.

Basically the only thing you would need to add

Code: Select all

    function st_gameTurnNextPlayer() {
        $next_player_id = $this->activeNextPlayerCustom();
        if ($this->playerCanOnlyPass($next_player_id)) { // implement this function do deal with condition
            $this->action_pass(); // correct player is active already, only need to add 'pass' as possible action in game state (if not possible just refactor to remove the check)
            return;
        }
        ...
Hi! This was my second approach I mentioned in the last paragraph:
I've also tried other approaches, like checking if the next player can still make moves while the next player is being determined and then let him pass immediately, or adding a new state to the state machine where the current player automatically passes. It all comes down to the fact that I can't perform the actions with the error message reported above. So I guess that the state machine is not updated properly. Is there anything else I need to do? Many thanks for your help!
My code is:

Code: Select all

    //////////// --- Game state actions generated begin ---
    function st_gameTurnNextPlayer() {
        $next_player_id = $this->activeNextPlayerCustom();
        if ($next_player_id == null) {
            // all passed activate turn order change
            $this->sactionReorderPlayers();
            // next
            $this->gamestate->nextState('last');
            return;
        }
        if (!$this->calculateActionSlots(false)) {
            self::notifyAllPlayers('message',
                clienttranslate('${player_name} cannot perform any actions and has to pass'),
                array('player_name' => self::getActivePlayerName(), 'player_id' => self::getActivePlayerId())
            );
            $this->action_pass();
            return;
        }
        $this->gamestate->nextState('next');
    }
But when a player uses his last ruble/worker I get the error message "This game action is impossible right now" and the last selected action was not executed. Even though I added "pass" to the possible actions array in *.states.php:

Code: Select all

        'gameTurnNextPlayer' => array (
                "type" => "game",
                "updateGameProgression" => true,
                "possibleactions" => array (
                    "pass",
                ),
                "transitions" => array (
                        "next" => 'playerTurnPlaceWorker',
                        "last" => 'gameTurnEndOfRound',
                ) 
        ),
User avatar
Victoria_La
Posts: 665
Joined: 28 December 2015, 20:55

Re: Add new states/buttons etc. (Russian Railroads)

Post by Victoria_La »

Well since I did it anyway I commited the code, it just 10 lines - functions I posted already and implementation of new function to check is player needs to pass. No state machien changes required. You can checkout the new code if you have access to project. If you test it and its ok I can deploy it.
User avatar
Tikhonov
Posts: 14
Joined: 24 June 2020, 13:08

Re: Add new states/buttons etc. (Russian Railroads)

Post by Tikhonov »

I just tested it and it works fine, thanks! I just would change the log output ("${player_name} has no legal moves, therefore they must pass") to "${player_name} has no legal moves and therefore has to pass" or something similar :)
Post Reply

Return to “Developers”