Performance Best Practices

Whether Hanon was off target or just mis-expressed himself, a related thing of mine (or maybe what he was trying to say) is:

I don’t give all things in the world a flag unless they need it or it will really help the code, if I can just give one thing a flag.

So if there’s one character whose happiness or anger is relevant, I say ‘Juanita can be happy or angry.’ Rather than ‘A person can be happy or angry. Juanita is (usually) happy.’

This approach can backfire if happiness/anger needs to interact with code in some very general case later on, but usually in a game where the case is this simple, this is OK.

The approach grows out of a general healthy conservatism of programming. I was thinknig ‘well, now the program doesn’t have to assign all those variables, and maybe it won’t have to iterate over them.’ Whether this is a case that ever made a real performance gain in any circumstance (I assumed it makes a memory difference, and memory is very burnable), I dunno.

-Wade

1 Like

This saves memory, but I don’t think it improves speed.

I’m a bit unsure about when to tag.

Tagging all things in the world seems most stable. If the game code checks if the ‘noun’ is sorted-alphabetically, and the noun in this instance is a horse … sure, I should have stopped the horse from getting this far in the first place, but at least the tag tells the game what to do. And when the horse is defaulted to not sorted-alphabetically, this won’t even be mentioned with showme horse.

I happen to live in this wild sci-fi future where RAM is measured in gigabytes, so no practical limit here.

I just noticed that people are defaulted to ‘unlit’ and ‘inedible’ :slight_smile:

1 Like

Actually, it’s also a fair point that Inform games can be played on a multitude of devices. FWIW. You don’t have to take that into consideration, and if you’re making something like Counterfeit Monkey where you just have to shrug and accept that performance will be sub-optimal in mobile/browser interpreters, then you should totally shrug and move on ahead.

…but if you’re not, give some thought to the little people. :wink:

The problem here is that before, Instead and After just feel much more intuitive, and that the alternatives doesn’t do exactly the same thing.

How costly in performance terms are before/instead/after rules, anyway? I always figured that running several extra rules a turn wouldn’t clobber performance much, as long as those rules weren’t doing expensive things like text manipulation (or lookup on huge tables, which a lot of my rules do do). But I don’t know.

That’s part of what I’m looking for from this thread–not “This trick will speed your game up a little” but “Here’s what’s totally clobbering your performance, and here’s how you can fix it.”

Very little. Each of them is called on every action, and exits quickly when the action does not match. So it’s not significant unless you wind up writing you whole game that way and have hundreds of instead rules.

There is no one great answer. If there were, someone would have stickied a list the first five times the topic came up.

1 Like

To expand on that:

Usually, no single thing in a game is the cause of bad performance. It’s a combination of several things, and you have to look at the game to decide which one to fix.

In the Counterfeit Monkey thread, I mentioned this bit of code:

Definition: a room is southern:
	let way be the best route from the roundabout to it, using even locked doors;
      	if way is south:
      	       	 yes;
	if way is east:
      	       	 yes;
	no.

Turns out that’s bad – but this is only obvious when you know that (a) CM has a whole lot of rooms, (b) there’s a “room-restriction rule for a southern room” which is checked on every action, © the game has “Use slow route-finding”. (I expect there’s a reason for © but I haven’t tried to figure out what it is.)

So it’s really hard to give general advice other than “don’t do slow things very frequently.”

The right answer is to run a profiler, but the profiling mode of glulxe is a nuisance to compile, a nuisance to run, and interpreting the results takes a knowledge of I6 and then some practice on top of that.

1 Like

Good point!

On the other hand - Let’s say we had a total of 200 before/instead/after rules. And let’s say we have 30 npc characters, each of which perform their own actions each turn. That would give 200 x 30 = 6000 things inform has to check out each turn.

I sort of feel that I had been drawn towards Before/Instead/After not because they were the right choice, but more because they sounds so comfy, as opposite to the more tech-sounding Check/Carry out/Report. I feel the right approach would be to first see if Check/Carry out/Report are the right tool for the job, and if they’re not, try out Before/Instead/After.

I have tried my best to understand how to replace Before/Instead/After. Corrections most welcome, and most likely needed:

THE THEORY:

Each action, like TAKE or JUMP or EAT, has its own Check rulebook. So Check jumping only gets consulted when the player jumps.

On the other hand - there is only one Before rulebook. So Before Jumping gets consulted for all players commands. Same goes with Instead and After.

So Before, Instead and After uses a lot of resources. Consider if they can be replaced with action-specific rules like Check, Carry Out or Report.

