Accessing data in a JSON WDL file - uchicago-cs/chiventure GitHub Wiki

The WDL file format uses the standard JSON format. In this page, we explain the basics of JSON (particularly as it relates to the WDL), and how the contents of a JSON WDL file are loaded into memory (and how you can access them)

JSON

The basic data structure in JSON is an object: an unordered collection of key/value pairs. For example:

{
    "action": "PUSH",
    "text_success": "You push the chair",
    "text_fail": "You cannot push this chair"
}

This is an object with three keys (or attributes): "action", "text_success, and text_fail (keys in JSON are always double-quoted strings). Each has an associated value; in the example above, they happen to be strings, but can also be integers, floats, booleans, lists, other objects, or the special value null.

For example, the following object has an end attribute whose value is another object:

{
    "start": "room_A",
    "intro": "This is the intro",
    "end": {
               "in_room": "room_C"
           }
}

JSON also supports lists of values delimited by square brackets. In the example below, the actions attribute contains a list of objects:

{
    "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"
                    }
               ]
}

For a (slightly) longer introduction to JSON, please check out the following DigitalOcean article: An Introduction to JSON

A WDL file is, at a high level, a JSON object with three attributes: GAME, ROOMS, and ITEMS

{
    "GAME": …,
    
    "ROOMS": …,
    
    "ITEMS": … 
}

libobj

When a WDL file is loaded, all the JSON objects in that file are loaded into the object store, contained in ctx->obj_store

The main data structure in libobj is obj_t. The semantics are a bit different from JSON (which distinguishes between objects and values): in libobj, “everything is an object”. An obj_t can represent either an object or a value. The type field can be used to determine the exact type contained in an obj_t.

For example, suppose we have a WDL file that looks like this:

{
    "GAME": …,
    
    "ROOMS": …,
    
    "ITEMS": {
        "CHAIR": {
            "short_desc": "This is a chair",
            …
        },
        "TABLE": { … }

}

We could use the following code to retrieve the value of the short_desc attribute:

obj_t *o = obj_get(ctx->obj_store, "ITEMS.CHAIR.short_desc");

assert(o->type == TYPE_STR);

printf("ITEMS.CHAIR.short_desc: %s\n", o->data.s);

Notice how we can use the obj_get function to retrieve objects from the object store, and that we use a simple dot notation to specify the location of the object.

A shorter version of the above code is the following, which uses the obj_get_str function, which works if we know that the object we're retrieving is a string:

char *s = obj_get_str(ctx->obj_store, "ITEMS.CHAIR.short_desc"); 

printf("ITEMS.CHAIR.short_desc: %s\n", s);

You can see src/libobj/examples/wdl-example.c for examples of:

  • Accessing individual values
  • Iterating over all the attributes of an object
  • Iterating over all the elements of a list

Adding component-specific information to a WDL file

To add component-specific information to a WDL file, make sure you use a top-level object with a descriptive all-caps name. For example, a more complete WDL file could look like this:

{
    "GAME": …,
    
    "ROOMS": …,
    
    "ITEMS": …,

    "NPC": …,

    "BATTLES": …,

    "QUESTS": …,

}