# MAX_STATIC_DATA maximum reached

I am using tables and properties but this is cumbersome. You are right I may benefit from doing a simple game before… I am thinking about it.
In the meantime if someone knows a language that is more appropriated for complex world simulations I’d like to know… of course I could do it in C something but I guess this won’t be as fun as inform, and may end in a steeper learning curve in fact… ^^;

So for those who wanted to know here is the function (I splitted it in 3 to resolve the limitation).
It works and I am pretty pleased with the output.
But as you can see it is not easy to understand what is going on (btw I didn’t included the tables which are refered to).

I have also used very-long-names-with-hyphens to be sure the engine doesn’t mistake them for other commands.
I also chose absolutely non consistent variable namings… I didn’t know it would become so big… See this as a very first draft.

And there is a lot of intermediate say statements for debugging purpose.

It is very very ugly with too many cascading ifs, but it was the first time I wrote such a complicated thing in I7. Since it works I expect to simplify it, or maybe to change it competely to a rulebook or activity when I know how to use them. I am sure there is a lot simpler way to do the same thing. Of course the tables won’t change much I think.

[spoiler][code]
to decide which number is the punch-damage-to (grocon - a person) hurting (victim - bodypart):
let X be a number;
let critical be a number;
let beforedegat be the part-state of the victim; [body part]
let degat be the contondant-poing2 corresponding to a part-state of beforedegat in the table of body part damage;
now critical is the contondant-poing2-proba corresponding to a part-state of beforedegat in the table of body part damage switch probability;
say “maxproba : [critical] | beforedegat [beforedegat] | degat [degat]”;
let minusnrj be the energy corresponding to a part-state of degat in the table of body part energy damage;
decrease the energy of the grocon by minusnrj;
if critical > 0:
now X is a random number between 1 and critical;
if X is 1:
now the part-state of the victim is degat;
let beforedegat-bone be the bone-state of the victim; [bone]
let degat-bone be the contondant-poing2-bonedamage corresponding to a bone-state of beforedegat-bone in the table of bone part damage;
now critical is the contondant-poing2-proba corresponding to a bone-state of beforedegat-bone in the Table of bone damage switch probability;
let toto be the part-name of the victim;
say “[line break]-- bone damage check --”;
if critical > 0:
now X is a random number between 1 and critical;
if X is 1:
now the victim is degat-bone;
if the victim is broken:
let minusnrj be the energy corresponding to a part-name of toto in the Table of broken bone damage;
decrease the energy of the grocon by minusnrj;
say “[line break]Bone Damaged!!! [line break]energy [energy of the grocon]”;
now the health of the grocon is the health corresponding to a part-name of toto in the Table of broken bone damage; [ add the time penalty here]
say “[line break][the grocon] is [health of the grocon]”;
otherwise:
say “[line break]Bone not damaged.”;
say “[line break]-- bone criticality check --”;
if the bone-state of the victim is not broken or the bone-state of the victim is not broken to pieces: [bone critical]
now critical is the contondant-poing2-proba corresponding to a part-name of toto in the Table of critical bone damage probability;
if critical > 0:
now X is a random number between 1 and critical;
if X is critical:
now the bone-state of the victim is broken;
let minusnrj be the energy corresponding to a part-name of toto in the Table of broken bone damage;
decrease the energy of the grocon by minusnrj;
say “[line break]Bone Critic!!! [line break] energy [energy of the grocon]”;
now the health of the grocon is the health corresponding to a part-name of toto in the Table of broken bone damage; [ add the time penalty here]
say “[line break][the grocon] is [health of the grocon]”;
otherwise:
say “[line break]Criticality failed on a total of [critical] chances.”;
check-the-organ-criticality-of the grocon with the victim;
if a face (called the-face) is part of the victim:
check-the-organ-criticality-of the grocon with the-face;
Decide on energy of the grocon.

