Elevator Patterns

Was mildly surprised to see only one TADS elevator discussion here: Elevator as Booth, or Room (TADS3)

Before consulting this forum’s history, which I really should get in the habit of doing, it occurred to me there are 4 obvious ways to elevator.

  • As a Room whose travelConnector changes;
  • As Booth with similar exit manipulation (and/or relocating the Booth itself);
  • As Vehicle that travels between rooms;
  • As near-identical static Rooms you just quietly teleport the PC between when floor is selected

Obviously a bit depends on the robustness of the physical model, and inherent assumptions. Can the player traverse floors OTHER ways? Do you need to model the elevator not being on the same floor? Can other characters use it?

In my hubris, and with some simplifying assumptions, I committed to the first without much thought or reflection. For simplicity, assume it is a two-position elevator, between lobby and upper hallway. While working fine, I am wondering if there are hidden drawbacks to this implementation vs Booth/Vehicle/Teleport. Or other solutions I may not be thinking of. Anyone have another implementation they care to share?

lobby : Room 'Hotel Lobby' 'hotel lobby'
    "A hotel lobby.  There is an elevator to the north.  "
    vocabWords = 'hotel entry/entryway/lobby'
    north = elevatorOnFloor
;
+ elevatorEntry : Enterable ->elevatorOnFloor 'main hotel elevator'
    'main elevator'
    desc = "<<elevator.desc()>>"  // since my elevator is always 'open'

// since vocab same as elevator proper
    dobjFor(Enter) { verify() { logicalRank(120, 'elevatorIn'); } }
;
//  This is the moving part!
elevatorOnFloor : RoomConnector
    room1 = elevator
    room2 = elevator.atLobby ? lobby : hallIntersection
;
elevator : Room 'Main Elevator' 'main elevator'
    "A hotel elevator with control lever.  Through the door you see
        <<atLobby ? lobby.theName : hallIntersection.aName>>.  "
// because desc also used by Enterables
    remoteDesc(pov) { "A hotel elevator with control lever.  " } 
    vocabWords = 'main hotel elevator'
    atLobby = (liftLever.curSetting == 'LOBBY')
    south = elevatorOnFloor
    out asExit(south)

//  only tricky part is here.  Without this, 
//  going say north reports exit to south "back to <wrong floor>"
// could make more sophisticated by detecting floor and whether its been seen...
    cannotGoThatWay() { reportFailure(cannotGoThatWayMsg); }
    cannotGoThatWayMsg = 'The elevator\'s only exit is to the south.  '
;
+ liftLever : Settable, Component 'control lever/selector' 'control lever'
    "A lever, for selecting floors.  It is currently pointing to <<curSetting>>.  "
    validSettings = ['LOBBY', 'HALLWAY']
    curSetting = 'LOBBY'
    canonicalizeSetting(val) { return delegated LabeledDial(val); }
    isValidSetting(val) { return delegated LabeledDial(val); }
    makeSetting(val) {
        if (val != curSetting) {
            "A short ride <<if (val == 'LOBBY')>>downward<<else>>upward<<end>>,
                and you arrive at <<if (val == 'LOBBY')>>the lobby<<else>>a
                long hallway<<end>>.  ";
            inherited(val);
        } else "The lever is already on that setting.  ";
    }
;
hallIntersection : Room 'Hotel Hallway' 'long hallway'
    "A long hallway.  "
    vocabWords = 'long hotel hall way/hallway'
    north = elevatorOnFloor
;
+ upperElevatorEntry : Enterable ->elevatorOnFloor 'main hotel elevator'
    'main elevator'
    desc = "<<elevator.desc()>>"  // since my elevator is always 'open'

// since vocab same as elevator proper
    dobjFor(Enter) { verify() { logicalRank(120, 'elevatorIn2'); } }
;
1 Like

Maybe I’m missing something, but the problem with using a Booth is that it’s a nested room, which means objects in the outer room are in scope for certain actions. Since reaching outside an elevator is usually impossible or a no-no, I think it needs to be a Room. (There’s a similar issue with Vehicle.)

There might be a way to configure a Booth/Vehicle to avoid this problem, but I still suspect using a separate Room simply solves the problem outright.

