0 votes
by (120 points)

Okay so I had this idea for my game/story/whatever where you can go to a petshop and buy cats (at the moment only cats, but maybe something else later, so far one type of animal seems to be complicated enough). It makes sense in the context, trust me.

Anyway, at the petshop, you are able to purchase as many cats as you want. Originally, I was just going to make up a few different ones to choose from, but then I thought that it could be neat if instead of me making all them, the cats could each be randomized.

The traits that would be described/randomized would be gender, breed, eye colour, and a name that would be chosen by the player.

So, the question is, what would be the best way to go about doing this, if there is any?

I was thinking of doing something like this:

You look at the new cat.
<<set $totalcats = $totalcats + 1>><<set $cat1gender to random(1, 2)>><<set $cat1breed to random(1, 2)>><<set $cat1eyes to random(1, 2)>>
<<if $cat1gender is 1>>\It is male, <<else>>\It is female, <</if>><<if $cat1breed is 1>>\is a calico, <<else>>\is a tabby, <</if>><<if $cat1eyes is 1>>\and has blue eyes.<<else>>\and has green eyes.<</if>>

What would you like to name the cat? <<textbox "$cat1name" "Cat1">>

But then I realized that since I have no idea how many cats the player/reader would want, I'd have no idea what to set the limit to. Also, it would be rather tedious to make every alternate $cat2name, $cat3name, $cat4name, etc.

So, is there a way I could have the game/story auto create a variable like that, since they'd almost be indentical, save for the single number difference? If I could do that, I wouldn't really need a limit either, and then the player/reader could buy as a ridiculous amount of cats as he/she/they would like.

Also, I don't think I could reuse the same variable for each cat, because I want there to be a page where you can view all of your cats.


So, is there anyway to do this, or am I being too ambitious? It'd be kind of nice if I could do something like this though, as it could potentially be good for things other than silly cats.

Thank you in advance to anybody who reads/replies to this!

1 Answer

0 votes
by (23.6k points)

First thing you should do is to use objects and arrays:

<<set $cat to {
name: "",
gender: "",
breed: "",
eyes: "",

<<set $cats to []>>

Now whenever you want to add a new cat you can use the pushUnique() function to add more cats:

<<set $cat.male to either(true, false)>>
<<set $cat.race to either ("Tabby", "Calico")>>
<<set $cat.eyes to either ("blue", "green")>>

It's a <<if $cat.male>>male<<else>>female<</if>> $cat.race with $cat.eyes eyes.
Name your cat: <<textbox "$cat.name" "">> @@#name;@@

<<link "Continue">>
	<<if $cat.name == "">>
		<<replace "#name" t8n>>
			@@color:red;Name your cat before proceeding!@@
		<<set $cats.pushUnique($cat)>>
		<<goto "shop">>

The number of cats is now $cats.length - to refer to the first cats name you'd say <<print $cats[0].name>>.

by (36.5k points)

Since you don't need to keep the value of the current cat, instead of "$cat" you should use "_cat".

Also, the "_cat" variable would be an object, so instead of .pushUnique() you could just use the .push() method to add it to the "$cats" array.

by (144k points)

I also suggest changing

<<set _cat.male to either(true, false)>>

... to

<<set _cat.gender to either('male', 'female')>>

.. that way you don't have to keep using an <<if>> macro each time you want to display the cat's gender, you can just output the value instead.

It's a _cat.gender _cat.race with _cat.eyes eyes.


by (120 points)

Okay, all of this is actually very helpful, and I've figured out how to do pretty much everything I wanted to do with the cats, except for one thing.

I would like to have a passage that allows you to view a complete list of cats that you've boughten, which each cat displaying a simple sentence along the lines of

In total, you have <<print $totalcats>> cats.   (I have $totalcats increment by 1 every time a cat is bought)
Currently, your cats are as follows:

<<print $cats[0].name>> is a <<print $cats[0].gender>> <<print $cats[0].breed>> with <<print $cats[0].eyes>>.

Meaning that all of the cats would be listed like

In total, you have 5 cats.
Currently, your cats are as follows:

Mittens is a male Tabby with blue eyes.
Callie is a female Calico with green eyes.
Fluffy is a male Calico with green eyes.
Kat is a female Tuxedo with yellow eyes.
Kiki is a female Siamese with blue eyes.

The question is, though, is there a way to have Twine detect how many cats you have boughten and automatically copy and paste the

<<print $cats[0].name>> is a <<print $cats[0].gender>> <<print $cats[0].breed>> with <<print $cats[0].eyes>>.

line without me manually copying and pasting it with the [0] number changed? So that Twine will be able to do things like see if you have three cats and paste the line three times, but only twice if there's only two cats, etc.? Because while I can just manually do

<<print $cats[0].name>> is a <<print $cats[0].gender>> <<print $cats[0].breed>> with <<print $cats[0].eyes>>.
<<print $cats[1].name>> is a <<print $cats[1].gender>> <<print $cats[1].breed>> with <<print $cats[1].eyes>>.
<<print $cats[2].name>> is a <<print $cats[2].gender>> <<print $cats[2].breed>> with <<print $cats[2].eyes>>.

It means that there will be a limit to how many cats are displayed on the list, despite an effectively infinite amount of cats that the player/reader can buy. (Plus, it always displays a bunch of Error: <<print>>: bad evaluation: Cannot read property '0' of undefined for every potential cat listed that you don't have.)

So what would be the best way to get this cat list working? While it's not really the most important thing, I think it'd be nice to have it in if I could.


Also, is there a way to make it so that $cats[x] is identical to the most recent $cats? i.e. if the most recent cat is the 5th, then $cats[6] = $cats[5]? Like a set of identical twins?

by (23.6k points)

What you want is a <<for>> loop. Look over here.

<<for _i to 0; _i lt $cats.length; _i++>>
<<print $cats[_i].name>> is a <<print $cats[_i].gender>> <<print $cats[_i].breed>> with <<print $cats[_i].eyes>> eyes.

The most recent cat is $cats[$cats.length-1]