In this assignment you will finish developing the text adventure game (TAG) that you began in A2. Although this handout provides some requirements regarding the functionality you should implement, many of the details are up to your team. If we left something unspecified in this handout, you are empowered to make your own choices about what to do. We hope you have fun making the game your own!

## Getting Started

There is no starter code provided for this assignment. Rather, you should begin with the code that you submitted for A2.

This assignment will not be autograded. You will demo your game in person to a TA. Hence there is no new makefile or make check. Passing make check is not a requirement for this assignment. Instead, your submission:

• must successfully compile,
• must pass your own test suite with make test,
• must successfully generate documentation with make doc, and most importantly,
• make play must successfully launch the game.

You are welcome to change any and all interfaces, to add new code, to link against libraries of your choice, etc. If you do add new compilation units, you will need to list them at the top of the Makefile to ensure they (and their documentation) are built correctly. If you link against new libraries, you will need to add them to _tags and .merlin. And both new compilation units and new libraries could require you to modify .ocamlinit.

To be clear, there is no need at all to link against new libraries, and most people will not. But it is a possibility.

## Step 1: Team Maintenance

1. Print out one copy of the Evaluation of Progress form, and fill it out together. Do your best to have a forthright and professional conversation about any issues that surface. If something comes up that you’re not sure how to handle, please talk to your TA to get their advice. You do not need to submit your form to CMS.

2. Assign new roles for this assignment. Make sure to give everyone a different role than they had in A2. Please note that the checker role has been updated to include additional responsibilities.

## Step 2: Finish A2

If there’s anything your team didn’t finish in A2, begin A3 by finishing it now. In particular, your A3 solution must provide the “go” and “quit” verbs, and a user interface, and be capable of loading adventures from data files.

Here are a couple definitions to recall from A2 for the rest of this handout:

• Verbs, objects, and commands: A player command is of the form “VERB OBJECT”, where the verb is a single word, and the object might contain several words.

• Data driven: The responsibility for implementing the game is factored between the game engine, which defines the verbs, and the adventure file, which defines the objects.

## Step 3: Gamify

Arguably, what you built in A2 is not yet a game, because there is no notion of winning or losing, or of comparison to other players. Add functionality to your software to make it a game, as follows.

Introduce a notion of score to your game. A player’s score should be based on which rooms they have visited, and possibly other factors (which we leave up to your choice). Each room should be worth some number of points for visiting. Moreover, the adventure file should specify the number of points for each room, meaning that each room can be worth a different number of points from all other rooms. In other words, the number of points any room is worth should be data driven, not hardcoded. You should provide a “score” verb to display to the player their current score.

Implementing this will require:

• extending your program with a new verb, “score”, as well as functionality to compute the player’s current score.

We leave the exact rules for scoring up to you, as long as they satisfy the above requirements.

Create your own adventure by constructing your own JSON file. It may not be based on any sample files we have already given you. We encourage you to create an interesting and creative adventure! But your grade won’t be based on that. Instead, we simply require that it have at least five rooms.

Then create a second sample adventure. This one may be quite small and minimal. The point of this step is to demonstrate that your game engine is data driven and does not hardcode objects (i.e., rooms or their points).

The names of both sample adventure files must end with .json.

This is the stopping point for a satisfactory solution.

## Step 5: Items

Adventure games usually involve items that the adventurer can move between rooms. For example, in the Colossal Cave adventure, the player’s goal was to collect all the items and put all of them in a designated room, making it a kind of treasure hunt. In Myst, the player’s goal was to collect missing pages of books, and to put those pages into the books.

Extend your game engine and your sample adventure with the notion of items. Your main sample adventure should contain at least three items. It should be possible for the player to issue commands that cause the adventurer to move items between rooms. The interface should display helpful acknowledgments and error messages for those commands. Moreover, the player’s score should in some way be dependent upon which room each item is located in, and each item should potentially be worth a different number of points than all other items. Finally, there should be some winning condition based on the items and their room locations that causes the engine to notify the player that they have won the game. We leave the exact design of these commands and rules up to you.

The items in your game should be data driven—that is, every item should be defined by the adventure file, not by your source code. The types representing items, of course, will be defined in your source code.

