Howdy, Stranger!

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

Help With

I am currently working on a Twine Story, and I have run into a problem. I am using SugarCube 1.0.34 with Twine 2. When I try to use <<print either>>, it ends up giving me the error "Error: <<print>>: bad expression: Unexpected token ILLEGAL".
If you would like to see what I attempted to use:
<<print either("Greg began to walk away when it asked 'May I have that gun?' Greg stopped and looked back at it.

Give
Continue", "The Riot member sat in silence. It stood perfectly still as Greg walked away. Greg turned a corner when he heard the squeak of a window opening.

RevKit")>>

Comments

  • You're using the either function to display a really complex string. With a bit of fiddling you could make it work (treat line breaks differently, escape where necessary), but I don't suggest to go that route.

    The simpler solution is to break the code & content down like this:
    <<nobr>>
    	<<set $result to either("havegun", "satstil")>>
    
    	<<if $result eq "havegun">>
    		"Greg began to walk away when it asked 'May I have that gun?' Greg stopped and looked back at it.<br><br>
    		
    		[[Greg gives it the gun.|Give]]<br>
    		[[Greg continues walking.|Continue]]
    	<<else>>
    		"The Riot member sat in silence. It stood perfectly still as Greg walked away. Greg turned a corner when he heard the squeak of a window opening.<br><br>
    
    		[[Greg heads to the kitchen.|RevKit]]
    	<<endif>>
    <<endnobr>>
    
  • Kigner wrote: »
    If you would like to see what I attempted to use:
    <<print either("Greg began to walk away when it asked 'May I have that gun?' Greg stopped and looked back at it.
    
    [[Greg gives it the gun.|Give]]
    [[Greg continues walking.|Continue]]", "The Riot member sat in silence. It stood perfectly still as Greg walked away. Greg turned a corner when he heard the squeak of a window opening.
    
    [[Greg heads to the kitchen.|RevKit]]")>>
    
    As mentioned by MoLoLu, you cannot simply place line breaks within a string like that and enclosing large chunks of content within a string could present you with escaping issues if you're not careful.

    That said, I'm going to suggest a slightly different solution than MoLoLu did for a few reasons.
    1. Using <<nobr>> here really is unnecessary, since there's only a few extraneous line breaks you probably want to remove. The line continuation markup allows you to remove line breaks on an individual basis.
    2. Storing a temporary value, like the result of either(), within a story variable is not ideal. You should either not use a story variable in the first place or <<unset>> it after it's no longer necessary—SugarCube 2 adds temporary variables specifically for this purpose.
    3. Using randomly selected strings to determine which bit of content is used is less than optimal. While not as descriptive, simply using random() here is the better way to go.

    I'd suggest something like the following. For this example I'm going to use line continuations and the special setup object—rather than using a story variable and unsetting it after.
    <<set setup.roll to random(1, 2)>>\
    <<if setup.roll is 1>>\
    Greg began to walk away when it asked "May I have that gun?" Greg stopped and looked back at it.
    
    [[Greg gives it the gun.|Give]]
    [[Greg continues walking.|Continue]]
    <<else>>\
    The Riot member sat in silence. It stood perfectly still as Greg walked away. Greg turned a corner when he heard the squeak of a window opening.
    
    [[Greg heads to the kitchen.|RevKit]]
    <</if>>\
    

    The basic idea here is the following:
    → A randomly selected choice with two possible outcomes.
    <<set setup.roll to random(1, 2)>>\
    <<if setup.roll is 1>>\
    	… outcome 1 …
    <<else>>\
    	… outcome 2 …
    <</if>>\
    
    → A randomly selected choice with three possible outcomes.
    <<set setup.roll to random(1, 3)>>\
    <<if setup.roll is 1>>\
    	… outcome 1 …
    <<elseif setup.roll is 2>>\
    	… outcome 2 …
    <<else>>\
    	… outcome 3 …
    <</if>>\
    
    → A randomly selected choice with four possible outcomes.
    <<set setup.roll to random(1, 4)>>\
    <<if setup.roll is 1>>\
    	… outcome 1 …
    <<elseif setup.roll is 2>>\
    	… outcome 2 …
    <<elseif setup.roll is 3>>\
    	… outcome 3 …
    <<else>>\
    	… outcome 4 …
    <</if>>\
    
    Et cetera.
  • Oh dear. I really don't want this to turn into a back and forth but neither of our answers seem to be complete. What MadExile said is absolutely correct. There are some caveats to consider here, depending on application:
    line continuation markup allows you to remove line breaks on an individual basis.

    The deciding factor in these two methods is how much you want to format the code and how many escapes this will require. When you get into complex conditions, continuation becomes a major headache and virtually impossible to read. In very long text passages with dozens of conditionals, it can become hard to tell what lines are being continued vs which ones are not. In OP's example however this is a non-issue.
    Storing a temporary value within a story variable is not ideal.

    This is true except if you want to reference it later on. Consider a scenario with several branching plots that get 'recombined' at some point. After the recombination, you want to know which option the player took. If you don't store the variable, you now have to write multiple sets of passages, whereas with the stored variable you can check this later and adjust content accordingly. Again depends on story complexity and whether you want to reference the value down the line.
  • edited October 2016
    MoLoLu wrote: »
    In OP's example however this is a non-issue.
    This was a practical example for Kigner. At no point did I say that one should never use <<nobr>>, simply that here, in this case, it was unnecessary—read: overkill.

    Case in point, as I noted when I mentioned line continuations, "Using <<nobr>> here really is unnecessary, since there's only a few extraneous line breaks you probably want to remove." (emphasis added)

    MoLoLu wrote: »
    Storing a temporary value within a story variable is not ideal.
    This is true except if you want to reference it later on.
    If you need the value on a later turn, then I don't consider it a temporary value. This is a definition issue. My definition of a temporary value, as it relates to story formats, has two requirements:
    • It has a limited, usually very short, useful lifespan. Usually, a single turn.
    • It does not require more permanent storage.
    By definition, story variables are more permanent storage.

    Having a useful lifespan of several turns and requiring the use of story variables does not meet the bar.
  • Again, I agree on all accounts. My intent was just to raise awareness to the fact that there are benefits and drawbacks to either approach depending on the situation.

    This was one of the mistakes I made early on (and still do to some extent) - adhering to inefficient practices because I wasn't aware of alternatives. The implication of scope may be obvious to me now but it wasn't early on. From the example given, we can't infer the scope or future consequences. Hence my interest in elaborating on both methods, so @Kigner can decide which suits their needs best.
Sign In or Register to comment.