Fatal error while testing...

I have essentially completed my game. I am now play-testing some of the final parts of it(after which I will be going through the game with a fine-toothed comb and fine-tuning it, so to speak). I was just now play-testing when after I had typed a command, I got the error message-- Glulxe fatal error: Stack overflow in function call.

What I was trying to do was examine an individual object to see if the description of it had changed after I had tied it to something.

Here is how I coded it(in synopsis)–I have five different-colored swatches of cloth. As a solution to a problem, the player needs to tie them together to make a rope. I created a list of objects containing each swatch that had been tied. Then I created a ‘short rope’ for the case where not all of the swatches of cloth are not yet included, and a ‘long rope’, for the case where the rope is complete. When you look at the description for either rope, you would see the swatches of cloth listed(though, of course, none of them are actually present, you just have the short rope or the long rope–and I stop the player from being able to untie them–until later–with a message saying ‘There’s no going back.’, because that rope will be the only way to go anywhere from there). Then the long rope gets tied to a pole, then the player goes over the side along the rope, which, unfortunately, rips at the swatch that was tied to the pole. So now the player has a ‘frayed rope’, listing all of the swatches, including the first one, which got ripped. I wanted the player to be able to untie the swatches at this point(at which all of the swatches magically reappear, and the rope vanishes), but see the description of the first one changed to ‘…It is now ripped in half.’
In play-testing, I tied two of the swatches together–so now I have the ‘short rope’–and to see if the first swatch description had changed(which a player would not be allowed to see until he had the ‘frayed rope’ after it had been used), I ‘purloined’ that swatch(so I could paradoxically have the ‘short rope’ and the first swatch). Then I tried to examine it. The program cut me off with that error message.

Any ideas?
Thanks

Sometimes you get a Glulxe fatal error: stack overflow because your code has an infinite loop in it. For instance, if you write this:

[code]Lab is a room.

A rock is in the Lab.

For printing the name of the rock: say “a nice [rock]”.[/code]

You get

because when it tries to print the name of the rock, it hits the text substitution [rock], which call the routine for printing the name of the rock, which hits the text substitution [rock], which…

I haven’t been able to quickly come up with an example which gives a stack overflow in function call, but I bet there’s an infinite loop somewhere.

(Purloining can also sometimes lead to weird behavior, but my guess is that there’s an infinite loop.)

Stack overflow means you have a bit of code which tries to call itself. Or a text with substitutions which tries to include itself.

I suspected that there might be a problem with how I coded the ‘ropes’. When you tie the first two swatches together, the first one(‘the noun’), is the one whose description changes–I simply use

After tying a topgarment to a topgarment: say "They are tied together--now you have a short rope."; now the description of the noun is "[description of the noun] It's now ripped in half."; now the noun is nowhere; now the second noun is nowhere; now the short rope is carried by the player.

Perhaps the third line(description of the noun) is our recursive loop…??
After I wrote that I had a nagging feeling that perhaps the whole thing could have been coded better…?? Here, I simply created a list of all the swatches that were tied, in order, and created ropes that included those lists in their descriptions, but the obvious disadvantage is that the ingredients aren’t actually present when you have the ropes. I had thought of making the ropes containers, where you ‘put’ a swatch in by tying it, but I want to avoid the ‘Inside of the short rope you see a …’(after having already listed the parts)(though I’m sure I could change this message). I just wanted to avoid a lot of extra coding–it’s fun, but I really want to move forward with this game.
Thanks to you both

now the description of the noun is "[description of the noun]  It's now ripped in half.";

That looks like it!

If you just want to add “It’s now ripped in half.” to the end of a text you can do it like this, though I’m going to explain why that isn’t what you want most likely:

now the description of the noun is the substituted form of "[the description of the noun] It's now ripped in half."

For what “the substituted form” does, see §20.7 of Writing with Inform. The short version (maybe not very short) is something like this: When you do something like this:

now the left hand status line is "[time of day]";

usually we don’t actually want to set the left hand status line to whatever the time of day it happens to be at the moment. We want to keep tracking the time of day. So what this does is to set the left hand status line to a function that calls the time of day, whatever it is, and prints that.

