RAIF FAQ > Programming IF > 4.6: What are VILE 0 ERRORS FROM HELL, and how should I avoid them in Inform?

4.6: What are VILE 0 ERRORS FROM HELL, and how should I avoid them in Inform?

It is illegal on the ZMachine that Inform compiles to to do any of the following when x == 0 (nothing):

child(x), parent(x), sibling(x), etc
if (x has attribute)
if (x.property == ...)
give x attribute
x.property = ...
move x to y
move y to x
remove x
... or pretty much anything else which assumes x is a legitimate object.

Some interpreters will ignore this, and either end up not messing up, or crash. In the former case, this means that you will falsely believe there is nothing wrong with your game. In the latter case, it, well, crashes.

MaxZip, and some other Zip interpreters, will check and warn at these illegal statements.

There is a bug in the Inform library (version 6/7) that will cause this in the HasLightSource function. You should patch this immediately if for some reason your are still using library 6/7.

In the library file parserm, find the function HasLightSource. Near the top, there are the lines:

   if (i has enterable || IsSeeThrough(i)==1)
   {   objectloop (i in i)
           if (HasLightSource(i)==1) rtrue;
   }

This should be

   if (i has enterable || IsSeeThrough(i)==1)
   {   objectloop (j in i)
           if (HasLightSource(j)==1) rtrue;
   }

In other words, change two i's to j's.

Library 6/8 and later fixes this and a few other uncommon V0EsFH.

Much more information on the subject of VILE 0 ERRORS FROM HELL can be found at <http://www.eblong.com/zarf/vileerror.html>, thanks to Andrew Plotkin, who made everyone aware of this problem and helped with this article.

As of Inform 6.20, VILE 0 ERRORS FROM HELL and other common Inform problems are caught at run-time by compiled-in checking routines. There is much rejoicing! Unfortunately, if this "strict" mode is turned off, Inform 6.20 (though not the newer 6.21 which should be used instead of 6.20) creates buggy code; and Library 6/8 in strict mode is too large to fit in a module, meaning that you can't create strict library modules. Inform 6.20 should *not* be used due to its bugs in non-strict mode: either stick with a lower version or upgrade to 6.21.

Inform 6.20 and up also classifies objectloop errors as V0EsFH and catches them. These are another common cause of problems in Inform. As most Inform programmers know, objectloop (x) { ... } will run ... once for each object in the game, setting 'x' to that object. Here's the problem:

objectloop (foo in someobject)
{
   move foo to somewhereelse;
}

You'd think this moves every object in someobject to somewhereelse. But it doesn't. This is becase objectloop(a in b) {...} is optimized. Instead of being equivalent to

objectloop(a)
{
   if (a in b)
   {
      ...
   }
}

it is the same as

for (a = child(b); a ~= 0; a = sibling(a))
{
   ...
}

In other words, it simply strolls along the object tree. If a is moved out of b, it will make the next a be equal to the sibling of the current a, which will not be what you want.

The solution is, for the simple case of "move all children of foo to bar":

while (children(foo) ~= 0) move child(foo) to bar;

For anything more complicated than that, use:

objectloop(a)
{
   if (a in b)
   {
      ...
   }
}
The same problem can occur in the little-used 'x from object' and 'x near object' versions, though not in any other ones (such as 'x ofclass c'). Inform 6.20 and up will catch these at run-time.
RAIF FAQ > Programming IF > 4.6: What are VILE 0 ERRORS FROM HELL, and how should I avoid them in Inform?