On the other hand, the new commands that you introduce will involve new verbs, and those verbs—like “go” and “quit” and “score”—should be hard coded.

As a suggestion, here is one way to satisfy the above requirements:

• Extend adventure files to have an array of items, each of which has a name, starting room, and number of points that it is worth.

• Modify the interface to display the items currently located in a room whenever the room’s description is printed.

• Add “take”, “drop”, and “inventory” commands. The command “take <item name>” would transfer an item from a room to the adventurer’s inventory, and “drop <item name>” would do the opposite. The “inventory” command would display the items currently carried by the adventurer.

• Extend adventure files to designate a treasure room.

• Modify the computation of the player’s score to add points whenever an item is in the treasure room.

• Modify the interface to print a “win message” when all items have been dropped in the treasure room. The win message could be hardcoded or come from the adventure file.

This is the stopping point for a good solution.

## Step 6: Augmentation

Thus far, the gameplay of our adventures does not involve very much adaptation to what the player does. Let’s make the gameplay more interesting by making it dependent upon the state of the game.

Pick one of the following three game augmentations, implement it, and extend your sample adventures to demonstrate it:

• Doors, locks, and keys: The exits from rooms can be blocked by doors, which can be locked, unlocked, and relocked. Items can be used as keys to unlock doors and pass through. Each door can have its own individual key. This adds additional challenge and interest for players.

• Dynamic descriptions: The description of a room depends upon what items are located inside it, what items are in the adventurer’s inventory, and whether the player has visited the room before. That enables the game to adapt to player actions in a way that feels natural.

• NPCs (non-player characters): There are other characters in the game with which the player can interact, have dynamic conversations, and get items. This augmentation is likely to be the most difficult.

As before, verbs may be hardcoded, but objects should be data driven. For example, which key opens which lock would be determined by the adventure file, but verbs such as “unlock” or “use” would be hardcoded. Likewise, dialogue would be data driven, but the “say” verb would be hardcoded.

You might consider commands that have indirect objects, such as “use <object> with <other object>” or “say <phrase> to <character>”.

If you implement two of the three augmentations, you will receive a small bonus. Implementing all three will not result in any additional bonus, though you are welcome to do it.

## Scope

Here’s what we consider a satisfactory, good, and excellent solution:

• Satisfactory: The solution submitted to CMS compiles. The REPL launches with make play. It implements the “go” and “quit” verbs required by A2, and it implements the scoring requirements above.

• Good: The solution additionally implements the items requirements above.

• Excellent: The solution additionally implements at least one of the augmentations above.

Regardless of the level of scope, two sample adventures should be provided that demonstrate all of the implemented functionality.

## Documentation and Testing

Documentation for this assignment will be graded as in A2: the grader will look at the public and private documentation generated by make doc. If that command cannot be executed, the grader will give you a score of -1 for documentation. So be sure to test it yourself.

Testing will be graded by checking that you have unit tests for each verb that you add to the game. For efficiency, graders will not investigate each .mli to make sure you have unit tests for every function—though for your own sake, you probably should. If you do not pass your own test suite with make test, the grader will give you a score of -1 for testing.

## Submission

Make sure your team’s NetIDs are in authors.mli, and update the hours_worked variable at the end of authors.ml. That should be the hours you spent after submitting A2. Please do not include the time you worked during A2. That is, the sum of your hours worked in your A2 and A3 submissions should represent the total time you spent working on the entire game.

Ensure that your solution compiles and passes your own test suite. Run make zip to create a zipfile to upload to CMS. Somewhat misleadingly, the name of that file will be a2src.zip. That’s our fault; we weren’t thinking far enough ahead when we created the makefile for A2. (You could fix the zipfile name in the makefile if you wanted, but it’s not necessary.) You’ll be just fine uploading the file to CMS regardless of whether it’s named a2src.zip or a3src.zip. Your zipfile must contain all your OCaml source files ( both .ml and .mli), your two sample adventures, and _tags and Makefile. The make zip command we provided in A2 will automatically do that for you, so please use it rather than any graphical tools.

Submit your zipfile on CMS. Double-check before the deadline that you have submitted the intended version of your file.