Howdy, Stranger!

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

Adding Inventory Tab

I'm using Twine 2, SugarCube 2.

I'm considering adding an inventory tab to my game.

But I'm not sure how to implement it, and whether it would work well with this type of game.

If I were to do it I'd want something simple, perhaps even just a faded gray link that's always there (except on title and end passages) and says something like "inventory" or "your pocket," and when you click on it you see a list of what you're currently carrying, and if you're not carrying anything, it says something like "inventory is empty". And you should always be able to go from the inventory passage/tab back to the passage you just came from.

How can I do that? I think I read somewhere about Inventory macros but I can't find that now.

Comments

  • You should probably define exactly what you want your inventory to do/accomplish first.

    If you want something simple, then you probably don't need the various inventory macros. A simple key item type inventory is easily done with story variables.
  • A simple key item type inventory
    This.

    You checked out the game, so maybe you remember that it already has a key item type inventory system, but the player can't see what they're carrying. So I want every passage to have a link that says "inventory", and when you click on it, you're taken to a separate inventory passage.

    The inventory passage would have a list of everything you're carrying right now, and a "back" arrow that would take you back to the passage you clicked from.

    So if you just found a key, the inventory passage would say "A key". And if you just used the key and aren't carrying anything else, it would say "Empty." And so on.
  • You could try something like the following.

    I don't know where you'd want to place the inventory link, however, I think at the top isn't a bad place for it in your current layout—say, top right. With that in mind: create a new passage, name it PassageHeader, and place the something like following within:
    @
    
    Do not put extra line breaks in there.


    Create a new passage, name it Inventory, and place something like the following within:
    !!Your inventory:
    <<if
    	((ndef $Eyes) or $Eyes lt 1)
    	and not $hasTooth
    	and not $hasSeed
    >>\
    Empty.
    <<else>>\
    <<if $Eyes>><<if $Eyes is 1>>An eye<<else>>Two eyes<</if>>
    <</if>>\
    <<if $hasTooth>>A tooth
    <</if>>\
    <<if $hasSeed>>A seed
    <</if>>\
    <</if>>
    <<return>>
    
    NOTES
    • The $Eyes subcondition of the initial <<if>> conditional is somewhat convoluted because of the way you seem to be handling its values—without looking through your entire project, you don't seem to be initializing your values anywhere.
    • If the player had the ability to leave the inventory screen/page by clicking on other links—to other inventory screens or elsewhere—you'd need something a tiny bit more complicated than a simple <<return>>. Without those complications, however, it alone will be sufficient to return the player to wherever they were.


    ADDITIONAL TIPS
    While looking at your project to be able to give you an on-target example for the inventory screen/page, I noticed some subpar coding behaviors. Here are some suggestions that will, hopefully, be of use to you.
    • Choose a naming style for your variables and stick to it—i.e. $saweye, $saw_eye, $sawEye, $SawEye, etc. Just from the little bit of your project I've looked at, you've used both the PascalCase and camelCase styles. Vacillating between styles can bite you in the arse down the line—i.e. was it $hasSeed or $HasSeed. Variables are case sensitive, so consistency matters.
    • Do not check a boolean value against the boolean literals. All conditionals resolve to boolean values, so if you have a boolean value already, then simply use it. For example:
      /* BAD */
      <<if $hasSeed is true>>…has seed…
      <<if $hasSeed is false>>…does not have seed…
      
      /* GOOD */
      <<if $hasSeed>>…has seed…
      <<if not $hasSeed>>…does not have seed…
      
    • In the Tree Hollow passage, I'd suggest replacing the following logic snafu, because what you have now is a maintenance nightmare:
      <<if $Eyes lt 1 and $hasTooth is false and $hasSeed is false>>[[An eye.|Eye]] [[A tooth.|Tooth]] [[A seed.|Seed]]<<elseif $Eyes lt 1 and $hasTooth is true and $hasSeed is false>>[[An eye.|Eye]] [[A seed.|Seed]]<<elseif $Eyes lt 1 and $hasTooth is false and $hasSeed is true>>[[An eye.|Eye]] [[A tooth.|Tooth]]<<elseif $Eyes lt 1 and $hasTooth is true and $hasSeed is true>>[[An eye.|Eye]]<<elseif $Eyes gte 1 and $hasTooth is false and $hasSeed is false>>[[A tooth.|Tooth]] [[A seed.|Seed]]<<elseif $Eyes gte 1 and $hasTooth is true and $hasSeed is false>>[[A seed.|Seed]]<<elseif $Eyes gte 1 and $hasTooth is false and $hasSeed is true>>[[A tooth.|Tooth]]<<elseif $Eyes gte 1 and $hasTooth is true and $hasSeed is true>>Empty.<</if>>
      
      Try something like the following instead:
      <<if $Eyes gte 1 and $hasTooth and $hasSeed>>\
      Empty.\
      <<else>>\
      <<if (ndef $Eyes) or $Eyes lt 1>>[[An eye.|Eye]] <</if>>\
      <<if not $hasTooth>>[[A tooth.|Tooth]] <</if>>\
      <<if not $hasSeed>>[[A seed.|Seed]]<</if>>\
      <</if>>
      
      I imagine that you probably have other instances of overly complicated conditionals elsewhere within your project.
  • Thank you! You're a lifesaver, that worked perfectly.

    And thanks for the boolean clarification. I didn't know the "is true/false" part is unnecessary. I'll make changes accordingly (in the meantime, is it actually harmful to have the overly complicated conditionals, or is it just inconvenient?).
  • Hawkmoth wrote: »
    […] in the meantime, is it actually harmful to have the overly complicated conditionals, or is it just inconvenient? […]
    Mostly the latter. They're not directly harmful, though unnecessary complexity is harmful in its own way. Reworking them as is convenient is perfectly fine.
  • I'm new to working with Sugarcube and Twine as a whole, so my answer might be incredibly inefficient. I do however do a lot of programming. What you can do is initialize an array variable initialized in StoryInit as
    <<set $Inventory to []>>
    

    To have the player access it, you can put a link in StoryMenu, or StoryFooter that leads to a passage containing your inventory. In order to get back you can just use a link with previous().
    [[Return|previous()]]
    

    For displaying the Inventory, you can go about it however you want but I simply run the $Inventory array through a 'for' loop which prints out the values until there are no more.
    This is your inventory:
    <<if $Inventory.length > 0>>
    <<for _i = 0;_i<$Inventory.length;_i++>>
    <<print (_i+1) + ". " + $Inventory[_i]>>
    <</for>>
    <<else>>
    Your inventory is empty!
    <</if>>
    

    Every time you want to add something to the inventory you can insert the new item name or variable into $Inventory using .push(). So if I'm adding $book to $Inventory I'd use.
    <<link "Pick up the book" >><<set $Inventory.push($book)<</link>>
    

    If you want to have inventory items be links you can do that as well but it needs some modification. Hopefully this is somewhat helpful!
Sign In or Register to comment.