Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Is there a way to have a list of pickable options?

edited September 2016 in Help! with 1.x
I am brand new to Twine. As in, I started my first adventure in it last night, less than 24 hours ago. I do have some programming experience in general and have an (extremely) rudimentary combat engine written in it, as I want it to have a bit of an RPG-feel to it.

However, my issue is I'm having to create so many passages to select all the options I want for combat. Right now, you can select whether to attack the head or body and then pick your attack. But they're all individual passages, so it looks like this:

In room1:

Do you want to attack [the head] or [the body]?

Then passages the head and the body both have something like:

Go for a KO attack.
Go for a stun attack.

And so on for all the options. Then all the attack passages created (KO and Stun) largely have the same code in them and there is a LOT of passages. This feels very inefficient to me. Tweaking the combat formula would be awful, as I'd have to go through every passage and change it in them all. Is there a way I could just put a list in a passage? You could pick all your options (what area to target, which attack to use, pick a special attack once I implement that, etc) and then it moves onto a second passage where it processes the choices.

The engine is functional right now, though unwieldy. (And also not exciting. It takes a _very_ long time to finish combat.) This seems like the first step towards making it better. Any suggestions?

*Edited to add: I'm using 1.4.2 with Sugarcane*

Comments

  • edited October 2016
    You're right. This is a inefficient way to set up combat - but don't worry, I made the same mistake in the beginning. The simplest way to set up combat (IMO at least; I've tried a few and this worked best) is to use one 'combat' passage and output results to HTML via <<replace>> and nested <<display>> macros.

    I'd link you my source for Scaffold 22 (which implements a fluid, low-load and highly customization turn-based combat system) but it'll be too confusing unless you already know what the code does. Thus, to present the concept, I'll try to simplify. This may help inspire you for a simpler variation.

    Overview

    I have three main passages:

    - combat UI (sets up a bunch of default values and generates the HTML elements used to display actions; basically the equivalent of initialization)

    - player action (updates everything related to the player's attacks by grabbing the elements set up in the UI and doing <<replace>>/<<display>> with a passage that contains all the logic)

    - enemy action (does the same thing as player actions just affecting stuff related to the enemy).

    Code
    Going into more detail, what I do in a watered down version is:

    Combat UI:
    <<display $enemytype>>
    <div id='combat_player'>//some basic stuff here</div>
    <div id='combat_enemy'>//some basic stuff here</div>
    

    Then when the player hits an attack button it calls the player action, which does:
    <<click 'attack'>> 
    <<set $attacktype = "fist">>
    <<replace '#combat_player'>>
    <<display 'do_player_actions'>>
    <</replace>>
    <</click>>
    

    And then does the same for enemy actions. The 'scenario' for the enemy is set up in a separate passage that defines their health, armor, etc. This is the initial $enemytype call, which populates a bunch of variables that define what text will appear, etc.

    Naturally, it's a lot more complex in practice, as I have to replace a whole bunch of other elements (player stats, enemy stats, items, ammo counters, yadda yadda). The key here is that by displaying passages I can customize a lot of content via variables and even re-order the way events flow if I want the enemy to move first. I'm basically just using the <<replace>>/<<display>> structure as a stand-in for what would usually be functions in regular programming languages.

    You can see the concept in action here: (excuse the rambling; I ramble a lot in these videos)

    Also note that, technically, the Twine story considers itself in the passage Combat UI for the duration of a battle. Bits and pieces of HTML simply get replaced without ever actually moving to another passage (the content is displayed but the screen never transitions). This continues until the combat is won and the player clicks some sorta 'continue' button, which then commits the changes made in combat to the story's history by moving to the next passage (defined somewhere in the Combat UI setup).

    One (dis?)advantage of this system is that if the player refreshes the browser tab, it simply resets combat back to its original state, allowing them to retry the battle. You can work around that though by making the combat state transition before every player action (which I admittedly don't do to ensure everything remains fluid).

    Hope this helps!
  • astrosteve wrote: »
    And so on for all the options. Then all the attack passages created (KO and Stun) largely have the same code in them and there is a LOT of passages. This feels very inefficient to me. Tweaking the combat formula would be awful, as I'd have to go through every passage and change it in them all. Is there a way I could just put a list in a passage?

    [...]

    *Edited to add: I'm using 1.4.2 with Sugarcane*
    I'm new to Twine to and like you I use 1.4.2 (perhaps not for long). Great thing that I found your thread, because I have the same problem when I work with my first game. Not with combat though (I plan on doing that later), but with selections such as 'yes' or 'no' or picking up items for later use...

    MoLoLu, so if I want to make different selections for let's say three different passages, and the choice will affect the outcome of the three, I'll have to use macros too?

    For example. "I'm sitting in front of my computer and reading the Twine forums. I have three choices: starting a new thread (A), commenting on a current thread (B) or editing my profile (C)."

    That would be three passages. In this example though, I'll make it easy and let the outcome of the three afterwards be the same: I'll log off and shut my laptop down (D).

    So naturally I would make the three passages end with one passage. But what if I want to visit the passages in different order?

    For example: I'll do A first, then B, C and D. But I could also do C first and then B and A... You can see that will be many different combinations. And for each passage, I would like the reader not to do some steps again, like he's done B already - so B is not selectable again.

    But like in astrosteve's case, I realise that tweaking the passages in order for the combinations to work flawlessly isn't very effective.

    So what should I do? Macros all the way?
  • note: I strongly suggest you consider switching to the SugarCube story format instead, preferably the 2.x series which is still actively being developed. The current version of Sugarcane was released in mid 2014 and it has a number of limitations / bugs, some of which have been fixed in the project's source code but those fixes are currently only available to people who know how build their own version of Sugarcane.

    You can use a story $variable to track which option was selected and a combination of <<if>>, <<elseif>>, and <<else>> macros to control what is displayed within a passage, so it is possible to have options A, B, C, and D all target the same passage is you want.
    The following example was written for Sugarcane but it will also work in SugarCube as is, although the default format for the <<endif>> macro in SugarCube is <</if>>. The example .

    1. The First passage, it is using a link type generally known as a Setter Link:
    Select an option:
    
    [[Option A|Next Passage][$option to "A"]]
    [[Option B|Next Passage][$option to "B"]]
    [[Option C|Next Passage][$option to "C"]]
    [[Option D|Next Passage][$option to "D"]]
    
    2. The Next Passage passage:
    <<if $option is "A">>A was the option selected.
    <<elseif $option is "B">>B was the option selected.
    <<elseif $option is "C">>C was the option selected.
    <<else>>D was the option selected.
    <<endif>>
    
  • Greyelf pretty much covered it. Variables are the way to go with this. Once you get the hang of the basics, it's fairly straightforward.

    To add a little more depth, you can save on a lot of passages and inter-linked chaos by setting up a "logic" and "content" structure (which is smth I make use of a lot due to the sheer volume of content in Scaffold 22). After lots of testing and experimenting, I more or less settled on this as an effective format:

    - one passage with logic; consider this a "scene"
    - one passage with text per user 'option'; consider this the "script"

    What this results in is:

    Somewhere in the beginning set:
    <<set $action1 = "">>
    <<set $action2 = "">>
    

    Now the Logic Passage (let's call it 'logic' in the example):
    <<if $action1 eq "">>
    <<display 'text1'>>
    [[Yes|logic][$action1 = "Yes"]]
    [[No|logic][$action1 = "No"]]
    <<elseif $action2 eq "">>
    <<display 'text1'>>
    <<display 'text2'>>
    [[Continue|next_logic_passage][$action1 = ""]]
    <<endif>>
    


    This allows you to set up 'scenes' that re-use the same passage and then bring in multiple text blocks as options develop (which is how I allow the player to 'view' prior actions in Scaffold 22, with a maximum of 6 actions in sequence, before I clear all the variables and move to a new scene).

    Text1 would then be some generic text, while Text2 would be:
    <<if $action1 eq "Yes">>
    You said YES!
    <<elseif $action2 eq "No">>
    You said NO!
    <<endif>>
    

    Now, if there are now 10 options in the first block of 'logic' I can just build 10 if/elseif blocks in Text2 and avoid having to write 10 separate passages to account for a few minor differences in player response.

    You can set this up in a number of different ways depending on how you want to write and structure your passages. But the basic gist of it is you use variables to track what the player selected, and then adjust the text to display based on that.
  • Greyelf pretty much covered it. Variables are the way to go with this. Once you get the hang of the basics, it's fairly straightforward.

    To add a little more depth, you can save on a lot of passages and inter-linked chaos by setting up a "logic" and "content" structure (which is smth I make use of a lot due to the sheer volume of content in Scaffold 22). After lots of testing and experimenting, I more or less settled on this as an effective format:

    - one passage with logic; consider this a "scene"
    - one passage with text per user 'option'; consider this the "script"

    What this results in is:

    Somewhere in the beginning set:
    <<set $action1 = "">>
    <<set $action2 = "">>
    

    Now the Logic Passage (let's call it 'logic' in the example):
    <<if $action1 eq "">>
    <<display 'text1'>>
    [[Yes|logic][$action1 = "Yes"]]
    [[No|logic][$action1 = "No"]]
    <<elseif $action2 eq "">>
    <<display 'text1'>>
    <<display 'text2'>>
    [[Continue|next_logic_passage][$action1 = ""]]
    <<endif>>
    


    This allows you to set up 'scenes' that re-use the same passage and then bring in multiple text blocks as options develop (which is how I allow the player to 'view' prior actions in Scaffold 22, with a maximum of 6 actions in sequence, before I clear all the variables and move to a new scene).

    Text1 would then be some generic text, while Text2 would be:
    <<if $action1 eq "Yes">>
    You said YES!
    <<elseif $action2 eq "No">>
    You said NO!
    <<endif>>
    

    Now, if there are now 10 options in the first block of 'logic' I can just build 10 if/elseif blocks in Text2 and avoid having to write 10 separate passages to account for a few minor differences in player response.

    You can set this up in a number of different ways depending on how you want to write and structure your passages. But the basic gist of it is you use variables to track what the player selected, and then adjust the text to display based on that.
Sign In or Register to comment.