CodeIgniter Forums
Text adventure - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forumdisplay.php?fid=23)
+--- Thread: Text adventure (/showthread.php?tid=39271)



Text adventure - El Forum - 03-06-2011

[eluser]devvee[/eluser]
Hello!

As a hobby project I'm trying to create a simple (single-player) web-based text adventure, like the old Zork games. I'm a bit stuck on how to do this exactly, so any tips would be welcome!

Currently I have 2 controllers: "Userinterface" and "Command". The Userinterface controller loads the view and the room you're currently in when starting the game. The rest of progress gets loaded with AJAX (with help from jQuery).

The commands you enter are intercepted with the Command controller. Right now it contains an array with as keys all possible commands and as value the function they refer to. Example:
Code:
$commands = array(
    "move"        => "move",
    "go"        => "move",
    "north"        => "move",
    "n"         => "move",
    etc...

    //Interaction
    "take"        => "take",
    "get"        => "take",
    "pick"        => "take", //pick up
    "grab"        => "take",
    "use"        => "use",
    "combine"    => "combine",
    "give"        => "give",
    "open"        => "open",
    etc...
);

The "move" commands refer to the _move function. It checks the entered command, and executes it. So "nw" refers to _move($cline), with $cline containing the entire command line. Then it checks the variable, see you want to move "north-west" and checks if there's a path in your current room allowing you to move there. If so, it loads the target room and presents you with the room description.

Quite simple, really! But now there are a few things I'm not sure about.

Rooms
How should I go about making the rooms? I personally thought about giving each room a class that inherits a master class containing all basic room functions (such as creating pathways, or objects that can be interacted with). How can I best do this with CodeIgniter? Make each room a library in CodeIgniter?

Items
The player should be able to pick up or interact with items that can be found in each room. When an item is picked up, it becomes part of the inventory and can be used in any other room. For instance, if I pick up a "book", I should be able to read it in another room. This means I can't define the entire item in the room it was first created in. Should I make a separate class for each object as well? This seems to be a little bit overkill for most items.

Custom commands
Occasionally, a room will have a command that is not available in the command array, because the command can only be used in that specific room. This means I will have to create a function for that command in the class of the room that uses it. Is this the best way to do this? Or should I just limit the game to only use the commands defined in the command array?


For a very small sample of what I have already made, look at: http://www.devvee.com
It only gives simple responses to some commands (like trying to move, or taking an item. Right now it takes any kind of item you enter, because there is no real check on whether the item exists yet. Would be pointless to make this if I'm not sure how to code the items!)

Any kind of help or tips would be great!

Thanks in advance,

Dev


Text adventure - El Forum - 03-06-2011

[eluser]Jaketoolson[/eluser]
> take virginity
You take virginity


Text adventure - El Forum - 03-06-2011

[eluser]devvee[/eluser]
[quote author="Jaketoolson" date="1299463693"]> take virginity
You take virginity[/quote]
Fixed that for you Wink


Text adventure - El Forum - 03-06-2011

[eluser]Jaketoolson[/eluser]
Even though I'm 29, married with 3 kids, 4th on the way, I still went the immature route Smile

The only thing that comes to mind first is creating some sort of DB schema that defines the rooms and items that can be used.

For those special commands, couldn't you just extend a boilerplate class or something?


Text adventure - El Forum - 03-08-2011

[eluser]devvee[/eluser]
[quote author="Jaketoolson" date="1299477462"]Even though I'm 29, married with 3 kids, 4th on the way, I still went the immature route Smile

The only thing that comes to mind first is creating some sort of DB schema that defines the rooms and items that can be used.

For those special commands, couldn't you just extend a boilerplate class or something?[/quote]

The rooms and items should be fairly dynamic, which is not really possible if I put them in a database. It's going to be a single-player game (but still online!), so I can't change room descriptions in the database if someone alters the room. After doing a certain action, the room description may change or some function may trigger based on your flags (a room may start out flooded, but once you flip a switch elsewhere, the real room description will show up). Additionally, an item may have specific functions as well. For instance, you may find a mechanical monkey that works with the command "wind up", but the command is unique to that item. The reason for this is so it's easy to create rooms and items without having to edit the main files and still being quite free in what to do with it.

I've changed the structure a little bit from my initial plan. I still have two controllers, except I've renamed them: Initialize and process.

1. Initialize is only used when entering the website. It checks for a session and presents a login form if none is available. A login is required so that data can be saved. Save states are the only things a database will be used for. Then it will load the interface view, which is the base HTML structure with the CSS and javascript files.

2. The javascript file will trigger a command on load that requests another page through AJAX. This is the process page together with the "look" command (through post data). Since progress in the game is only made through entering commands, every action has to go through this controller. The game starts with a "look" action, so your current location is described to you, be it the starting location or a location from a save state.

3. The process controller first checks the current room (which should be in the session after login). It then loads the base location class (library), as well as the current room class (also a library), that extends the base location class. The base location class provides functions to the custom room, such as "add_path()", "add_item()", "description()", "commands()" and through the use of these commands it generates an array, that once finished gets passed to the process controller.

4. The process controller now has the current room data. It then checks what command was used, which right now is "look". It confirms the existence of look, by merging the custom set of room commands (created through the location class' commands() function) with the base list of commands and checking it. If it is a legal command, it proceeds to the function of that command, which is "_look()" (also defined in the commands array).

5. The _look() function then gets the room description and available item list from the data array received from the location class. It uses a custom _echo() function, which puts all the output in an array. This way, I can easily change the formatting of the output without having to change many different lines in the code. Right now every line of output gets a <span> at the start and a </span> at the end of the line.

6. A custom _output() function then really echo's every line in the array created by the _echo function and this is where the script stops and waits for a new command!


I have yet to make a login script and most functions still don't work. Right now I'm working on the function for movement, so I can test the loading of new rooms, the paths and more. Items are most likely going to be classes as well, but I'm not sure on this yet.

Save states: I'm still not sure how to tackle this one. A player will advance through the game by entering new rooms, changing rooms (flipping switches, moving objects, taking objects, etc.) which will set flags for him. There are item and event flags. The item flags are placed in an array, with the item classname as key. Its value is the state of the item. "0/false" = doesn't have the item. "1" = has the item in inventory, etc. I'm not yet sure how to enter elaborate states, such as the item being a "wound-up mechanical monkey" instead of a "mechanical monkey" if you used the "wind up" command.

This item list also contains the list of dropped objects and which room they are dropped in, so you can drop an item and still have it lying there when you re-enter or look.

Events work a bit different, as a switch may have several states instead of just "on" and "off". I'm also not entirely sure on how to do this yet.

So the things stored are: current room, item flags, event flags. Especially the event flags can, once the game progresses, become quite an elaborate list which simply can't be cleaned up due to backtracking. How should I store these? I don't want to keep requesting the database every time an action is performed. Sessions are good, but will all this data fit? Additionally, being AFK for too long will remove your session and your progress, which is a baaaad thing!


I hope this is a bit clear! Any tips are still welcome, as I might over complicate things without noticing it Wink