!----------------------- ! CS 370 Computer Game Design ! Twonky Island ! ! Sample game for experimental purposes ! ! Release 5; Constant DEBUG; Constant Story "Twonky Island"; Constant Headline "^CS CS370 Computer Game Design Example^"; Serial "980330"; Constant MAX_CARRIED = 10; ! Let player carry lots of stuff Constant SACK_OBJECT = backpack; Include "Parser"; Include "Grammar"; Include "VerbLib"; ! Global attributes Attribute Legible; ! From designer's manual [ ReadSub; <>; ]; Extend "read" first * legible -> Read; !!!-------------------------- ! Plot state variables !!!-------------------------- Global player_karma = 0; ! 0 => neutral, 1 => befriended twonkies, ! -1 => killed twonkies (Rambo mode). Global Player_encountered_gold = 0; Global Player_advised_by_gold = 0; ! ============================= ! Locations used in the story ! ============================= ! By default all of the places in this game are going to have ! light. Simplest way to do this is by subclassing object Class Room with explosion [obj; objectloop (obj in self && obj provides explosion) obj.explosion(); ], has light supporter enterable; ! Around the Airstrip is a control shack and three paths ! North of the airstrip is ocean, it would be nice to say ! something clever to the player who tried to go North from ! the airstrip... Room airstrip "Airstrip" with name "airstrip" "runway", description "A small runway that runs east-west, in good repair. An occasional cockatoo flies overhead, shrieking loudly. The windsock rustles slowly in a gentle breeze. ^To the west is a one-lane paved road, to the east is a footpath. A Quonset hut lies to the south-east, and a path going up a steep hill lies to the south.", w_to Airstrip_Path, e_to Beach_Path, se_to Control_Shack, s_to Lookout_Path, cant_go "The rocks are too steep to climb, and you don't have time for a swim."; Room Control_Shack "Control shack" with name "Control shack" "shack" "tower", description "A Quonset hut that was used as a control tower for planes landing on the island. It has been shredded, as if by a giant can-opener. All electronics equipment appears to have been removed. ^The airstrip lies to the northwest.", nw_to airstrip, cant_go "You try foraging through the dense underbrush, but decide that it isn't worth it and turn back."; Room Beach_Path "Airstrip beach path" with name "path" "beach path", description "This part of the Universe is under construction. Please return when the Author has made more progress on the game.^The airstrip lies behind you, to the west.", w_to Airstrip, cant_go "You peer into the deep emptyness of the Void, and decide not to leave the Author's domain."; Room Lookout_Path "Lookout Point path" with name "path" "Lookout path" "Lookout point path" "point path", description "This part of the Universe is under construction. Please return when the Author has made more progress on the game.^The airstrip lies behind you, to the north.", n_to Airstrip, cant_go "You peer into the deep emptyness of the Void, and decide not to leave the Author's domain."; Room Airstrip_Path "Airstrip road" with name "Airstrip road" "lab road", description "This one-lane paved road connects the Base (going west) to the Airstrip (going east).", e_to airstrip, w_to Base_Guard_Post, cant_go "You decide that you don't have time for a swim, and that the dense foliage looks uninviting."; Room Base_Guard_Post "Base Guard Post" with name "Guard post" "Post", Initial "It's clear that a struggle occurred, with weapons of unknown origin.", description "The guard post has been charred and blasted. ^The Laboratory lies to the west, and the road to the airstrip runs off to the east.", w_to Laboratory, e_to Airstrip_Path; Object -> "guard's body" with name "body" "guard^s body" "guard", description "Although there isn't much left, from the remains it is clear that this was once a sentry.", has static; Room Laboratory "Laboratory" with name "Lab" "Laboratory", initial "The door to the laboratory is shredded, and the whole building has a burnt-out look to it. From the layout of the base, it seems clear that supporting this laboratory is the whole purpose of the base. Looking out the east door you can see the guard post, and looking out the south door you can see a beach.", description "The interior of the laboratory is one large room, containing various benches with equipment and a bookshelf lining one wall.", e_to Base_Guard_Post, s_to Western_Beach, cant_go "While the walls have had heavy damage, they do not yield when you push against them."; Object -> Bookshelf "bookshelf" with name "bookshelf" "shelf" "books" "book", description "The bookshelf contains a selection of technical books, mostly in the physical sciences and electronics.", before [; Read: "Your mission is urgent, and you won't learn anything from these."; ] has legible static; ! Could make the bookshelf suffer damage if a grenade goes off where ! it is. Or make it movable, if there is some useful purpose that ! could be served by it as an alternate solution to some puzzle. ! But otherwise we don't want the player fooling around in ways that ! will ultimately prove fruitless. Object -> Scientist_Body "scientist's body" with name "body" "scientist's body" "scientist", description "This corpse was probably a scientist working in the lab. Like the sentry, the body is burned beyond identification. A mostly-melted remote control unit is fused into one hand.", has static; Object -> Lab_Bench1 "long laboratory bench" with name "long bench" "bench" "long", description "A long laboratory bench, with various pieces of apparatus on it. Each piece of apparatus has at least one component missing from it.", has static; Object -> Lab_Bench2 "cluttered laboratory bench" with name "cluttered bench" "bench" "cluttered", description "This lab bench is festooned with small mechanical and electronic parts. It is as if someone spread several devices out on it. Each piece of apparatus has at least one component missing from it.", has supporter static; Object -> -> Scientist_Note "note" with name "note" "message", Initial "It looks as if a message was hurridly scrawled on a page torn from a lab notebook.", description "The page is charred, but the note is still readable.", before [; Read: "When we saw them at the airstrip, they looked like animated 1950's radios, so we called them Twonkies. They took apart the control hut, as if they were looking for something. The officer of the day fired on them, and they shot him with a red beam. They swarmed up the road. It would have been funny, that combination of square boxy bodies and obscenely lithe limbs, if it hadn't been for the devastation and the smell of charred flesh. Fred tried radioing for help, but they already got the airstrip antenna and we seem cut off from the Command Dish. George broke out the guns, and maybe we can..."; ] has legible; Room Western_Beach "Western Beach" with name "Beach" "Western Beach", description "The smooth fine-grained sand stretches out before you, inviting you to dive into the crystal blue water, if only there were time and circumstances less dire. Fronting the beach is a dense stand of palm trees. ^Paths lead off to north, south, and east.", e_to West_Beach_Picnic_Area, n_to Laboratory, s_to Command_Antenna_site, cant_go "You really don't have time for a swim right now."; Room Command_Antenna_site "Command Antenna Site" with name "Antenna Site" "Site", description "In this clearing, hacked out from dense underbrush, you see a small shed with several satellite antennae jutting out from it. You feel a strange sense of unreality about it, as if the Author hadn't quite finished putting it together yet.", n_to Western_Beach, cant_go "As you walk into the Void you feel an ever increasing sense of dread. After a few steps, you hasten back to a place where Reality is somewhat more firm."; Room West_Beach_Picnic_Area "West Beach Picnic Area" with name "Picnic Area" "West Beach Picnic Area", initial "This small clearing was obviously set up as a picnic area for the staff.", description "A small clearing used as a picnic area", w_to Western_Beach; Room Twonky_Lair "Twonky Lair" with name "Lair" "Twonky Base" "Twonky Lair" "hive" "colony", description "A vast cavern has been cut out of the hillside, lined with a material whose bluish hue reminds you both of steel and something oddly organic."; ! ============================= ! Props used in the story ! ============================= Class SeriousContainer ! A SeriousContainer is one that can block explosions. ! If you put a grenade in a trash pit, that shouldn't kill ! you. But if you put it into a paper bag, well... with explosion [obj; objectloop (obj in self && obj provides explosion) obj.explosion(); ], has container static open; Class grenade ! A grenade explodes after five turns have passed. ! It kills the player if they are silly enough to be in the ! same location, and also sets off any other grenades in ! the same location. with name "grenade", plural "grenades", short_name "grenade", description "regulation-issue explosive grenade", before [; Set: if (self has general) "Already activated..."; StartTimer(self, 5); give self general; "You set the grenade's timer to explode in five moves."; ], time_left 0, time_out [x; print "^The grenade explodes!^"; ! Figure out what room the grenade is in x = self; while (~~ ((x ofclass Room) || (x ofclass SeriousContainer))) { x = parent(x);} remove self; x.explosion(); if (player in x) {! deadflag=1; "^The explosion tears you apart!^ You should have moved farther away.^";}; ! remove self; ], explosion [; remove self; "The explosion sets off a grenade.^"; ], has transparent; Object backpack "backpack" ! The player's backpack contains useful stuff with description "a strong canvas backpack, suitable for carrying lots of equipment", name "backpack" "pack" "satchel", article "your", when_closed "Your pack lies on the floor.", when_open "Your pack lies open on the floor.", has container open openable; ! Start player off with six grenades Grenade ->; Grenade ->; Grenade ->; Grenade ->; Grenade ->; Grenade ->; Object machine "Alien Machine" Twonky_Lair with name "machine" "gadget" "gizmo" "kludge" "hack", description [; if (self.status == -1) "You see a pile of rubble that fills most of the cavern. Many of the parts are identifiable as bits and pieces scrounged from other parts of the island. It is clearly beyond repair."; else "You see a giant machine that fills most of the cavern. Many of the parts are identifiable as bits and pieces from the from control shack and laboratory."; ], status 0, explosion [; self.status = -1; print "The alien machine explodes, sending showers of sparks and pieces everywhere."; ], has static; Object Translator "alien gizmo" West_Beach_Picnic_Area with name "translator" "alien gizmo" "gizmo", description "An odd alien device, whose shape is hard to make out even when looking at it closely.", after [; Take: self.description = "A translation device, which converts between human speech and Twonky language."; return false; ]; ! Useful procedure [HasTranslator; if (Translator in player) return true; else return false; ]; [ ShootSub; if (noun == player) print_ret "You are too dedicated to your mission to do that."; if (~~ Laser_Saw in player) print_ret "With what?"; if (noun provides shoot) noun.shoot(); else print_ret "It hasn't done any harm to you, so why bother?"; ]; Verb 'shoot' 'blast' 'zap' 'fry' 'attrit' 'exterminate' 'terminate' 'slaughter' * noun -> Shoot; Object Laser_Saw "laser saw" West_Beach_Picnic_Area with name "saw" "laser" "weapon", with description "A small orb with a ruby rod projecting from it. There is a button on the orb." ; ! Rope puzzle ! The idea is that player will rescue Red Twonky in the trash pit by ! tying the rope around something and throwing the rope into the pit ! Idealized sequence: ! >Tie rope to stump ! >Throw rope into pit ! twonky scrambles out ! Tie is already defined in the library, so we just have to tweak the ! rope's response to that message. ! Similarly, throw is in there as well. ! Untie isn't, so we have to define it Attribute is_rope; Verb "untie" * noun -> Untie; ! Default action for untie [UntieSub; "It isn't tied up right now."; ]; !Have to extend throw to handle ropes, which can ! be thrown even though they aren't held. ! N.B. The "first" makes this extension the first rule ! used when parsing throw. Extend "throw" first * is_rope "in" / "into" noun -> TossInto; Verb "toss" * is_rope "in" / "into" noun -> TossInto; [TossIntoSub; if (~~ rope has is_rope) "You can't toss that"; else "You can't toss it there."; ]; Object Rope "rope" West_Beach_Picnic_Area with name "Rope" "line" "coil" "coil of rope", description [; if (self.tied_to == 0) "A coil of rope, probably from a sailboat."; print_ret "A rope, tied to ", (name) self.tied_to; ], tied_to 0, before [; Tie: ! second = thing to tie it to. if (second has static) if (~~ self.tied_to == 0) {print "You untie the rope and tie it to ", (name) second, "."; self.tied_to = second;} else {print "You tie the rope to ", (name) second, "."; move self to location; self.tied_to = second;} else print "You try to tie the rope to ", (name) second, ", but find you cannot."; return true; Take: if (~~ self.tied_to == 0) print_ret "You can't, because it is tied to ", (the) self.tied_to, "."; else return false; Untie: if (self.tied_to == 0) "The rope isn't tied to anything."; else { print "You untie the rope from ", (the) self.tied_to, "."; self.tied_to = 0; return true;}; TossInto: if (second == Trash_Pit) {if (Babbler in Trash_Pit) { ! Time to climb out print "Seizing the rope, the red twonky lithely climbs up out of the trash pit."; move Babbler to West_Beach_Picnic_Area; if (Player_Karma == 0) Player_Karma = 1; return true;} else "One end of the rope dangles into the trash pit.";} else "Why would you want to toss it there?"; ], has is_rope; SeriousContainer Trash_Pit "trash pit" West_Beach_Picnic_Area with name "Trash Pit" "Pit", description "This deep pit was dug to hold trash from picnics, a good solution if one's goal is to minimize support staff.", has static container open; Object Barbeque "barbeque grill" West_Beach_Picnic_Area with name "Barbeque" "BBQ" "stove" "oven" "grill", description "A small gas-powered barbeque grill. It looks like it has been heavily used.", shoot [; remove self; "With a blinding flash and a nasty tangy smell, the barbeque grill is gone, with only a small puddle of liquid metal marking its presence.";], has static; Object Picnic_Table "picnic table" West_Beach_Picnic_Area with name "Picnic Table" "table", description "A picnic table, made out of redwood. Clearly imported from off the island. It has a few initials carved in it, probably by bored staffers.", before [; Read: "The wood is so weathered that you can't make out any of the initials.";], shoot [; remove self; "With a blinding flash and puff of smoke, the picnic table disappears, leaving a small pile of ash." ;], explosion [; remove self; print "The picnic table splinters into a cloud of small fragments.";], has legible supporter; Object Stump "tree stump" West_Beach_Picnic_Area with name "stump" "tree stump" "tree", description "A sturdy tree stump, set firmly into the ground.", has static; !!!---------------------------- !!! The Twonkies !!!---------------------------- [FindCurrentLocation thing; while (~~ (thing ofclass Room)) { thing = parent(thing);}; return thing; ]; ! Blue twonky names should be supressed unless the player ! has the translator. That is, we should see ! "A blue twonky wanders off" and "A blue twonky wanders in" ! instead of "Louie wanders off" and "Huey wanders in." Class Blue_Twonky with name "Blue Twonky" "Blue" "twonky" "worker" "drone", shoot [; if (random(2)==1) {remove self; player_karma = -1; switch(random(3)) {1: "The blue twonky explodes, leaving a slightly bitter smell behind."; 2: "The laser flash melts the blue twonky instantly, leaving only a single tentacle waving forlornly."; 3: "The glancing blast splits the blue twonky into two, leaving a small, harmless-looking pile of electromechanical parts, some of which are still clicking to themselves.";};} else {switch(random(5)) {1, 2: "The blue twonky skitters away, avoiding the laser beam."; 3, 4: "Rolling aside, the laser beam flashes past the blue twonky."; 5: "Using a small mirror, the blue twonky deflects the laser beam harmlessly into the sky.";};} ;], plural "blue twonkies", explosion [; remove self; print "The explosion obliterates the blue twonky.^";], daemon [current_location; if (random(3)==1) ! Move one time in three {current_location = FindCurrentLocation(self); if (player in current_location) print "^", (name) self, " wanders off."; switch(current_location) {Western_Beach: move self to West_Beach_Picnic_Area; current_location = West_Beach_Picnic_Area; West_Beach_Picnic_Area: move self to Western_Beach; current_location = Western_Beach; default: current_location = thedark;}; if (player in current_location) print "^", (name) self, " wanders in."; return true;}; ], has animate neuter; Blue_Twonky Huey "blue twonky" West_Beach_Picnic_Area with name "blue" "blue twonky" "twonky"; Blue_Twonky Dewey "blue twonky" West_Beach_Picnic_Area with name "blue" "blue twonky" "twonky"; Blue_Twonky Louie "blue twonky" West_Beach_Picnic_Area with name "blue" "blue twonky" "twonky"; Class Red_Twonky with name "Red Twonky" "Red" "flunky" "twonky", shoot [; if (random(3)==1) {remove self; player_karma = -1; "There is a blinding flash, and the red twonky explodes, causing small mechanical parts to fly everywhere.";} else {switch(random(3)) {1: "The red twonky gracefully steps aside, narrowly dodging the laser beam."; 2: "Flattening against the ground, the laser beam flashes harmlessly over the red twonky."; 3: "Leaping surprisingly high, the laser beam flashes under the red twonky.";}} ;], has animate neuter; Red_Twonky Babbler "red twonky" Trash_Pit with description [; switch(player_karma) { -1: "The red twonky chitters meanacingly at you."; 0: "The red twonky gazes at you curiously, humming softly."; 1: "The red twonky buzzes at you in a friendly manner."; };]; Object Gold_Twonky "Gold Twonky" Twonky_Lair with name "Gold Twonky" "Gold" "twonky" "boss" "honcho", initial "A golden Twonky is watching you, with some concern.", description "The Gold Twonky is about the size of the red twonkies, but seems quieter and more somber. Although you cannot see anything identifiable as eyes, you get the impression that it is looking you over with a cool and powerful intellect.", life [; Ask: switch(second) {'plan','mission','goal','asteroid': if (machine.status == -1 || Player_Karma < 0) "The Gold Twonky sighs. ~We were trying to save Humanity. A large asteroid is heading towards your planet. The consequences of its impact will wipe out most existing species.~"; else "The Gold Twonky says urgently, ~We are trying to save Humanity. A large asteroid is heading toward your planet. We are going to try and deflect in into deep space.~"; 'machine','device','gadget','gizmo': if (machine.status == -1) "The Gold Twonky looks very tired. ~That machine you destroyed would have amplified your strategic defense system enough to deflect it harmlessly into deep space. Now I'm afraid your species is doomed...~"; else "The Gold Twonky waves a tenacle proudly at the device. We built this machine out of the parts we scavanged from your base. It will amplify the strategic defense system you built here, enabling us to deflect the asteroid.~"; 'humans','people','islanders','personnel','collegues','friends': if (player_karma > -1) "The Gold Twonky bobs with regret. ~That was most unfortunate. While we were arriving, some of your people attacked us. When I am exposed to attack, my Reds tend to, well, overreact. We are extremely sorry about what happened.~"; else "The Gold Twonky bristles. ~They attacked us, tried to destroy us. We only defended ourselves. You are a brutal, horrible species. Now I wonder why we bothered trying to help you...~"; 'purpose','reason','why': if (player_karma == -1) "The Gold Twonky sways back and forth. ~We were fools. We tried to help you, and you in return are destroying us. We made a horrible mistake. You deserve extinction!~"; else "The Gold Twonky vibrates pleasantly. ~Don't you help those you feel are disadvantaged? Organic lifeforms are so fragile. And sentient ones! The very idea that an organic system can be sapient! Our philosophers still don't believe it. You are our Spotted Owl, our Snail Darter. We've stayed out of prime real estate for several parsecs to keep from disturbing your habitat!~";} "The Gold mutters, ~I'm sorry, my Human isn't very good.~"; Attack, Kiss: "You feel a mild electric shock.";], explosion [; "^The Gold Twonky buzzes irritably but is unharmed.";], react_before [; Set: print "The Gold Twonky mutters ~I wish you wouldn't do that.~^"; ], has animate; [ Initialise; ! Here is where one specifies how the game starts up. ! location=laboratory; ! Where the player starts -- airstrip is ! intended, but other locations might be used while debugging. move backpack to player; ! Give the player the backpack to start with ! ! Start up the NPC's StartDaemon(Huey); StartDaemon(Dewey); StartDaemon(Louie); ! ! And start the action rolling... print "^^You barely have time to appreciate the sunrise on the lush tropical island below as the ground rushes up at you. Your knees buckle as you land, and you quickly roll up your parachute to minimize the chance of discovery. Fortunately, the airstrip is deserted. Aside from the occasional bird call and a gentle breeze, you hear nothing.^^^"; ]; !----------------------------------- ! End of game source code !-----------------------------------