But what if we do want to freeze something to the current time of day? That’s where “the substituted form” comes in–when we do the substituted form of a quoted expression, it evaluates that expression to a text and freezes it, instead of a function call. So if we do this:

Instead of attacking the clock: "You strike the clock and it stops."; now the description of the clock is the substituted form of "It's stopped at [time of day]."

then the last line evaluates the string to “It’s stopped at 9:05.” (or whatever) and sets the description of the clock to that, permanently.

OK, so in your case what happens is that when you do this:

now the description of the noun is "[description of the noun]  It's now ripped in half.";

it actually sets the description of the noun to do a function call to the description of the noun and then print " It’s now ripped in half."… except that that function call is calling the description of the noun, which starts with a call to the description of the noun… this is bad. When we put in “the substituted form,” though, what happens is that it evaluates “[description of the noun] It’s now ripped in half.” and then sets the new description of the noun to be that. So we get the old description of the noun with “It’s now ripped in half.” added on at the end.

However! There are some problems with this. Take this code:

[code]Lab is a room.

A shirt is in the Lab. The description of the shirt is “A motley patched shirt.”

Instead of attacking the shirt:
say “You rip the shirt in half.”;
now the description of the noun is the substituted form of “[the description of the noun] It’s now ripped in half.”[/code]

If you try “break shirt/x shirt” repeatedly, you will see that every time we do this, we add another copy of “It’s now ripped in half” on the end. This is undesirable. Also, if the description of the shirt had had a text substitution in it, using “the substituted form” would freeze that substitution in place. For example:

[code]Lab is a room.

The player wears a shirt. The description of the shirt is “A motley patched shirt[if worn]. It fits loosely[end if].”

Instead of attacking the shirt:
say “You rip the shirt in half.”;
now the description of the noun is the substituted form of “[the description of the noun] It’s now ripped in half.”

test me with “x shirt/remove shirt/x shirt/wear shirt/break shirt/x shirt/remove shirt/x shirt”.
[/code]

You can see that, when we rip the shirt while wearing it, we freeze “It fits loosely” to be part of the description, so it stays there even after we take the shirt off.

My advice for dealing with this particular problem would be to create a “ripped” property for topgarments. Then you can write a rule that adds “It’s now ripped in half.” after examining a ripped topgarment:

After examining a ripped topgarment: say "It's now ripped in half."

(Unfortunately this will print that on a separate line. Getting the line spacing correct here is tough, at least for me.)

As for your other question… ropes are notoriously difficult to code in Inform. I don’t think it’s a problem to have the swatches be absent when you have the ropes; that’s how people usually code multipart assemblies. Definitely don’t make them containers–that would just give you a lot of extra work.

Matt W has given some good advice for displaying a garment as ripped. As for the ropes, here’s a simple implementation that allows you to tie things together, and should work for your needs with a little tweaking:

[spoiler][code]“All Tied Up” by Chin Kee Yong

Chapter 1 - Tyable Things and the Improvised Rope

A thing can be tyable. A thing is usually not tyable.

The improvised rope is a tyable thing. The description is “The improvised rope comprises [a list of things that are part of the improvised rope].”

Rule for printing inventory details of the improvised rope (this is the show rope components in the inventory rule):
say " (comprising [a list of things that are part of the improvised rope])[run paragraph on]".

Rule for printing room description details of the improvised rope (this is the show rope components in the room description rule):
say " (comprising [a list of things that are part of the improvised rope])[run paragraph on]".

Chapter 2 - Tying It To

The block tying rule is not listed in the check tying it to rulebook.

Check tying it to (this is the can’t tie something that’s worn rule):
if the noun is worn by the player:
say “You seem to be wearing [the noun].”;
rule fails;
if the second noun is worn by the player:
say “You seem to be wearing [the second noun].”;
rule fails.

Check tying it to (this is the can’t tie something that isn’t carried rule):
if the noun is not carried by the player, carry out the implicitly taking activity with the noun;
if the noun is not carried by the player, rule fails;
if the second noun is not carried by the player, carry out the implicitly taking activity with the second noun;
if the second noun is not carried by the player, rule fails.

