Elevator and Stairs (Example Code)

I’ve added some example code to the Wiki:

Elevator and stairs (Dialog example)

If anyone has suggestions on how I could improve the code or solve the problem in a more idiomatic way, I’d be grateful.

4 Likes

I spent a little time playing with your example earlier this evening.

First off: the scenario plays very well, and lots of small details are carefully implemented. This is of course the main job of the IF author, so, congratulations!

Since you’re asking for suggestions, I’ve written some notes below.

More relations

There are quite a few if-else chains in the code that deal with each of the floors in turn. For example:

(if)($Room = #ground)(then)
  (now)(#ground-button is lit)
(elseif)($Room = #second)(then)
  (now)(#second-button is lit)
(else)
  (now)(#third-button is lit)
(endif)

This can be more concisely implemented by adding more relations to the code. If you’d declared (#ground-button is the button of #ground) etc. somewhere in your code, you could replace that whole paragraph with ($B is the button of $Room) (now) ($B is lit).

An extra clever way to do this is with a “level” predicate. For example:

%% If we declare the floor level of various things in the game...
(level #ground 1)
(level #ground-button 1)

%% We can figure out which button matches which door by checking the level
((call button $B) is the button of (room $R)
  (level $B $N)
  (level $R $N)

Because relations are so fundamental in dialog, whenever you can capture some meaningful structure about your game in relations things seem to just work out a lot nicer.

More math

Timers are also implemented in a rather labour-intensive way:

  (if)(#third-door closes in 1)(then)
    (now)(#third-door closes in 0)
  (endif)
  (if)(#third-door closes in 2)(then)
    (now)(#third-door closes in 1)
  (endif)

(#third-door closes in $Old) ($Old minus 1 into $New) (now) (#third-door closes in $New) does the same thing (for $Old > 0) and behaves better if eg. you ever decide to increase the time the doors stay open.

This combines well with the first suggestion. If you apply both to the section of code this example was taken from, it shrinks down quite a bit. And if you have a (level $ $) predicate to get the floor number for various things, there are a lot more opportunities to implement logic by comparing numbers instead of handling things case by case.

Really minor stuff

A couple places have more customization than necessary:

  • (par) appears in a lot of places where dialog adds paragraph breaks automatically, like at the end of room descriptions.
  • The custom leave-by-stairs action doesn’t seem to be doing anything that the builtin behaviour for go doesn’t do.
  • There’s a little dead code; for example, a global variable that’s never used.

Anyways, I hope that’s all helpful and not annoying. And thanks for contributing the code – having more examples out there is really useful!

3 Likes

Your code is beautiful! Thank you!

The custom leave-by-stairs action doesn’t seem to be doing anything that the builtin behaviour for go doesn’t do.

I’m pretty sure I added that so that as per the instructions taking the stairs takes three ticks instead of the usual one. (N.B. Going north should still take only one tick.) I will add a comment to that effect.

Anyways, I hope that’s all helpful

This is the first time someone has commented on my working code, so this is super helpful. You’ve given me ideas on not only how to improve the example code but also how to improve the code in one of my personal projects. Again, thank you!

How, if at all, would you like me to credit you when I revise the sample code?

Edit: I have updated the example code on the wiki.

You’re welcome! I’m glad there’s more and more Dialog code out in the wild these days, so we can all learn from each other.

That makes sense! It’s possible you could get away with a (after [leave $ #up/#down]) rule that calls (tick), but honestly I’d have to try it to be sure; I’ve never really looked into how the tick processing works.

No need!

1 Like