``````to check-the-organ-criticality-of	(grocon - a person) with (victim - a bodypart):
say "[line break]-- organ criticality check --";
let toto be the part-name of the victim;
if there is a part-name of toto in the table of potential organ damage:     [organ critical]
if there is a contondant-poing2-hitorganlist corresponding to a part-name of toto in the table of potential organ damage:
let L be a list of organs;
now L is the contondant-poing2-hitorganlist corresponding to a part-name of toto in the table of potential organ damage;
say "[line break]list of organs L : [L].";
let X be a random number between 1 and number of entries in L;
let organ-to-burst be the entry X of L;
say "[line break]Organ touched : [organ-to-burst].";
repeat with n running from 1 to number of entries in the list-of-organs of the grocon:
let organ-check be entry n of list-of-organs of grocon;
if organ-check is organ-to-burst:
now X is n;
if the entry X of the list-of-organ-states of grocon is whole:
let critical be the contondant-poing2-proba corresponding to an organ of organ-to-burst in the table of critical organ damage probability;
if critical > 0:
let n be a random number between 1 and critical;
if n is critical:
now the entry X of the list-of-organ-states of the grocon is crushed;
let minusnrj be the energy corresponding to an organ of organ-to-burst in the Table of critical organ damage;
decrease the energy of the grocon by minusnrj;
say "[line break]ORGAN Critic!!! [line break] energy [energy of the grocon]";
if there is a health corresponding to an organ of organ-to-burst in the Table of critical organ damage:
now the health of the grocon is the health corresponding to an organ of organ-to-burst in the Table of critical organ damage; [ add the time penalty here]
say "[line break][the grocon] is [health of the grocon]";
otherwise:
say "[line break]Criticality failed on a total of [critical] chances.";

To process-the-health-of (the victim - a person):
say "[line break] Process health status - ";
if the energy of the victim > 120:
if the victim is-not-disabled:
now the health of the victim is genki;
say "/ health -> genki/";
otherwise:
if the energy of the victim > 100:
if the victim is-not-disabled:
now the health of the victim is tired;
say "/ health -> tired/";
otherwise:
if the energy of the victim > 80:
if the victim is-not-disabled:
now the health of the victim is very tired;
say "/ health -> very tired/";
otherwise:
if the energy of the victim > 40:
if the victim is-not-disabled:
now the health of the victim is unable to stand up;
say "/ health -> unbale to stand/";
otherwise:
if the energy of the victim > 0:
if the health of the victim is not unconscious:
now the health of the victim is unable to move;
say "/ health -> unable to move/";
otherwise:
now the health of the victim is unconscious;
say "/ health -> unconscious/";
say "[line break]*** Health of [victim] : energy : [energy of the victim] | health : [health of the victim]".

To decide if (the patient - a person) is-not-disabled:
if the health of the patient is unconscious or the health of the patient is unable to move or the health of the patient is unable to stand up:
decide no;
otherwise:
decide yes.
``````

[/code][/spoiler]

You’re using variables in some places where Inform doesn’t really need variables. Also, I understand the aversion to using spaces in identifiers, but for the most part, using them is one of the things that makes Inform exceptionally easy to read. It takes some experience to figure out when you can get away with it, but it works often enough that the occasional compiler-failure won’t ruin your day.

I’m looking for examples of variables you don’t need…

It looks like X is always a random number. You don’t need it at all, because you can say:

``If a random chance of 1 in critical succeeds:``
``choose a random row in Table of Silly Events;``

You also rarely need count variables. You can loop over just about anything:

``repeat running through Table of Things To Mention:``
``repeat with the limb running through Table of Body Parts:``

I’m not sure why you’re using lists. If there is a finite limit to whatever you’re listing, it’s probably more efficient (and easier) to use a table instead. Tables can be written as well as read:

```Blank out the whole of Table of Parts To Process; Repeat with limb running through injured body parts: choose a blank row in Table of Parts To Process; now body part entry is the limb; now damage entry is the damage of limb; sort Table of Parts To Process in damage order;```

You certainly don’t need list variables in places where you can do this:

``let the organ to burst be a random organ in the contondant-poing2-hitorganlist corresponding to a part-name of toto in the table of potential organ damage``

Now I admit that’s a bit wordy, and that’s exactly the sort of situation in Inform where you might want to write a short phrase:

```To decide what list of organs is the set of organs in (limb - an organ): Decide on the the contondant-poing2-hitorganlist corresponding to a part-name of the part-name of the limb;```

Now you have a phrase that not only does one specific useful thing, but has a name describing what that specific useful thing is. And as a bonus, you don’t need the “toto” variable any more.

Here’s a way to avoid lists entirely:

[code]A part-name is a kind of value. Some part-names are head, arm, torso, and leg.

An tissue is a kind of value. Some tissues are brain, blood, bone, and heart.

Flesh-housing relates various tissues to various part-names. The verb to house (he houses, they house, it is housed, he is housing) implies the flesh-housing relation.

The torso houses the heart. The torso houses blood. The torso houses bone.
The arm houses blood. The arm houses bone.
The leg houses blood. The leg houses bone.

