Page 1 of 1

The Case of the Disappearing Divs

Posted: 02 February 2023, 21:06
by IndianaScones
I'm having some trouble implementing my first couple game states. The first state is a "game" state that simply places a set number of character elements in a wrapper beneath the title message area so that the players can choose from them. That transitions to an "activeplayer" state where the player chooses a character.

The problem I'm having is that when the game loads into the "activeplayer" state, the character divs are no longer in the wrapper. Or anywhere else. The relevant code:

states.php -

Code: Select all

2 => array(
        "name" => "characterInit",
        "description" => "",
        "type" => "game",
        "args" => "argCharacterInit",
        "action" => "stCharacterInit",
        "transitions" => array("characterInit" => 3)
),

3 => array(
        "name" => "characterSelection",
        "description" => clienttranslate('${actplayer} must choose a character'),
        "descriptionmyturn" => clienttranslate('${you} must choose a character'),
        "type" => "activeplayer",
        "possibleactions" => array("chooseCharacter"),
        "transitions" => array("chooseCharacter" => 4)
game.php -

game state argument -

Code: Select all

function argCharacterInit() {
        return array(
            'available_characters' => $this->getGlobalVariable('available_characters'),
        );
    }
game state action -

Code: Select all

function stCharacterInit() {
    //$this->gamestate->nextState('characterInit');
}
player action -

Code: Select all

function chooseCharacter($character) {
    self::checkAction('chooseCharacter');
    $player_id = self::getActivePlayerId();
    self::DbQuery("UPDATE player SET `character`='$character' WHERE player_id='$player_id'");
    self::notifyAllPlayers( "chooseCharacter", clienttranslate('${player_name} chooses ${character}'), array(
        'player_name' => self::getActivePlayerName(),
        'character' => $this->characters[$character]['description'],
        'character_div' => "character_{$character}"
    ));

    $this->gamestate->nextState('chooseCharacter');
}
game.js, onEnteringState -

Code: Select all

case 'characterInit':
    for (let character_id of args.args.available_characters) {
        let character = this.gamedatas.characters[character_id];
        let bg_pos = character['x_y'];
        dojo.place(this.format_block('jstpl_character', {
            type : character_id,
            extra_class : "character_select",
            charX : bg_pos[0],
            charY : bg_pos[1],
            extra_style : "margin-top: 5px; margin-right: 5px; position: relative",
        }), 'character_selection');
        let html = `<div style="margin-bottom: 5px;"><strong>${character['description']}</strong></div>
                          <p>${character['flavor']} - ${character['effect']}</p>
                          <p>Starting Water/Psych: ${character['water_psych']}</p>
                          <span>Home Crag: ${character['home_crag']}</span>
                          <span style="font-size: 10px; white-space: nowrap;"><i>${character['translation']}</i></span>`;
        this.addTooltipHtml(`character_${character_id}`, html, 1000);
    }
    break;

case 'characterSelection':
    dojo.query('.character_select').connect('onclick', this, 'onChooseCharacter');
    break;
FWIW, the console also fails to log 'Entering state: characterInit'.

I know the divs are getting placed, because if I comment out the state transition from "characterInit" to "chooseCharacter", I can see the divs when I load the game and the state is logged to the console, but of course nothing happens next because it's now an inert state.

For my life I can't figure out what's happening to the divs between states.

Re: The Case of the Disappearing Divs

Posted: 02 February 2023, 23:18
by robinzig
I'm not really sure I follow the details here very well - but I suggest that whatever you're trying to do, you do in a different way. It makes zero sense (to me at least) to have a "game" state that doesn't actually do anything on the server side. (And if you do need to do something on the server side before any player actions that I'd prefer to put that in setUpNewGame anyway.)

Why not place your divs at the start of the corresponding activeplayer state, if the purpose of them being there is for the active player to select one of them?

Re: The Case of the Disappearing Divs

Posted: 03 February 2023, 00:16
by IndianaScones
robinzig wrote: 02 February 2023, 23:18 I'm not really sure I follow the details here very well - but I suggest that whatever you're trying to do, you do in a different way. It makes zero sense (to me at least) to have a "game" state that doesn't actually do anything on the server side. (And if you do need to do something on the server side before any player actions that I'd prefer to put that in setUpNewGame anyway.)

Why not place your divs at the start of the corresponding activeplayer state, if the purpose of them being there is for the active player to select one of them?
So if I place the divs at the start of the corresponding activeplayer state, then I have to clean them up at the end of the state or they will be duplicated when it comes back to the same activeplayer state (for the next player to choose a character).

That's fine but I thought that if I placed them beforehand, it would be more efficient as I could just move the existing ones, instead of recreating them each time it loops back around to that state.

As for setUpNewGame, the only reason I made a functionless game state was so that I could trigger placing the divs in JS under onEnteringState. I know I can put it in the JS setup, but then it'll have to be handled every time the JS setup runs, whereas if it was in onEnteringState for a game state that will never be reached again, then it's done and out of the way.

I hope that made sense. All of that said, yes I'm going to have to find another way because it seems it's just not possible to create persistent divs in this way. I reproduced the issue in Reversi. If I make an initial game state and create html in the onEnteringState for it, it is gone by the time the first activeplayer state is reached.

Re: The Case of the Disappearing Divs

Posted: 03 February 2023, 01:07
by ufm
Put an if to detect the div in question first.
I'd rather create divs during setup as robinzig said though. Changes occurring later can be reflected via notifs.

Re: The Case of the Disappearing Divs

Posted: 03 February 2023, 14:13
by robinzig
IndianaScones wrote: 03 February 2023, 00:16 So if I place the divs at the start of the corresponding activeplayer state, then I have to clean them up at the end of the state or they will be duplicated when it comes back to the same activeplayer state (for the next player to choose a character).
Well yes, of course. That's what onEnteringState/onLeavingState are for - to add and remove any UI elements that are specific to a particular state.

Even if the approach you were trying was working, you'd still have to remove the divs at some point, unless you want them persisting for the entire game if a player is online at the point your initial "game" state starts and doesn't leave or refresh the page (eg. in a real-time game).

Re: The Case of the Disappearing Divs

Posted: 03 February 2023, 16:21
by IndianaScones
I was going to create them in the state, move them where they would stay for the rest of the game, and remove the ones nobody chose. But at any rate I'm going to handle it all in the JS setup() now.

Re: The Case of the Disappearing Divs

Posted: 04 February 2023, 09:54
by RicardoRix
Yeah, the setup needs to handle the game at any given time, a user can always press F5 at any time. You may even need to consider this half way through their turn.