My take on elevators in general:

On some early and failed WIPs, I tried various approaches to simulating elevator travel. Since nothing really interesting happens within the elevator in my stories—they’re just a means to moving the character around the map—I wound up making them Enterables where the player is teleported directly to the elevator’s destination:

>PRESS CALL BUTTON
A bell rings and the elevator door opens.

>ENTER ELEVATOR
The elevator takes you to the penthouse suite...

Penthouse
This luxurious abode...

If, however, the elevator had multiple stops, I would approach the problem as a Room:

>PRESS CALL BUTTON
A bell rings and the elevator door opens.

>ENTER ELEVATOR
Elevator

There are three buttons, marked 1, 2, and 3.

>PRESS 1
You're already on the first floor.

>PRESS 2
You're whisked to the second floor.

Second Floor
A long hallway leads deeper into the building...

(In other words, press the floor button and the player is deposited at the destination.)

I think you could build a single elevator Room and have the call button on each floor simply rewire directional navigation by manipulating in properties and careful use of isHidden for Enterable objects.

The point is, I’ve come to push back on the hardcore logistics of building a true functional elevator, and more about seeking shortcuts to keep the player’s interest and the story moving forward. Does anyone get a visceral thrill operating a simulated elevator? (I suppose someone out there does…)

6 Likes

Seems like it needs to be a single object, or items left in the elevator won’t travel with it.

Another option is to treat it more like a staircase than something the player actually gets in. Press the call button and get a floor menu sort of thing. Make the up/down commands do elevator things.

3 Likes

Hm, good call. I read the general tenor of your advice as ‘worry less about what it is, than how you want it to play.’ That is def bangup advice. Elsewhere in my WIP, I implemented a Booth because, well, it was an actual booth. However to get the gameplay I wanted I needed to apply a mix of OutOfReach behaviors and isLookAroundCeiling(actor, pov) { return true; } In retrospect, a Room implementation would have been much simpler.

D’oh! I was SO CLOSE!

Lol, this is one of those ‘do it because you SHOULD, not because you CAN’ things, innit? Thanks for your thoughts!

(Counterpoint, the BluesBrothers elevator scene! Granted, may not translate to IF so well…)

4 Likes

If you want to see someone else’s implementation of an elevator, here is mine. It’s a moving room which has multiple (disable-able) buttons, exterior call buttons per level, a key card that gives you access to certain floors, sounds made when travelling and arriving, and probably even more overly-engineered features: BEHOLD MY MESS OF CODE

4 Likes

summing all up, all four methods are valid, but I strive for world model consistence…

Best regards from Italy,
dott. Piergiorgio.

1 Like

Thanks for sharing! This was my secret agenda, I tend to learn a lot from reading others’ code. Your implementation was certainly complete! If I may be so bold, the only missed opportunity I detected was this:

+ElevatorSounds
    movingMsg = '<<one of>>An<<or>>The<<stopping>>
        electric piano version of <i>Girl from Ipanema</i>
        <<one of>>meanders in the air<<or>>plays barely above subliminal levels
        <<or>>causes Pavlovian toe tapping<<or>>exerts its mesmeric force on you
        <<or>>conjures images of white sand beaches<<or>>tests your patience
        <<at random>>.   '
1 Like

In Thaumistry, I had an elevator that went to three floors. It had three buttons (“B” for basement, “1” for the lobby, and “2” for the mezzanine.). I implemented it as a booth that moved between rooms.

(Disclaimer: Realnc helped me out with the gnarlier problems in Thaumistry. I have lost in the mists of time the recollection of which one of us implemented the elevator. I neither wish to take credit for this implementation if it is seen as elegant, nor foist the blame on him if it is not. At this point, I can only say that, for better or for worse, here is the code that ended up in the game.)

I don’t want to spam the thread with a bunch of code, but here is a Dropbox link to the file that contains the elevator object…

And here is the code for the simplest of the 3 rooms that the elevator goes to.

–Bob

6 Likes

Another great block of code! I particularly liked the repurposing of up/down. So we’ve seen room, booth and teleport solutions. Anyone try vehicle, or is that just a less-elegant booth?

1 Like