To decide which tissue is the site of impact in (limb - a body-part):
Decide on a random tissue that is housed by the part-name of the limb;[/code]

Yes I have bumped in a few errors like that so I decided to free myself from this problem for the moment with the intermediate variables, I use more than I should but it is to avoid writing long phrases that may confuse inform7 (Or should I say I got an error when writing it in a single phrase and didn’t manage to write it correctly).

Thank you for your help ^^

I need to count variables in a few cases because it didn’t work (or can’t work) with the running through table thing because of the design of the tables…
I haven’t found a better solution yet. I guess there is though.

I use lists for 2 things.
First to list the organs that are attached or inside a body part (in the table of body parts I have a column of organs lists). I didn’t really attached the objects to the persons because it became too big and broke some objects number limitations (while only 4 persons were in the game at the moment). So I use tables, properties and lists to simulate almost everything.
I use another 2 lists to track the damage of all the organs. So a list with all the organs and a list with their status. I can’t do this with a table since I need separate data for each person. At least it is the way I managed to implement it for the moment. Not the best that is for sure.

Your example with a table works well but I would have to create a table for each person right? I need to have dynamically assigned such a table for each person. If there is a way, I guess this is what I would like to do.

You certainly don’t need list variables in places where you can do this:
let the organ to burst be a random organ in the contondant-poing2-hitorganlist corresponding to a part-name of toto in the table of potential organ damage

I tried to do it but I had errors so as a temporary solution I created intermediate variables.

Decide on the the contondant-poing2-hitorganlist corresponding to a part-name of the part-name of the limb;

“the part-name of the part-name of the limb” is a good example of phrase that sometimes work but most of the time don’t for some reason… ^^;

flesh housing relation.

Yes, I knew relations could help me but I had difficulties to manage them and didn’t know their limitations so I prefered doing withut, but I guess I should try to use them…
Though, do your relation example work for multiple persons,.
Since the tissue is a kind of value it may be lighter than objects, so I wouldn’t need to attach them to every person. This sounds like a working solution…
I must find a way to differenciate males and females either… but I think it shouldn’t be too difficult (in the present implementation all the persons have all male and female organs (lol) and I do a male/female check when an inappropriate organ is randomly selected)

I will say that if you get this all ironed out, it may be worth releasing as an extension alongside Magic, Combat and Basic Characters.

If Inform is misinterpreting these constructions, you can use parentheses to group entities to help it get things right, e.g.:

``the part-name of (the part-name of the limb)``

You could dynamically insert your data into blank tables preassigned to each character, but you’d still need to manually include a table for each character, e.g.

```Table of Fred body part damage with 50 blank rows```

But this is not very convenient.

–Erik

As I mentioned, you can use relations, but you can also use a table for this.

Sure you can. Inform won’t conveniently look up the row in the table for you if you need to constrain your search by two columns at once, but you can still loop through it manually. Didn’t we talk about this in an earlier thread? Here’s a working example that uses a Table of Tissue Containment as a reference to create a Table of Tissue Damage that records damage for every person. I’ve also written a couple of useful phrases to illustrate one possible style of phrase-writing you could employ:

[spoiler][code]Body part is a kind of value. Some body parts are head and pelvis.
Tissue type is a kind of value. Some tissue types are brain, blood, bone, muscle and testicles.
Gender is a kind of value. Some genders are any, masculine, and feminine.

Arena is a room. Hercules is a man in Arena. Xena is a woman in Arena.

Table of Tissue Containment
sex body area tissue maximum damage
masculine pelvis testicles 2
any pelvis blood 5
any pelvis bone 15
feminine pelvis muscle 15
masculine pelvis muscle 10

Table of Tissue Damage
combatant (object) body area (value) tissue (value) damage (number)
with 24 blank rows [you must calculate number of people times number of rows in Table of Tissue Containment. You don’t need quite that many because of gender differences, but this is probably not where you’re going to run out of memory.]

When play begins:
repeat with the current combatant running through people:
repeat through Table of Tissue Containment:
If the sex entry fits the current combatant, create a record of damage for the tissue entry of body area entry in the current combatant;

To decide whether (identity - a gender) fits (combatant - a person):
if identity is any, yes;
if identity is masculine and combatant is male, yes;
if identity is feminine and combatant is female, yes;
no.

