CText Engine
During my first semester at UCF, I was a Computer Science major taking Intro to C. For the most part, the class was simple: it introduced basic programming concepts (loops, variables, functions, etc.) that I was already familiar with. Pointers were new, but I picked up the concept pretty quickly, and was having a very nice time enjoying the little programs we made for the class. However, at the end of the semester, we had a project: Make whatever you want.
In most cases, our professor shared, students made small games, inventory management systems, etc. Battleship was common, as were simple versions of chess/checkers (with no AI).
I wanted to make a little text adventure game engine, editor, and player.
Over the course of about two weeks, I made CText as my final project, alongside two little example worlds for it.
Here's what it does, and how it works.
What it does
When you execute CText2.exe, you're given the option of opening the editor or the player.
The Player
When you select "Player," the program asks what file you'd like to load - I provide two worlds already: mansion.world
and new.world
. Typing in either file will open them up, and begin playing.
The game takes place in a series of rooms. Each time it's the player's turn to put in input, the room is named, described, and the various pathways out of the room and the items in both the room and in the player's inventory are listed. Each "door" in the room is listed in an ordered list starting from one, and the items all share another ordered list.
Inputting "h," or any unknown command pulls up the list of commands
"g" attempts to traverse through any door (path) that you ask - though some paths may be blocked and must be unlocked by an item.
"i" describes the item you select
"t" attempts to take the item from the ground and put it into your inventory
"u" attempts to use an items action. This can range from unlocking doors to transforming the item to making the item dissapear
"c" attempts to craft or combine two items together
"q" quits the player.
The game consists of traveling from room to room, interacting with items and combining them together to whatever end you might desire. It's a pretty simple, but (in my opinion) flexible system that allows creators to do a lot of things that are quite unique.
In the new.world level, the world is pretty simple. Built as a testing ground, it features a simple puzzle (unlock the garage door and use the computer to end the game), a few interactible items, and multiple rooms.
If you want a guide, it's listed here:
new.world guide
- Use the knife block to get a knife from it
- Go to the basement
- Use the fish dispenser to get a keyfish
- Combine the knife and the keyfish to get the keyfish skeleton
- Go back to the kitchen
- Go to the living room
- Use the keyfish skeleton, which unlocks the door to the garage
- Go to the garage
- Use the computer to end the game.
The "mansion.world" is supposed to be a slightly larger, but still kinda small level. You find yourself in the overgrown garden of an abandoned mansion, and must find out what happened to leave it in such a sorry state. You can discover the story through notes left around the mansion, which also guide your actions.
mansion.world guide
- Take both the key prong and key handle from the ground
- Combine the key prong and key handle to form a rusty home key
- Use the key, which opens the door
- Enter the mansion
- Enter the grand hall
- Go to the armory
- Take the axe and short dagger
- Go to the grand hall
- Go to the lobby
- Go back outside
- Use the axe, opening up the overgrown path
- Go through the overgrown path
- Take the inactive golden chalice
- Work your way back to the armory
- Go to the servants quarters
- Go to the wine cellar
- Combine the short dagger and the wooden chest to get transform it into an open chest
- Use the open chest to get a piece of gold
- Combine the golden chalice and the piece of gold to get the activated chalice
- Combine the golden chalice and the leaky cask of wine to get a filled activated golden chalice
- Pick up the filled activated golden chalice
- You have two options: For the bad ending, use the filled activated golden chalice to die on the spot
- Go to the servants quarters
- Go to the master's quarters
- Combine the filled activated golden chalice with the dead corpse to create an angel
- Use the angel to end the game
The Editor
The editor was by far the more complicated part of the program. In the player, only a small subset of interactions is allowed between the player and the world, and it can therefore be limited and controlled. But an editor? A lot more freedom is required to allow for the construction of unique, dynamic worlds.
When you open or create a world in the editor, you land at the index room - the starting room. Here's what the index room looks like for new.world
In this main mode, there's little you can do directly. To make real change, you must go into any of the submodes - room, door, item, or combination, to make real change.
Room Mode
Room mode allows you to edit the names and descriptions of all the rooms in the world, as well as creating and deleting existing rooms. This also allows you to jump to any room in the world, bypassing the door traversal method that the player is limited to.
Door Mode
Doors are the way the player traverses the world, and as such, are a critical part of the editor. However, they're pretty simple. Doors have a description and a destination, and that's about it. If the destination of the door is "-1," then the door is locked and cannot be traversed. This - and any door's destination - can be changed through the use of items by the player.
The destination here in the ID of the room the door will go to. It's not the cleanest solution, but it works okay. If I put more time into this, I'd include a listing of all rooms inside the door editor, but unfortunately I did not.
Item Mode
The item mode lists all item prototypes in the world - which can be a few - as well as the items in the current room. Think of the item prototypes as the origianl versions of the item - they represent an idyllic version of the item from which actual versions can be cloned from.
The interesting part about items is the Action stuff - there are five different action types, though they're not clearly laid out in the editor
Action Type -1
The item does nothing when interacted with.
Action Type 0
The item acts as an item dispenser, creating a new specified item when the user interacts with it.
This is configured by two variables - the item ID and the quantity. The quantity represents how many items can be dispensed (-1 for infinite), and the ID is, naturally, the ID of the item to be dispensed.
Action Type 1
This item transforms into another when interacted with. The user is informed of the transformation, the item is dropped into the inventory it came from, and the original is deleted. Configured by the item target ID.
Action Type 2
This item unlocks a door when interacted with.
It's configured with a room ID (so that it only unlocks doors in a specific room), a door ID (so it only unlocks a specific door in that room), a desintation room ID (where the door will point to next), and a message, describing the action. The item is destroyed afterwards.
This is probably the most powerful of the item actions - you could go through and set up elevator buttons, shifting mazes, anything, just with the ability to reroute any path/door on the fly by user actions.
Action Type 3
This item ends the game, printing out the configured message before closing.
Combine Mode
Here, you create recipies that combine two items into another. In addition, you can add a description of what happens during the combaintion
A recommended process for making worlds
- Write out and plan the overall story & puzzles on paper
- Create all of the rooms
- Create the items
- Create combinations
- Place items into the rooms
- Test
How it works
Basically, lots of linked lists and pointers.
This is the most advanced data structure we learned at the time. So I just made everything linked lists. It's messy. Would not recommend.
The .world files themselves are a little more interesting - they're ASCII encoded files. I might investigate documenting them further later, but for now, that is an exercise left up to the reader.
The source is available on github: thomasstoeckert/ctext: A simple text-adventure engine written in C, created as a first-semester final project for Intro to Programming at UCF (github.com)
It was orignally built for Windows, x86. Also built using Code::Blocks, so you have to install that to compile the project.