inventory: {'An apple': {name:"Granny Smith", number:1, colour:"lime"}, "A banana": {name:"Yellow Banana", number:1, colour:"yellow"}}
config.footer.left: "[[Credits]]"
--
{embed image:"https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Still_life_-_Caravaggio.png/640px-Still_life_-_Caravaggio.png"}
# A Fruit Bowl Inventory
This example uses a **single Javascript Object** as an inventory within [[Twine (Chapbook)->https://klembot.github.io/chapbook/guide/]]. It follows on from the [[much simpler Array version here->https://www-users.york.ac.uk/~tas509/Inventory%20Array%20Example.html]].
You will need a copy of the [[Twine app->https://twinery.org/]] to open it.
__What do I mean by inventory?__
By inventory I mean data that is saved, and can be changed. I am going to use a fruit bowl analogy but it could have been a backpack, or a complex score and ranking {life:27, speed:55 etc}, or whatever data you want to persist, or be saved.
In order to understand this you need to understand how to use the Javascript data structures of [[Javascript Object->https://www.w3schools.com/js/js_objects.asp]] and it differs from the Javascript [[Array->https://www.w3schools.com/js/js_arrays.asp]] (or list). _Note - Don't get confused with an Array of Objects which are also a valid way of storing data_
## A Mini Guide To Javascript Objects
* An Object is surrounded in {} whilst an Array is surrounded in []
* Each item in an Object has a unique key or name
* Each item's key can be anything, but is usually a string (text).
* Interestingly, the name doesn't have to have quotes around it
* Each item's value comes after a colon.
* Multiple utems are comma-separated
* The items are not in order, so even if you add an apple first, then an orange, you can't ask the object what its last item is
## Using An Object As An Inventory
On this page, at the top, I have already added some fruit to your inventory. You need to initialise (or create) an Object before you can start working with it.
Often on your first page you would create an empty object, that you will alter later on in subsequent pages.
So, for example the first item has a key of __"apple"__ and extra variables in it such as number and colour. You will need to look at the source code to see this in action in the Twine app. _I haven't figured out how to escape certain characters in Twine so that if I show source code in the Twine text, it doesn't break it_
On the following pages I have to use Javascript to display the object because it is a bit complex - there are things contained within things - so to speak, but that's OK, that's exactly what we want.
# Your Mission ...
Now go and add some strawberries, and cherries. When you visit these pages, hidden Javascript does the magic.
Once you have collected all the fruit THEN go on further to look at the Advanced Inventory. It doesn't do anything except display what's in the inventory with a little more sophistication.
[[Your Inventory]] - this pages lists what fruit you have, and offers pages that add to your fruits.
# Let's See Your Inventory
Here, a Javascript block is being used to get the inventory variable, and then iterate through it, writing it to the page.
[Javascript]
var inventory = engine.state.get('inventory');
for (i in inventory){
write([i] + " - " + inventory[i].name + "<br>");
}
[continued]
Let's add some [[Strawberries]] or some [[Cherries]]
## Note
Because Objects each need a unique key, if you add an "apple" then add another "apple", you will never get two apples, the 'first' one will be overridden.
# Yay! A whole punnet of lovely sweet strawberries!
{embed image:"https://upload.wikimedia.org/wikipedia/commons/thumb/6/69/Strawberries_at_Ljubljana_Central_Market.JPG/800px-Strawberries_at_Ljubljana_Central_Market.JPG"}
You have added some strawberries to your inventory... Because it is a punnet of strawberries, the strawberry item has a **number** of 9.
Imagine this was a game where you needed to collect amounts of things, and then spend them later in the game.
[Javascript]
var inventory = engine.state.get('inventory');
inventory['strawberries'] = {name:"A Punnet of Strawberries!", number:9, colour:"red"}
for (i in inventory){
write([i] + " - " + inventory[i].name + "<br>");
}
[continued]
... now go back to [[Your Inventory]] to see the changed reflected.
If you have added both the strawberries and the cherries, go on to the [[Advanced Inventory]].# A Lovely Bag of Cherries
{embed image:"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Italienische_S%C3%BC%C3%9Fkirschen.JPG/576px-Italienische_S%C3%BC%C3%9Fkirschen.JPG"}
[Javascript]
var inventory = engine.state.get('inventory');
inventory['cherries'] = {name:"Lovely bag of cherries!", number:14, colour:"purple"}
for (i in inventory){
write([i] + " - " + inventory[i].name + "<br>");
}
[continued]
You have added a lovely bag of cherries to the inventory. Note that there are more cherries than the apple.
If you have added both the strawberries and the cherries, go on to the [[Advanced Inventory]].# Advanced Inventory
See here how I have used the number of each fruit in my inventory to generate a HTML P tag, with colour styling.
[Javascript]
var inventory = engine.state.get('inventory');
for (i in inventory){
var num = inventory[i].number ;
for (n=0; n<num; n++){
write('<p style="background:')
write( inventory[i].colour );
write(';">')
write( inventory[i].name );
write("</p>")
}
}
[continued]
[[What's Next?]]# What's Next?
So because we are using an Object, rather than a simple Array to store our data, we can do more sophisticated things more easily.
For example, what if some bounder came and ate all but one of our cherries. The rogue might even spit the pits into our fruit bowl.
[Javascript]
var inventory = engine.state.get('inventory');
var numberOfCherries = inventory['cherries'].number;
var numToEat = numberOfCherries -1;
inventory['cherries'].number = 1;
inventory['pits'] = {name:"Cherry pit", number:numToEat, colour:"brown"}
[continued]
Now take a look at the
[[Eaten Cherries]]# The Rotter!
So, we should have five different fruits in our object, and each has a number, a colour and a name.
[Javascript]
var inventory = engine.state.get('inventory');
for (i in inventory){
var num = inventory[i].number ;
for (n=0; n<num; n++){
write('<p style="background:')
write( inventory[i].colour );
write(';">')
write( inventory[i].name );
write("</p>")
}
}
[continued]
OK. So [[What Have We Learned?]]# What Have We Learned?
Hopefully, we have learned a little about how we might store __state__ in Twine (Chapbook). Dropping down to use Javascript is a bit more geeky, in that you need to know Javascript, but you get the ability to do much more powerful things with variables more easily.
We could have used a standard Twine variable for each and every thing we wanted to store, but this can get unweildy, if each of those variables needs it's own little collection of variables storing. For example, we might have a list of people, each of which has a name, height, hair colour and a collection of items to trade.
# Tom Smith
This is me trying to figure out the **best** way to do clever things with Twine.
http://everythingability.com
### Strawberries
By domdomegg - Own work, CC BY 4.0, https://commons.wikimedia.org/w/index.php?curid=46010844
https://upload.wikimedia.org/wikipedia/commons/thumb/6/69/Strawberries_at_Ljubljana_Central_Market.JPG/800px-Strawberries_at_Ljubljana_Central_Market.JPG
### Cherries
Italienische Süßkirschen (Prunus avium), fotografiert an einem Marktstand Heidelberg (Baden-Württemberg, Deutschland)
https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Italienische_S%C3%BC%C3%9Fkirschen.JPG/576px-Italienische_S%C3%BC%C3%9Fkirschen.JPG
### Fruit Bowl
By Caravaggio - http://www.ayapov.com/wp-content/gallery/caravaggio/thumbs/thumbs_1601_caravaggio_still_life_with_fruit.png, Public Domain, https://commons.wikimedia.org/w/index.php?curid=5148827