To create a record of damage for (the organ - a tissue type) of (the limb - a body part) in (combatant - a person):
Choose a blank row in Table of Tissue Damage;
Now combatant entry is combatant;
Now body area entry is the limb;
Now tissue entry is the organ;
Now damage entry is 0.

To decide what number is the maximum damage to (the organ - a tissue type) of (the limb - a body part) in (combatant - a person):
Repeat through Table of Tissue Containment:
if the sex entry fits the combatant and the body area entry is the limb and the tissue entry is the organ, decide on the maximum damage entry;

To decide what number is a randomly chosen record of damage for (current combatant - a person):
sort the Table of Tissue Damage in combatant order;
Let the first possible record be 0;
Let the current record be 0;
Repeat through Table of Tissue Damage:
increment the current record;
if the combatant entry is the current combatant and the first possible record is 0, now the first possible record is the current record;
if the combatant entry is not the current combatant and the first possible record is not 0:
decide on a random number between the first possible record and the current record - 1.

When play begins:
Choose row a randomly chosen record of damage for Hercules in Table of Tissue Damage;
say “[combatant entry] has sustained [damage entry] damage to the [tissue entry] in the [body area entry], out of a possible [maximum damage to tissue entry of body area entry in combatant entry].”;[/code][/spoiler]

Inform’s table syntax is tricky, and one of the tricky things about it is the “choose row” behavior. The chosen row is locally-scoped, so it doesn’t persist between phrase-calls. But as above, you can use this to your advantage, by keeping track of the current row in one phrase while calling another phrase to work on a different table.

That’s what the “pragmatic programmers” (Hunt & Thomas) call “programming by coincidence.” I admit that with the state of I7’s documentation, sometimes it’s the only way. But it’s almost always worthwhile to stop and investigate whenever you feel like you don’t understand what’s going on. Write a short experiment to test the behavior. I actually did that while I was writing the example, to make sure the “choose row” statements worked as I expected, and that all the various “random” phrases did what I thought they would. Doing this consistently will rapidly expand your understanding of how I7 works, and save you a lot of time and headaches in the near future.

Interesting. What is the purpose of this extremely low limit? Regardless of whether there might be other ways of achieving what is intended — how could any compiler designer know for certain, in advance that there are no situations in which more than 15 temporary variables would be the best solution? Isn’t the decision of how many temporary variables are necessary, much better left to the person who will be actually familiar with whatever specific problem that the code will attempt to solve?

Paul.

The limit comes not from a compiler design decision but from the Z-Machine—it only gives you so many locals per function, and anything more than that means that the compiler can’t create a valid game file. (It could simulate extra locals, but that would be a lot of work for only marginal benefit.)

Which means that this will be the only way to solve your problem unless you discover something or someone else has discovered something that the documentation doesn’t mention. And the docs aren’t slated for any revision any time soon. Having fun yet? I7 is in a state of partial abandonment and it’s been that way since its inception.

A personal reminiscence: When I started learning Inform 6 in 1999, I was inspired by the documentation (currently known as the DM4), in no small part because it was so literate. In returning to it a couple of years ago, after working for a while with TADS 3 and Inform 7, I was surprised to find the DM4 as sketchy in some respects as the Inform 7 Documentation.

The difference, I think, comes down to the language itself. Learning Inform 6 from the DM4 is materially easier than learning Inform 7 from the Documentation and Recipe Book because the new language is an order of magnitude more convoluted, and not because of any inherent difference in the quality of the writing or presentation.

Of course, if you search the newsgroup archives, you’ll find more than a few messages, circa 2004, in which I whined about the state of the TADS 3 documentation too. There’s no index, and unlike the I7 Documentation, the T3 manuals are not readily searchable, because they’re distributed across many different files. Nonetheless, the information on T3 (written up first and foremost by Eric Eve) is quite solid and thorough.

I fully agree that the I7 Documentation is a mess. I communicated my observations to the development team in some detail several years ago. Nothing at all was done in response. My Handbook, which was an attempt to rectify the situation, is now somewhat out of date, and I have no plans to expand and update it.

Given the amount of effort that has been and continues to be put into the Inform 7 authoring system itself, and given the continued enthusiasm for Inform 7 on the part of a good-sized community, the absence of proper documentation is rather disheartening. Not to give myself airs or anything, but I am a professional writer with more than 30 years of experience in explaining fairly technical matters (in electronic music) to a non-technically-savvy readership, as well as a modest amount of experience writing IF. I would not hazard a guess as to why nobody in the Inform 7 development team has ever approached me about developing proper documentation – but I can tell you that nobody has done so.

