Unstickying a sticky-random text

Hi there! I decided maybe it was time to finish that game I started in 2005 (oops), and now I’m facing the added difficulty of learning Inform 7. (The unpleasant alternative: relearning Inform 6.) I’ve been getting by on a combination of hammering on the documentation and pestering experienced IF writers over instant message, but I thought I’d try asking for help in a way that’s less frustrating to myself (in the former case) and my friends (in the latter).

So I’m trying to understand randomness, and sticky-randomness in particular. As best I understand it, “[at random]” is great for things that should change every time they’re invoked, and “[sticky random]” for things that shouldn’t ever change. But what if you want things to stay constant until told otherwise? For instance, suppose I want a newspaper headline that doesn’t change throughout the day, insofar as newspapers are static items in the real world, but which does change from day to day, insofar as new newspapers get delivered each morning:

[code]“Newspaper Headlines”

Your House is a room. The description is “This is a boring little house. Someone has brought in the newspaper already; its headline is ‘[headline]’.”

Instead of sleeping:
say “You go to sleep. In the morning, a new newspaper has arrived.”;
move player to the house.

The headline is a text that varies.

To redeliver:
now the headline is “[one of]Land War in Asia[or]Pope Admits Fallibility; Experts Consider It An Error[or]Newspapers Collapse; More Tomorrow[at random]”.

When play begins:

Test me with “sleep / look / sleep / look / sleep / look / sleep”
The sad result of this story is that every time you look at the room, the room description calls [headline], and headline is “one of these three things at random”, so every time you look at the room you get a headline at random. I thought “sticky random” would fix this, but replacing “[at random]” with “[sticky random]” means that the headline never changes, not even when “redeliver” is called.

Is there some way to assign text at random to “headlne”, and have it stay that way, but still be changed later?

I don’t think you can do that with the standard text substitutions. I’d use a list, something like this:

Your House is a room. The description is “This is a boring little house. Someone has brought in the newspaper already; its headline is ‘[entry 1 of headlines]’.”

The headlines is a list of text that varies. The headlines is {“Land War in Asia”, “Pope Admits Fallibility; Experts Consider It An Error”, “Newspapers Collapse; More Tomorrow” }.

When play begins:
sort headlines in random order.

To redeliver:
rotate headlines.[/code]
“rotate headlines” moves entry 2 to entry 1, entry 3 to entry 2 and so on so that entry 1 is always a new entry and if you run out it starts from the beginning.

Juhana’s way is more elegant anyway, but just out of curiosity I changed headline into an “indexed text that varies” and that made Tahnan code work as expected (though I’m not sure why!).

Lists and indexed texts require use of the memory heap. You’ll probably use less memory with a table of texts or a kind-of-value:

[code]“Newspaper Headlines”

Your House is a room. The description is “This is a boring little house. Someone has brought in the newspaper already; its headline is ‘[news of the day].’”

Instead of sleeping:
say “You go to sleep. In the morning, a new newspaper has arrived.”;
follow the redelivery rule;
move player to the house.

Table of News
“Land War in Asia”
“Pope Admits Fallibility; Experts Consider It An Error”
“Newspapers Collapse; More Tomorrow”

The news of the day is a text that varies.

When play begins (this is the redelivery rule):
choose a random row in Table of News;
now the news of the day is the headline entry.

Test me with “sleep / look / sleep / look / sleep / look / sleep”[/code]

Sure, but unless you have several hundred headlines the practical difference it makes is zero.

A text with substitutions is actually a function. An indexed text is a string of characters. So if the headline is an indexed text, whenever you say "now the headline is “[one of]…”, you execute the function and store its result in a string. If the headline were a text and not an indexed text, that statement would just make the headline variable point to the function that prints “[one of]…”, which would run again every time it was printed.

If I remember other people’s reports of memory usage, even a list of a couple dozen entries takes up quite a bit more memory than a table. But perhaps I’m wrong.

Oh, weird! (It didn’t help that I hadn’t made it to “Indexed Text” in the documentation–I didn’t even know it was there.) That’s extremely useful to know. I’m assuming that an indexed text has to be stored as a string of letters and not just a reference to the “…” stuff, which is why it has the effect of freezing it in place.

I’ll certainly consider the other ways of doing this. As it happens, the text I’m working with is slightly more complex than just “Sentence[or]Sentence[or]Sentence”; translating it into the headline analogy, it’s closer to…

   now the headline is "[one of]Bachmann[or]Romney[or]Pawlenty[or]Gingrich[at random] Visits [one of]Iowa[or]New Hampshire[or]South Carolina[at random]".

It looks like it ought to be possible to simulate this with lists by setting up a list called “politicians” and a list called “states”, and then writing

To redeliver: sort politicians in random order; sort states in random order; now the headline is "[entry 1 of politicians] Visits [entry 1 of states]".

(Unless there’s a way to get “random entry of politicians” that I was missing.) Of course, this has the same problem that the original code did, which is to say that subsequent sorting of the politicians or the states changes the headline, unless the headline is specified to be an indexed list. I’m assuming that tables could be made to work in much the same way.

In situations like this, I’ve gotten into the habit of using a table, similar to Capmikee’s suggestion. I don’t know enough about the technical aspects of memory usage, but the table approach is very convenient; all of the possibilities are laid out together, and separate from the rest of the code, so I can see at a glance what’s there, and its easy to add or change entries.

Robert Rothman

You might be thinking of my case, where I exceeded z-machine limits with a few dozen lists (of three to eight entries) rather than a list with a few dozen entries. As it was explained to me, lots of lists eat lots of memory because the game reserves a bunch of room for each one to expand, even when the lists are in fact completely static.

With Z-code, I think that just including even one list (or worse, indexed text) in your game will cause the code library for managing that data type to be compiled into the file. I think the indexed text library by itself is about 100K, which is a pretty big hit for that limited format.

If you’re compiling to Glulx, there is almost certainly no reason that you need to give these memory questions any thought at all.