Issue with buttons

Twine Version: 2.8.1.0
Story Format: Sugarcube 2.36.1

Basically I was making a novel with a card game mechanic, it going decently until I ran into an issue with the buttons.

Basically I press one of the buttons created by a for loop and it returns the wrong card. Like the button is index 0 but in player info text it’s saying index 6 and it’s a completely different card

I tried asking gpt for help but it made it worse if anything.

I think it’s either the index or the update display but I decided to post for help in finding the issue.

(Below is the code that handles playing the card and player turn that’s both in storyinit, and the battle passage)

I’m having trouble updating the buttons in my Twine game. When I play a card, the display doesn’t refresh correctly to show the updated state. Below is my updateDisplay function and setup.playCard function, along with the BattleStart passage. Can someone help me identify what might be going wrong?

// updateDisplay function
window.updateDisplay = function() {
    console.log('Updating display');

    // Update opponent mood
    var opponentMoodElement = document.getElementById('opponentMood');
    if (opponentMoodElement) {
        opponentMoodElement.innerHTML = State.variables.characters["Cala"].mood.emotion + ' (' + State.variables.characters["Cala"].mood.value + ')';
        console.log('Updated opponent mood');
    } else {
        State.variables.opponentInfoText += " [Debug: Cala's mood not displayed]";
    }

    // Update player mood
    var playerMoodElement = document.getElementById('playerMood');
    if (playerMoodElement) {
        playerMoodElement.innerHTML = State.variables.characters["Player"].mood.emotion + ' (' + State.variables.characters["Player"].mood.value + ')';
        console.log('Updated player mood');
    } else {
        State.variables.playerInfoText += " [Debug: Player's mood not displayed]";
    }

    // Update opponent info text
    var opponentInfoTextElement = document.getElementById('opponentInfoText');
    if (opponentInfoTextElement) {
        opponentInfoTextElement.innerHTML = State.variables.opponentInfoText;
        console.log('Updated opponent info text');
    }

    // Update player info text
    var playerInfoTextElement = document.getElementById('playerInfoText');
    if (playerInfoTextElement) {
        playerInfoTextElement.innerHTML = State.variables.playerInfoText;
        console.log('Updated player info text');
    }

    // Update player's card buttons
    var playerCardsContainer = document.getElementById('playerCardsContainer');
    if (playerCardsContainer) {
        playerCardsContainer.innerHTML = ''; // Clear existing buttons
        console.log('Cleared existing buttons');
        for (var i = 0; i < State.variables.playerCards.length; i++) {
            var card = State.variables.playerCards[i];
            var button = document.createElement('button');
            button.innerHTML = 'Play ' + card.name + ' (' + i + ')';
            button.onclick = (function(index) {
                return function() {
                    setup.playCard(index);
                };
            })(i);
            playerCardsContainer.appendChild(button);
            console.log('Added button for card:', card.name, 'at index:', i);
        }
    } else {
        console.log('playerCardsContainer not found');
    }
};

// setup.playCard function
setup.playCard = function(index) {
    var playerCharacter = "Player";
    var currentCharacter = "Cala";

    // Ensure the card index is within bounds
    if (index < 0 || index >= State.variables.playerCards.length) {
        State.variables.playerInfoText += " [Error: Invalid card index " + index + "]";
        return;
    }

    // Play the card
    var card = State.variables.playerCards[index];
    // Debug: Log the card being played and its index
    State.variables.playerInfoText += " [Debug: Playing card " + card.name + " at index " + index + "]";

    setup.updateMood(currentCharacter, card);

    // Update player info text
    State.variables.playerInfoText = "You played " + card.name + " (Emotion: " + card.emotion + ", Value: " + card.value + "). " +
                                     "Opponent's mood is now " + State.variables.characters[currentCharacter].mood.emotion + " (" + 
                                     State.variables.characters[currentCharacter].mood.value + ").";

    // Remove the played card from the player's hand
    State.variables.playerCards.splice(index, 1);
    // Draw a new card and add to the player's hand
    var newCard = setup.drawCard(playerCharacter);
    State.variables.playerCards.push(newCard);

    // End player's turn
    State.variables.playerTurn = false;
    setup.opponentTurn();

    // Update the display to refresh the buttons and other elements
    updateDisplay();
};

// BattleStart passage
:: BattleStart
<<set $playerCharacter = "Player">>
<<set $currentCharacter = "Cala">>
<<set $playerTurn = true>>
<<set $playerCards = []>>
<<set State.variables.playerInfoText = "">>
<<set State.variables.opponentInfoText = "">>

<!-- Initial opponent move -->
<<set _opponentCard = setup.drawCard($currentCharacter)>>
<<run setup.updateMood($playerCharacter, _opponentCard)>>
<<set State.variables.opponentInfoText = $currentCharacter + " played " + _opponentCard.name + " (Emotion: " + _opponentCard.emotion + ", Value: " + _opponentCard.value + "). Player's mood is now " + State.variables.characters[$playerCharacter].mood.emotion + " (" + State.variables.characters[$playerCharacter].mood.value + "). [Debug: Initial opponent move]>>

<!-- Update display on initial load -->
<<script>>
updateDisplay();
<</script>>

<div style="text-align: center;">
    <div>
        <strong>Opponent Information:</strong>
        <p id="opponentInfoText"><<print State.variables.opponentInfoText>></p>
    </div>
    <div style="margin-bottom: 20px;">
        <strong>Opponent Mood: <span id="opponentMood"><<print State.variables.characters["Cala"].mood.emotion>> (<<print State.variables.characters["Cala"].mood.value>>)</span></strong>
    </div>
    <div style="margin-bottom: 20px;">
        <strong>Player Mood: <span id="playerMood"><<print State.variables.characters["Player"].mood.emotion>> (<<print State.variables.characters["Player"].mood.value>>)</span></strong>
    </div>
    <div>
        <strong>Player Information:</strong>
        <p id="playerInfoText"><<print State.variables.playerInfoText>></p>
    </div>

    <!-- Player's turn to play cards -->
    <<if $playerTurn>>
        <div>
            <strong>Play Your Cards:</strong>
            <br>
            <!-- Initialize player's hand if empty -->
            <<if $playerCards.length == 0>>
                <!-- Initialize player's hand with 7 random cards -->
                <<for _index = 0; _index < 7; _index++>>
                    <<set _card = setup.drawCard($playerCharacter)>>
                    <<set $playerCards.push(_card)>>
                <</for>>
            <</if>>
            <!-- Display buttons for random cards -->
            <<for _index, _card range $playerCards>>
                <<button "Play <<print _card.name>> (<<print _index>>)">>
                    <<set _playedCard = $playerCards[_index]>>
                    <<set State.variables.playerInfoText += " [Debug: Attempting to play card " + _card.name + " at index " + _index + "]">>
                    <<run setup.playCard(_index)>>
                <</button>>
            <</for>>
        </div>
    <</if>>
</div>
1 Like

I’m guessing you need a <<capture>> in your loop: is it always doing the last card?

Yes, I think so? I noticed that a few times

Edit: Okay so I did a quick check, on the first play of each card 0-6, it actually works, however the buttons don’t update the card names, so if I play “regret” it’s going to play that card once and if I press it again it’s going to play “irritation”, so once again the button doesn’t update

Edit2: nvm I figured it out, thank you for your help!