Thanks for that, but I wonder… if it’s a Z-machine issue, does that mean it could easily be avoided by compiling with glulx? It was my understanding that by compiling to glulx instead of the z-machine, there are no more serious limits. But this here is a serious limit.

(As for the documentation discussion going on, I have thought about this at length and have a half-written i7 spec that I intend to turn into a manual myself one day, at least for my own purposes and possibly for release. It’s going to be a while though as I am not prioritising the project and am rather just filling in things about the language as I learn them, because I can’t find them written down plainly, anywhere else. But in my opinion the poor documentation situation is not due to any state of half-abandonment or not even technically because i7 is that difficult to learn. The problem is that i7 is very difficult to document, which is something slightly different. The difficulty involved adheres directly to the problem of how to organise documentation for a natural language. I know because I’ve programmed in i7 and tried to write documentation for i7, and the latter is actually much more difficult. So I believe that we will have a good variety of documentation with a variety of approaches eventually but it’s taking a while because it’s just a much harder task and everyone is busy developing games. Writing both plain and comprehensive docs is such a challenge that you’ve gotta basically give up writing games for a while in order to do it in anything resembling a timely fashion. This also explains why the DM4 may have also suffered in quality (though I don’t know this for sure); because it is now just one piece of a much more massive documentation project that dwarfs it in complexity – nobody’s energies are intensely concentrated on just that fairly narrow problem set anymore.)

Paul.

What would be “proper” documentation? I think the documentation is sometimes hard to use but that’s because I think there’s too many forward references and an uneven balance of detail. Do you mean just cleaning up the existing documentation or are you referring to entirely new material?

As for me, honestly, the documentation is not the issue. I have a “trust issue” with Inform. The last couple of threads or so have shown me even more how clunky Inform 7 is beneath the covers. Sometimes I have the “lipstick on a pig” feeling. The underlying architecture just seems so dated. Granted, it’s based on the z-machine and maybe that just was clunky. I don’t know. I know it did it’s job for the time it was written in. I see how Glulx has updated things a bit but I also see Glulx being very confusing when you really try to utilize it, such as with some of the graphics extensions. (Rocks and Glk and all that stuff. It’s pretty discouraging to me anyway.) I don’t know if it’s still true but in my early forays I found you could only have two styles, which is a step backward from the z-machine. That made utterly no sense to me at all.

I don’t know. I just feel like Inform keeps forcing you to worry about what’s under the covers. And in those cases, I’d really just deal with what’s under the covers consistently rather than sometimes dealing with the lipstick and sometimes dealing with pig. I may be looking at it entirely wrong and I’ll admit I’m a skeptical audience of the whole text adventure scene.

It should be – zarf said that in glulx the limit is raised to 119, which seems like it should be enough for most purposes.

Much better. Thanks Matt, I missed that somehow — which is weird, because I did read through the entire thread.

Paul.

I get a similar feeling at times — not as much now as I used to, but I do — however, I don’t interpret it as ‘lipstick on a pig’; I interpret it as ‘lipstick on a highly advanced robot recently developed, amazingly, for free by hobbyists, who chose such ambitious goals for it that they have little time left over to pick out clothes for it, besides they don’t make anything in its size, so they have to sort of build a clothing factory, but that’s a lot of work and the robot itself still needs improving, so for now all they have is this lipstick – enjoy’.

P.

It was late at night when I wrote that. Perhaps “proper” was a poor word choice. It’s been a while since I spent any time with the I7 Documentation, but IIRC, its most telling weakness is that it assumes readers will only want or need to do easy things. On almost no page will you find a topic discussed in a complete, well-structured manner, complete with caveats. And as you said, there are not enough references to the pages where the topics are discussed in more detail. Sometimes, there are no such pages.

If you compare this, for instance, to the long, detailed page in the TADS 3 Technical manual called “How to Create Verbs,” the difference should be quite clear.

This is the conversation node where I repeat the link to the I7 topic index that I put together a couple of years ago:

eblong.com/zarf/i7index/

It isn’t perfect, and even if it were perfect it wouldn’t be a complete solution to the documentation problem. But it frequently solves the problem of “I know X is discussed somewhere, I just need a link.”

I believe I have that link already somewhere because I remember using it: it came in handy. Thanks for doing it!

P.

I guess it may take time but in fact it was in the plans, because I would want to use the same system for other games too ^^
Though, I have to learn inform7 a little more first (>_<)