REPLACING BEFORE

Before can (sometimes) be replaced with Check.

OLD CODE:

Before a woman (called W) jumping: Say "A female person called [W] is going to jump! How very exiting!";
NEW CODE:

Check a woman (called W) jumping: Say "A female person called [W] is going to jump! How very exiting!";

But this trick only works for specific player actions. The following is not a player action, and thus, can’t be replaced with Check:

Before printing the locale description of a room: Say "(nice!)";

Likewise: in the following, ‘doing something’ would be too abstract for Check :

Before asking someone (called P) to try doing something: Say "With great authority, you order that [P] do your bidding."

REPLACING INSTEAD

Instead can be replaced with Check (or Carry Out). Just remember to add the word ‘instead’ in the end, to tell inform to abort any subsequent rules.

OLD CODE:

Instead of eating the fish: say "Ewwww!"
NEW CODE:

Check eating the fish: say "Ewwww!" instead.

REPLACING AFTER

After can be replaced with Report (or Carry Out) Just remember to add an extra line with ‘Rule succeeds.’ to abort any subsequent rules.

OLD CODE:

After eating the fish: say "Did you just eat that?"
NEW CODE:

Report eating the fish: say "Did you just eat that?"; rule succeeds.

Well, a game with 30 NPCs carrying out independent actions each turn (as opposed to getting activated when you reach their location) would be far more complex than most games anyway. A lot of the time much of this could be taken care of by using Every Turn rules to move the NPCs around instead of the full-fledged action machinery–for instance, in many cases, instead of trying the NPC go somewhere, you can just move them to their destination.

If they really need to obey action rules (whenever anyone goes to the bank vault the alarm goes off) then this won’t work, but again, we’re looking at an extraordinarily complex game.

In fact, this is an activity rather than an action, so it doesn’t involve the Before rulebook at all, but the Before printing the locale description activity. See §18.3 of Writing with Inform.

In this particular case I think you can shunt it off to a persuasion rule:

First persuasion rule: Say "With great authority, you order that [the person asked] do your bidding."

Agreed, there is no reason to aim for realism when a shortcut can get the job done. It is a classic error in games to waste time on realistic simulation that has no real impact on the actual gameplay. I think it was SIMS 4 which let 80 different sims in your neighborhood go on with their life in real time - something the player hardly noticed since he was focused on managing his own sims.

… wait, instead is supposed to take precedence over any check, right? To sort of replicating that effect with check, we could add a first check, like so:

OLD CODE:

Instead of eating the fish: say "Ewwww!"
NEW CODE:

First check eating the fish: say "Ewwww!" instead.

I’d been giving this some thought. What I do here is replacing some really good, specialized rules - before, instead and after - with some hacks which hopefully does kinda the same things. So basically, the code becomes a bit more crude.

This should be held up against the slightly performance gain.

On the other hand, if I have 50 instead rules to check if the player is going in wrong directions in certain rooms - those 50 completely similar instead rules could easily be replaced with check:

[Instead rule converted to Check:] First check going north when player is in temple: say "You hit a wall. It's really quite solid." instead.

(I think it would be a good practice to always mention in a comment that the following Check rule is an Instead-wannabe.)

You can replace those 50 rules with one:

First check going nowhere: ["nowhere" is any direction that doesn't lead to a room] if the player is enclosed by indoors: ["indoors" being a region] say "You hit a wall. Ow." instead; otherwise: say "There doesn't look to be much off in that direction, so you change your mind and look for more promising routes." instead.

If regions don’t work, I’d define an adjective. “A room can be interior. Temple is an interior room.” Then check if the location is “interior” for your rule.

1 Like

Thanks, that’s pretty convenient!

Something else:
§4.14 says that duplicates makes the game slow and uses memory.

I tried to create 1000 different animals:

The game halted for something like two seconds just to type that! But looking at them individually or looking in other rooms didn’t have any slowdown.

1 Like

Now try “Loving relates various animals to various animals. Every zebra loves every rabbit.”

Actually DON’T so I’m not responsible for breaking your computer.

1 Like

I would argue Inform 7 is not the platform such a story. Dynamic objects are good for a few limited things, but hundreds or thousands? No. Not with the current foundation.

In Quixe/Lectrote on my Mac:

No objects in room: LOOK takes 12 ms
1000 objects in a different room: LOOK takes 250 ms
1000 objects in the same room: LOOK takes 11000 ms

So there is some slowdown, though obviously much less than when the objects are visible.

It’s not the computer that’d get broken. Ouch.

1 Like