Turn Based Moves Question [Sugarcube 2.34.1]

If you are requesting technical assistance with Twine, please specify:
Twine Version: 2
Story Format: Sugarcube 2.34.1

Hello,

I’m new to interactive fiction and have been trying to make something of like a turn based board game. Being new to writing basic code, I was wondering exactly how to add a random number system [like a dice roll the indicates how many steps a player can take] and then to allow the player to move a single space until they run out of steps. Any advice wouldbe greatly appreciated.

ktk

The official Twine Cookbook includes a Dice Rolling recipe that demonstrates how to use SugarCube’s random() function to simulate the rolling of a die.

There is also a Setting and Showing Variables recipe that shows how to use the <<set>> macro to store values within variables. The recipe also shows how to use the same macro with a maths to increment the current numerical value stored within that variable, and you can use the same technique to decrement a number.

<<set $numberVariable to $numberVariable - 1>>

There is a third recipe named Conditional Statements that explains how to use the <<if>> family of macros to use the current value of a variable to determine if something should or shouldn’t be done.

You can combine the techniques of the above three recipes to produce something like the following TWEE Notation based example. Which consists of three Passages named Start, Walking, and Sit.

:: Start
<<set $steps to random(1, 6)>>
[[Start walking|Walking]]

:: Walking
You are walking along...
<<set $steps to $steps - 1>>

<<if $steps > 0>>[[Continue walking|Walking]]<</if>>
[[You've walked enough!|Sit]]

(debug: steps: $steps)

:: Sit
You're decide to sit down on the ground.

note: you can safely remove the (debug: steps: $steps) line, it’s only include so you can see that the steps counter is decreasing.

1 Like

I’m not sure quite what you want to happen when you say, “allow the player to move a single space until they run out of steps.” What do you want to have happen when a move occurs? Do you want one page with all results? Or each step to be its own page?

Anyways, hopefully this example of how to do a basic board game (think “Monopoly”, “Sorry”, “Candy Land” or the like) will point you in the right direction.

First you can set up your board as an array of objects within the StoryInit special passage:

<<set $maxRoll = 6>>
<<set $position = 0>>
<<set $board = []>>
<<set $board.push({ name: "Start", description: "Board square 0" })>>
<<set $board.push({ name: "Mediteranian Ave", description: "Board square 1" })>>
<<set $board.push({ name: "Community Chest", description: "Board square 2", include: "Community Chest" })>>
<<set $board.push({ name: "Baltic Ave", description: "Board square 3" })>>

Basically, just “push” each Object (i.e. the { ... } part) describing a board square into the $board array in the order that you want those squares to be around the board. If you want more squares on the board, simply add more lines that push them in. (Note: The .push() method is an Array method that lets you add an element to the end of an Array object.)

You can create the Objects however you want, using “key: value” pairs. In the above I used “keys” (also called “properties”) for “name”, “description”, and an optional “include” key for including code from other passages.

(Note: Basic key names should only be upper- or lower-case letters (a - z and A - Z), numbers, dashes (-), and/or underscores (_), and cannot start with a number. Putting other characters, such as a space, within a key name won’t work without doing some extra work on your part, so I’d recommend just sticking with basic key names. Note also that key names are case sensitive, so “Name” will NOT be treated the same as “name”.)

You could then create the “Board” and “Community Chest” passages like this:

:: Board
(Position = $position; Board size = <<= $board.length>> squares)

You are at the <<= $board[$position].name>> square.  It's the <<= $board[$position].description>> position.

<<if $board[$position].include>>\
	<<include $board[$position].include>>
<</if>>\
\
<<set _roll = random(1, $maxRoll)>>\
<<set $position = ($position + _roll) % $board.length>>\
You rolled a _roll.

[["Move " + _roll + " spaces"|Board]]

:: Community Chest
You draw a Community Chest card.

(code to do that goes here)

(Note: The “:: PassageName” parts above are just Twee shorthand to indicate the name of the passage for the text that follows, up until the next “:: PassageName” part.)

So, that code would let you play out a whole game board in just a few passages, using the $board array to do all of the “heavy lifting” to make the output different each time.

These lines:

<<set _roll = random(1, $maxRoll)>>\
<<set $position = ($position + _roll) % $board.length>>\

roll the die, moving you anywhere from 1 to whatever number $maxRoll is set to (in this case it’s 6) spaces forward on the board to the new position, and the second line makes sure that if you go past the end of the spaces in the $board array that you wrap back around (the % gives you the remainder of that division, e.g. 7 % 5 = 2, since 7 divided 5 leaves a remainder of 2).

This part:

<<if $board[$position].include>>\
	<<include $board[$position].include>>
<</if>>\

Makes it so that, if the $board object at $position has an “include” property, then it will <<include>> the contents of the passage named by that property within the passage. See the <<include>> macro documentation for details on how that works.

Hope that helps! :slight_smile:

1 Like