WDL ~ Current Integration in Chiventure - uchicago-cs/chiventure GitHub Wiki
The World Description Language (WDL) system in Chiventure is one of the fundamental aspects of the engine. It's purpose is to allow for users to write out the rooms, objects, etc. in their text-based adventure game without the skill for programming.
This document is in response to #440 and was previously updated on Sunday May 5th, 2020.
This section primarily focuses on the format of the WDL document.
Currently, WDL information is stored in a YAML file <file name>.WDL. These files are read by the Chiventure program to construct a series of in-game objects that will act as the various rooms and items the player will interact with through their gameplay.
Objects expressed in Chiventure's WDL fall into three categories: the game object, rooms, and items. These objects are each specified in their own category on the WDL Document. Each of these items have a series of "attributes" that provide information or traits for the object.
Below is a basic description of each object in the document. A more expansive explanation of the format can be found in the wdl.md file.
The game object specifies important information for the game as a whole. There is only one Game Object per Chiventure game. It has three attributes: 'start', the room where the player begins the game; 'intro', a string of text given when the game begins; and 'end', the end condition to be met to complete the game (currently only supports the 'end_room' condition).
Example:
GAME:
- start: "KITCHEN"
intro: “Welcome to the virtual house. You have been wandering for quite some time,
and you need to determine how to return to reality.”
end:
- in_room: "LIVING ROOM"
Rooms are the locations that the player traverses through in Chiventure.
Rooms have four attributes. These are 'id', the unique name associated with the object; 'short_desc', a text displayed to the player upon entering the room; 'long_desc', text displayed to the player upon typing "look at room"; and 'connections', a list of rooms that can be entered from this room. Each connection specifies a 'to', the room id of the room the exit goes to, and 'direction', a cardinal direction used to travel to that room.
ROOMS:
- id: "kitchen"
short_desc: "A well-furnished area for cooking food."
long_desc: "The room is lit merrily, and a faint glow comes from the oven."
connections:
- to: "basement"
direction: "down"
- to: "bedroom"
direction: "north"
Items are objects that can be found within rooms and interacted with by the player.
They have five attributes: 'id', the unique name associated with the object; 'short_desc', text displayed when picking up the object; 'long_desc', text displayed upon typing "look at <object id>; 'in', a room id specifying the room the object is found in; and 'actions', a list of available actions that can be done to interact with the object. Each action specifies 'action', the action to start the interaction by typing "<action name> <item id>"; 'text_success', text that displays upon successfully having completed the action; and 'text_fail', text that displays upon having failed to complete the action.
ITEMS:
- id: "CHAIR"
short_desc: "This is a chair"
long_desc: "This is a chair long"
in: "room A"
actions:
- action: "PUSH"
text_success: "You push the chair"
text_fail: "You cannot push this chair"
- action: "PULL"
text_success: "You pull the chair"
text_fail: "You cannot pull this chair"
- action: "TAKE"
text_success: "You take the chair"
text_fail: "You cannot take this chair"
This section focuses on the process of loading an WDL file. Most of the specifics on how the code is parsed is left out, as the majority of that system was written by Borja and the TAs of last year, being more complicated than what we are expected to do.
A Chiventure game is loaded when a user types in the command: ./chiventure <string of path to .wdl file>
The file path string is passed through a series of top-level functions until finally being loaded by the first WDL command load_wdl() within chiventure_ctx_init().
load_wdl() is found with load_game.c. load_wdl() takes in a string of a path to a YAML file and returns a pointer to a game object.
The passed string is used to find the actual file itself, which is parsed into tokens that are stored in an obj_t struct called "big_document".
Aside: The entire parsing and tokenization system is found within the lib_obj directory. All of this was programmed by Borja and the previous years's TAs due to the difficulty of converting YAML files into objects. Part of the reason for switching to WDL++ and JSON is that we will ideally be able to remove this complicated system for loading a game.
"big_document" is passed into create_game(), which creates a game_t called "game" and sets the 'intro' value to be the intro text for the game.
Next, in succession, the rooms, room connections, and items are loaded into the game (using the commands add_rooms_to_game(), add_connections_to_rooms(), and load_items(), respectively). Each takes in "big_document" and "game" and returns an int value indicating success which is stored in "rc". The list of tokens in "big_document" is accessed to find the relevant objects to load which are then added to "game".
After each command, if the value of "rc" is not equal to SUCCESS, then a error is printed and a NULL is returned in place of the expected game.
Next "big_document" is used to find the 'start_room' and 'end_room' attributes, which are stored in "game" as the 'current_room' and 'end_room'.
The file validate.c contains a series of functions used for checking the types of obj_t tokens in order to more effectively run parsing of a document.
Validate contains four print functions for each relevant object: print_item(), print_room(), print_game(), and print_document(). The first three commands print out information pertaining to an individual object passed through the command. The final command, prints the information for the entire game, allowing for easy access to all information necessary gained from the WDL file.
A function list_print() also exists. It takes a list of objects and a pointer to a print function in order to automate printing out a series of object prints.
Validate.c also contains five type-check functions that when passed an obj_t, will check to ensure all attributes of an object are appropriately typed. The five functions are for: the game object, rooms, items, players, and actions.
Like the print functions, there is a list type-check function that accepts a list of objects and a pointer to a type check function to automate the process of type-checking a series of objects.
Finally, there are two other commands connections_get_list() and check_connection_attr() for checking attributes of connections.
connections_get_list() takes a room obj_t and returns the list of connections from the room.
check_connection_attr() takes a room obj_t and ensures that every single connection from that is has appropriate attributes to be a connection.