Check tying it to (this is the can’t tie non-tyable things rule):
if the noun is not a tyable thing or the second noun is not a tyable thing:
say “You can’t tie those.”;
rule fails.

Check tying it to (this is the can’t tie something to itself rule):
if the noun is the second noun:
say “That would only succeed in knotting [the noun].”;
rule fails.

Check tying it to (this is the can’t have more than one rope rule):
if the improvised rope is on-stage:
if the noun is not the improvised rope and the second noun is not the improvised rope:
say “You would rather add to the improvised rope you’ve already created.”;
rule fails.

Carry out tying it to (this is the standard tying it to rule):
if the improvised rope is off-stage:
now the noun is part of the improvised rope;
now the second noun is part of the improvised rope;
now the player carries the improvised rope;
otherwise:
let the other rope be a thing;
if the improvised rope is the noun, now the other rope is the second noun;
if the improvised rope is the second noun, now the other rope is the noun;
now the other rope is part of the improvised rope.

Report tying it to (this is the report tying it to rule):
if the improvised rope was off-stage:
say “You tie [the noun] to [the second noun], creating an improvised rope.”;
otherwise:
let the other rope be a thing;
if the improvised rope is the noun, now the other rope is the second noun;
if the improvised rope is the second noun, now the other rope is the noun;
say “You tie [the other rope] to the end of the improvised rope, extending its length.”;

Chapter 3 - Untying

Untying is an action applying to one thing.
Understand “untie [something]” as untying.

Check untying (this is the can’t untie a rope that isn’t carried rule):
if the improvised rope is not carried by the player, carry out the implicitly taking activity with the improvised rope;
if the improvised rope is not carried by the player, rule fails.

Check untying (this is the can’t untie things that aren’t tied rule):
if the noun is not the improvised rope and the noun is not part of the improvised rope:
say “[The noun] [aren’t] something you can untie.”;
rule fails.

Carry out untying (this is the standard untying rule):
if the noun is the improvised rope:
now all things that are part of the rope are carried by the player;
now the improvised rope is nowhere;
otherwise:
now the noun is carried by the player;
if the number of things that are part of the improvised rope is 1:
let the remaining rope be a random thing that is part of the improvised rope;
now the remaining rope is carried by the player;
now the improvised rope is nowhere.

Report untying (this is the report untying rule):
if the noun is the improvised rope:
say “You untie the improvised rope, dissolving it completely.”;
otherwise if the improvised rope is on-stage:
say “You untie [the noun] from the improvised rope.”;
otherwise:
say “You untie [the noun], dissolving the improvised rope completely.”

Chapter 4 - The Rope Shop

The Rope Shop is a room. A checkered handkerchief, a bath towel, and a flag of the People’s Republic of China are tyable things in the Rope Shop. A toy train is a thing in the Rope Shop. A Hawaiian shirt and a pair of jeans are wearable tyable things worn by the player.

Test me with “tie handkerchief to toy train / tie handkerchief to bath towel / i / tie rope to shirt / take off shirt / tie rope to shirt / i / untie shirt / i / untie bath towel / i”.[/code][/spoiler]

Thanks Matt–that’s a lot of help, and I understood it clearly.

Before I read your input, I went with making another list, called ‘firstswatch’–it’s a one-object list–and put the first shirt tied(the one we’re tying to the next swatch) into it. Then I created a statement called ‘tiedon’, saying “It is now ripped in half, due to a climbing mishap”. Then I went to the original descriptions of each of the swatches and added a substitution to each–"…[if the so-and-so colored swatch is listed in firstshirt][tiedon]".

That worked. But it was somewhat lugubrious to type.

You know, I didn’t think of creating a ‘ripped’ property, as you suggest. I could do that, then add a substitution to each swatch description, saying “…[if the so-and-so colored swatch is ripped][tiedon]”. That would save the program from creating another list.

Thanks

Thanks KCY,

I’ll have to refer back to your input, I do plan on using more ropes in other games.