+1 vote
by (210 points)
reopened by

So I'm apologizing right off the bat as i am just now learning how to use this sort of stuff. I have never messed with scripts before but I have messed with Java Code before so I am still learning.

I am trying to implement a system in which the character can hire randomized companions. I want them to have different stats such as height, weight, agility, etc. I believe i can handle the randomizing and creation of the companions. What I don't know how to do is recruit them. I'm not sure how to save the object that they are somewhere.

For example, if I wanted just created a companion and wanted to add them somewhere to be accessed, how would I?

example companion:

<<set $companion to {
	height: "68",
	weight: "145",
	agility: "4",
}>>

for the sake of simplicity just so I can figure this out, this will be in my StoryInit passage. I am not sure what to add this to or how to do so. Do i simply add the object to another object? I don't even know if that is possible. Any ideas or explanations are welcome as I cannot find any explanations on this kind of topic anywhere. One additional detail. There cannot be a limit to how many companions the player has or it will severely hinder the game idea.

1 Answer

0 votes
by (44.7k points)
selected by
 
Best answer

Yes, you can have objects that have other objects inside of them.  So, for example, you could do something like this:

<<set $companion to {}>> \
<<set $companion.Anne to {
	height: "68",
	weight: "145",
	agility: "4"
}>> \
<<set $companion.Bob to {
	height: "70",
	weight: "265",
	agility: "2"
}>> \
\
<<set _names = Object.keys($companion)>> \
<<for _i = 0; _i < _names.length; _i++>> \
	<<set _name = _names[_i]>> \
	_name weighs <<=$companion[_names[_i]].weight>> lbs. and is $companion[_name].height inches tall.
<</for>>

That will create two companions, and then the for loop will print out some of their stats.  (Note: "<<=$var>>" is the same as "<<print $var>>", but faster to type.)

However, I'd recommend only creating companions when you need them.  All of those story variables add up, so if you're making a big game it could begin to slow down if it has to copy too many variables every time you go to the next passage.   (See this recent thread for details.)  You should make sure you delete any companions you won't need anymore.

If you want to get rid of a companion, you can do:

<<run delete $companion.Bob>>

That will only delete Bob, and not any of the other companions.

Hope that helps! smiley

by (210 points)

Okay, well thank you for the answer. It definitely helps quite a bit. However, I don't fully understand the code. I remember seeing something like this before.

<<set _names = Object.keys($companion)>> \
<<for _i = 0; _i < _names.length; _i++>> \
	<<set _name = _names[_i]>> \
	_name weighs <<=$companion[_names[_i]].weight>> lbs. and is $companion[_name].height inches tall.
<</for>>

I could not find any explanation for it though. I do not understand what _i is or really any of the procedure within it. So if you could explain or link me to a page about this that would be great. Furthermore lets say that I already have Bob as my companion and I come across Anne later in the story. How would I go about adding her to my companions then? Sorry about being a bit of a noob about this. I'm doing my best to figure it out but there seems to be a bit of a lack of explanations on this kind of stuff as far as I can tell.

by (159k points)

Some answers to your last post:

1. the Object.keys() function is a feature of Javascript, it returns an Array containing what 'keys' have been assign to the $companion object.
 eg. ["Anne", "Bob"]

2. the SugarCube manual includes Information about the <<for>> macro,.

3. the _names_i, and _name references are Temporary Variables

4. the .length part of _names.length is the Javascript property of Array that returns the number of elements within the Array.

5. the [_i] part of  _names[_i] is access a specific element of the _names Array based on it's position (index) within the Array.

6. the SugarCube manual includes Information about the <<= >> macro.

by (68.6k points)

I'm surprised the <<for...range>> form wasn't used in the example.

by (8.6k points)
A not on your (the OP's) companion code: If something is a number (height, weight, agility), store it as a number (70, 265, 2), not as a string ("70", "265", "2").
by (44.7k points)

@Reversal:

Furthermore lets say that I already have Bob as my companion and I come across Anne later in the story. How would I go about adding her to my companions then?

You would add Anne more or less the same as I did in my example, though Akjosch is right that you should probably store them as numbers instead of strings, like this:

<<set $companion.Anne to {
	height: 68,
	weight: 145,
	agility: 4
}>>

When you "<<set $objectName.newName = someValue>>" it both creates that newName on the $objectName and also sets it to someValue.  In the above case, it both adds Anne to the list of properties on $companion, and set's Anne's height, weight, and agility properties.

@TheMadExile:

I'm surprised the <<for...range>> form wasn't used in the example.

I wanted to show him how to get the keys from an object, since he'll probably need that at some point.

@Reversal:

That said, the <<for...range>> version means you don't need to grab the keys, since the "for...range loop" does that for you.  Here's what that would look like:

<<for _name, _person range $companion>> \
	_name weighs _person.weight lbs. and is _person.height inches tall.
<</for>>

So that loop will go through each property on $companion (Alice and Bob in this case), and sets "_name" to a string with the property name ("Alice" or "Bob") and sets "_person" to an object with that companion's properties.

As you can see, it turns the five lines of code I gave you earlier into just three.

You want to use temporary variables (the ones that start with an underscore) in loops like that, instead of story variables (the ones that start with a dollar sign), so that you aren't storing extra data you don't need to keep in your story's history.  Storing too much can slow down your story.

Hope that helps! smiley

by (210 points)

Alright, I almost have this all figured out now there is just one small issue I am having. I could get my game to work out now, but with what I currently have it forces me to create an extra passage in order for it to work. I want to avoid having extra passages and so I want to be able to add the companion in a manner like this:

[[Recruit|Recruitment][set $companion.Bob to {height: 70,weight: 265,agility: 2}]]

Now I am sure there is something blatantly wrong with this but I cannot see what it is. As I stated earlier I got the program to work by using the same command

<<set $companion.Bob to {height: 70,weight: 265,agility: 2}>>

However, in this manner I used it within a destination passage rather than in the the first passage itself. I should probably mention that I am trying to get this to work in only one passage. The earlier code takes place within the passage "Recruitment" just for proof of concept. Thank you all for your help and I hope this is the last bit of help that I need.

by (159k points)

Now I am sure there is something blatantly wrong with this but I cannot see what it is...

If you look at the Link w/ Setter example in the Links documentation you will see that the Setter part does not have a set keyword in it, that part only contains the assignment expression(s).

by (63.1k points)
You should select an answer rather than locking your post. If you didn't like any of the answers you got, write your own and select that when you have the time to spare.

This will help future users find this question and quickly determine that you came to a solution and find out what that solution was so they can benefit from it.
...