Professional Documents
Culture Documents
_______________
A Capstone Report
_________________________
_______________
In Partial Fulfillment
Bachelor of Science
in
Computer Science
_______________
by
Summer 2021
D’Orazio, James, Oakes 2
Copyright © 2020
Executive Summary
The project was designed for the development of a video game which implements
features that have been previously unexplored in interactive fiction games. Along with many
recognizable features from previous text-based adventures, this game will also have a unique
system for casting magic spells. The setting for Lair of the Forgotten Beast will be a fantasy
world that includes a hero, monsters, and magic. The main goal of this project is to highlight the
new magic features and offer the client an improved experience over previous designs done by
After many years of interactive text adventures, the genre now has a game that is more
complex in its magic spell system. pts to use a magic spell during gameplay, a text entry is
required. For example, “Cast Fireball on hobgoblin”. A canned response is usually set up to react
to this text input with very little function. This method of magic is simplistic to a fault. The
interactive fiction products rarely expand on the magic spell casting that make fantasy game
settings so interesting. This project will attempt to address this issue in a way that creates a very
Table of Contents
Executive Summary 3
Table of Contents 4
List of Figures 6
Background and Approach 7
Introduction/Background 7
Project Name and Description 7
Problem and/or Issue in Technology & Solution to the Problem and/or Issue 8
Evidence that the Proposed Project is Needed 9
Project Goals and Objectives 9
Stakeholders and Community 10
Feasibility Report 11
Design Requirements 12
Functional decomposition of the project 12
Command Line Instruction Execution 12
Object Creation using Abstract Factory Pattern 14
Selection of design criterion 17
Final Deliverables 19
Approach/Methodology 19
Ethical Considerations 20
Legal Considerations 20
Final Report 21
Timeline/Budget 21
Usability Testing/Evaluation 22
Final Implementation 24
Abstract Factory design pattern 24
Command Line 26
Discussion 29
References 31
Appendix A 32
Usability/Evaluation Test Plan 32
Usability Test Post-Survey 32
Appendix B 35
D’Orazio, James, Oakes 5
Team Members 35
Appendix C 36
Client/Focus Group Feedback 36
Introduction 36
Focus-Group Testing 39
Form Q&A 40
Appendix D 45
Client-Side Javascript 45
Appendix E 46
CommandInterpreter Code 46
Appendix F 48
CommandDictionary Code 48
D’Orazio, James, Oakes 6
List of Figures
Figure 8: Get Method for Retrieving a Lambda Within the CommandDictionary Class 27
PART I
Introduction/Background
This project is called “Lair of the Forgotten Beast”, and is a text-based fantasy adventure
A blinking cursor greets your black screen. What do you do? “Start Game”. You hear
what sounds like an airplane as the mainframe draws more power. White text begins to scroll the
screen.
46 1090 40 45 205
DO YOU WANT TO (1) STOP AT THE NEXT FORT, (2) HUNT, OR (3) CONTINUE
?3
Text-based computer games have been around since the 1960s where they could be
played on University, and Business mainframes. Many of the original mainframe games have
been lost to time, but a few have lasted. You may not be familiar with the text output above, but
you’ve probably played or at least heard of the game it came from; The Oregon Trail will be half
a century old as of this year, yet it is still being remade for mobile devices today.
While the rise of point and click games started the downfall of text-based games, and led
to the AAA games we play today there is still a spot for those old text games in the modern
culture. Recently A Dark Room hit number one in the app store and the modern text-based game
grossed over $800,0001. This shows that text-based games are still relevant today. It's unclear
why the game gained such popularity. The Artifice states, “many [text-based games] offer
While creating the project, “Lair of the Forgotten Beast”, we did just that: bring
something entertaining, new, and fresh to the history of text-based games. Our game is an RPG
text-based adventure. The player plays through the story of falling into a cave when the ground
beneath their feet collapses. Introduced to a rarely seen part of the world the character lives in,
the player must find their way to safety. During the hero’s journey, they will need to overcome
many challenges. This ultimately leaves the character with a new perspective of the world once
they return.
Problem and/or Issue in Technology & Solution to the Problem and/or Issue
Art enriches people’s lives and improves their quality of life. With the fast-paced bustle
of life, it’s more important than ever to take time to enjoy art. Video games such as ours compose
D’Orazio, James, Oakes 9
a unique art form which not only provides entertainment and enrichment but can also help
There are other games that exist which are similar to Lair of the Forgotten Beast, each of
which has its own issues. We produced a game which solves some of the existing issues with
related games, serving as an improvement over existing games. We took a new approach with
our new magic system that will combine ease of use for casual players with complexity.
The main goal in developing The Lair of the Forgotten Beast was to create a text
adventure game that would be received well by an audience. The game had to be able to perform
all the common functions of an interactive fiction piece, and also implement new features unique
to the project. Another long-term goal of the project was to design and implement a new magic
During this project, there were several objectives timely ordered to meet weekly goals.
The project began with basic building blocks of the program; Pivotal Tracker was set up first, a
project was created, and a GitHub repository was made, and weekly work was being tracked on
the Kanban cards within Github. After the skeleton of the project was laid out, we began adding
features. The first feature we added was a grid map in Java which served as an abstraction for the
fantasy game setting, specifically the locations the player can visit. Unit testing was included as a
creatures, magic, and items were listed and implemented. Once enough data was accumulated,
work began developing the services and methods that support these objects. More objects were
added later after some proof of concept was completed with the initial portion of data. Data
structures formed the infrastructure that supports all of the program objects that are processed
using Java Spring Boot controllers and classes. Then, the game map was populated with Java
objects that represent places, people, creatures, items, and spells. It is in this phase that the new
magic system was implemented. After all Java classes and methods were unit tested, the team
increased the scope and complexity of the game. The game was considered finished when the
team carved out the entire game world and verified the functionality of all the components in
end-to-end testing.
The stakeholders on this project were the developers and end users. The project was
The first developer was motivated to create a properly advanced magic system, and
would gain from creating the system he always wanted introduced into a text-based game. He
also benefited from the experience of working on a project of this scale as well as game design
experience.
The second has career plans to become a game developer, and this project helped him to
get experience in the field. Creating the Lair of the Forgotten Beast was the first step in building
The last developer, having never played a purely text-based game before, has gained
Feasibility Report
As the project team scanned the environment, other interactive fiction games were
examined. Some of the features that existed in the older games were important enough to
consider in Lair of the Forgotten Beast. The use of directional navigation text such as “north”,
“n”, or “go north” were recreated. This is a nod to games produced in the 1980’s like Zork (Zork
verb-noun combination allowed the team to continue some of the features that made those old
games so easy to play. Other resources including articles from the internet were examined and
compared with the features that were planned. This game was designed to be unique among a
decades-long community full of text-based adventures. One of the main databases for finding
interactive fiction works is called the Interactive Fiction Database or IFDB (The Interactive
Fiction Database, 2021). This site was designed to archive all of this genre in one place with user
reviews and ratings. The games and the reviews given to them offered a lot of insight into what
made a game that interactive fiction enthusiasts prefer. The Lair of the Forgotten Beast will join
The spell and magic system in the older games like Adventure were mostly shallow and
lacked complexity. In this project, a new form of casting spells was introduced. Spells,
components, runes, and item enchantments were all considered and experimented with in the
design process. After some deliberation about how to do it, magic words are discovered
throughout the game world. Combining specific magic words can be used to cast spells with
different effects that the player must learn through some trial and error.
To create a set of room items and creatures, a factory design pattern was introduced to
populate the map. The factory pattern allows for the game to implement a randomization system
D’Orazio, James, Oakes 12
for map generation. This will result in a better user experience over the older games, which used
a static map each time a new game was created. During the development process, statically
PART II
Design Requirements
Lair of the Forgotten Beast is a text-based game that relies on user input through a
console input window. This gives the game the daunting task of having to parse the user's input
into usable strings that can then be interpreted by the program to run specific commands. Our
game uses the same noun-verb system that older text-based games do. The system architecture
starts at the command line console window. When the user enters a command the Home
Controller routes the instructions to the Game Service and provides a ResultObject object for
which the returned UI (User Interface) feedback is packaged up for displaying back to the user.
The Game Service creates a new Command Tokenizer, Command Interpreter, Command
Dictionary, and Static World Map to hold the player's current game world instance.
D’Orazio, James, Oakes 13
The Command Tokenizer was created to be the first step in parsing inputs. Sentences are
to be provided by the user, then the Command Tokenizer separates out individual words in a list
format for easy processing by the Command Interpreter. With the user input already parsed into
separate words the Command Interpreter has the job of reading the words and determining how
the user’s instructions should be handled. The Command Interpreter, working in concert with the
Command Dictionary, determines which command path the user instruction will take. The
Command Dictionary, which sets up the valid command routes the instructions can be processed
through, is passed the parsed command. If the first word in the instruction maps to a valid
command route, the Command Dictionary wraps up a lambda function with the path to take and
sends it back to the Command Interpreter. It is up to the Command Interpreter to handle any
errors and redirect the instruction to a different route, a default route, if needed. With an
established instruction route the ICommand functional interface’s call method is invoked. The
ICommand interface is used in the manner a railway switch is used. The Command Interpreter
and Command Dictionary determined the route and now it is up to the ICommand Interface to
unify the command calling process to make sure each command goes to where it needs to be
processed. Fourteen commands and the ability to save and re-execute the last command
The way commands are currently being handled can be expanded for new routes when
necessary, by simply implementing a new command class off of the ICommand interface and
D’Orazio, James, Oakes 14
This game has multiple creatures and room items that require many individual instances
of functional response. In the process of creating Lair of the Forgotten Beast, there was a need
for efficient creation of numerous objects in the game. This game application uses a software
design creation pattern called “factory”. This pattern is used more than any other in Java. The
factory is considered the top way to create a Java object, because it does not reveal the creation
logic associated with private code. Instead of pointing to a concrete class, the client service refers
to a newly created object using a common interface. Depending on what parameters are supplied
to the factory methods, a different type of creature or room item will be generated by the same
factory method.
The program executes the object creations from its map domain functions
called using parameters similar to “name”, “description”, or “attack damage”. A call to a java
method is made to get the values that are stored in these fields and a different set of methods is
used to overwrite them. In the diagram below, the abstract factory named
From the CreatureFactory, a creature class can call one of several types of creatures. For
room objects, they are referred to in the project as “props”, which can be any object inside a
room that is not a creature object. The factories can be used to create custom versions of existing
creatures or props by changing the input parameters to the factory methods. The diagram above
shows the abstract class called Creature downstream from the CreatureFactory, and has multiple
In the beginning, the team wanted to build a video game. This was the first known
requirement to be written down and recorded. Following that initial request, numerous other
tasks were created to complete the project. There were many details to figure out, and technology
helped to organize work. When crafting Lair of the Forgotten Beast, the team manufactured
several user stories that would eventually shape the entire program. The user stories quickly
became functional requirements that held together the entire user experience. In Figure 1 below,
User stories are typically set up as a way to track functionality in a non-technical way.
They clarify the reason for the functionality in the first place. The stories should be a reminder of
what was discussed, but not necessarily every small detail. In this case, the stories were able to
help the team develop ideas on boilerplate java code so that the program would execute the
stated tasks within each story. The technical mandates that come from the user stories eventually
found their way into the Github project card system. Below is a picture of the Github project
cards.
The cards represent technical tasks in various states of progress. The first column is an icebox,
which works in a similar way to the icebox found in Pivotal Tracker. The second column is the
To Do list. This has all of the tasks that are currently waiting to be accepted. The third column is
the In Progress area. This column is used for any tasks that are currently being worked on.
Finally there is the Done column which is where an In Progress card will go once it is completed.
D’Orazio, James, Oakes 19
Final Deliverables
For the final deliverables on the project, the team has created a functional video game
written in Java and JavaScript. The backend uses Spring Boot and the game is being deployed on
a Heroku server. The team has also conducted a first round of acceptance testing requiring a
small focus group, five test subjects, playing the game in a one-on-one testing session with a
developer present and completing a usability feedback survey at the end of the subjects’ game
playthrough.
Approach/Methodology
The team used an Agile methodology for software development. The tasks were divided
into three time-boxed two-week sprints. During each sprint, the team would look at both the
Pivotal Tracker user stories and the small changes that were recorded within the Github project
page. On the project page, one was able to write task cards and assign them to an appropriate
column such as “Done”. Many of the complex changes were solved in user stories, as they
typically required multiple services to be configured in specific ways before they can be
considered done. In Pivotal Tracker, the user stories would be gathered, evaluated for priority,
then classified into weighted points. These points could then be applied to the next iteration to
better determine how to time-box the task. Three tasks that are worth one point will take the
same time to complete as a single task worth three points. Going through these evaluation steps
Ethical Considerations
Ethical concerns played a role in the choices that were made when building Lair of the
Forgotten Beast. The first concern was that this game would cost too much to play. It was
decided that the game would be free to play since the team believed that everyone should have
the opportunity. There are some games that are free to play, but also have microtransactions. Lair
The use of violent or sexual content was never something that the team had thought about
including in the game. There are some fantasy role playing games that include violence or
sexuality. This game was not one of those, and depicts combat in a non-sensationalized manner.
The team understands that our game can be played on any device that has a web browser, and
children could find it. The game is completely safe for young children to play and contains no
objectionable material.
The testing done on this project was also done with awareness of rules and ethical
concerns surrounding the use of human subjects. The development team was able to secure five
live test subjects from a focus group, which had received prior approval from the Committee for
Legal Considerations
Legal considerations for video game development influenced where boundaries were for
what the team was allowed to create. The work done in this game was original. This project
obeyed the copyright laws within the United States. No images, scene images, settings,
dialogues, or music that has been produced and copyrighted was used in Lair of the Forgotten
PART III
Final Report
Timeline/Budget
The video game, Lair of the Forgotten Beast, was created under a strict deadline of six
weeks. Under this deadline the game development life cycle was set up to include three back to
back agile style sprints of two weeks each. To keep this fast pace, a schedule was created to keep
the developers on track. In the first two week iteration, the initial set up would be completed.
Initial setup involved creating a Github repository, Pivotal Tracker account, a Heroku pipeline,
the webpage routing system, and a command line interface for users to enter text into. Work on
game movement and basic mechanics would begin in development and go through to the next
iteration. In iteration two game mechanics would be added to the game to parse commands, fill
rooms with items and monsters, and create an inventory system for the players to hold objects as
they interacted with the fictitious world that is the setting of Lair of the Forgotten Beast. With the
first two iterations done, the last iteration would begin to introduce the main feature targeted with
this game. Introducing a more complex magic system than other games were able to provide had
always been the focus of the game. As the magic system developed, so too would the combat
system. Lastly, in this final iteration the team had to begin game testing by gathering game
The budget for Lair of the Forgotten Beast was initially set to a total of $4 to host the
Heroku pipeline in a non-personal account for the added features doing so would make available.
The team only exceeded this budget after the game's conclusion when creating the video and
D’Orazio, James, Oakes 22
slides necessary to present the project at the Capstone Festival. Two of the developers incurred
another $20 cost each for special features in the slides. One cost was to include an AI voice to
automate reading the slide scripts over the video. The second of the costs was to include icons as
graphics on the slides. An account at iconfinder.com was paid for to get access to icons that had
suitable commercial use licenses that would legally help the team avoid incurring copyright
Usability Testing/Evaluation
In week six of the video game’s development cycle the team began user testing. The team
had previously consulted friends and family members, along with other Cal State Monterey Bay
students within the same cohort, to build a list of potential testers for each of the game’s features.
Lair of the Forgotten Beast’s game developers reached out to the pool of potential testers and
received five responses. At this point the developers scheduled one-on-one meetings with each of
the testers where a single developer would sit through a game playthrough and listen to any
feedback or concerns the testers could provide. During the playthrough the developers took notes
which were used to make game changes to address the concerns of the testers. At the end of the
playthrough session the testers were asked to complete a survey (see Appendix A) to create a
concrete record of what they thought of the game’s design. The results of the survey indicated
that improvements were needed to bring the game up to the users standards.
The survey responses (see Appendix C) indicated that all the testers had previously
familiarity with Interactive Fiction or Text Adventure games in the past. Generally consensus
between the testers state that Lair of the Forgotten Beast fell below an average difficulty to use
rating indicating that most testers found the game difficult to use as it was when tested. Concerns
leading to this rating include that the code for the user login/sign up page had not been fully
D’Orazio, James, Oakes 23
merged into the project before the testers received the playthrough, the magic system was not
well documented for the players to know that it existed without being told about it from the
developers, and no game over sequences had been created. One tester responded to the survey
stating, “I did not know you could cast magic. I am IMMORTAL (-850/100)!”. The last part of
the statement shows he was able to still play the game when his character’s health points had
fallen into extreme negative values. Even with survey responses generally stating that the game
needed more improvements, all but one of the testers indicated that they would play Lair of the
After the testing phase was completed the development team immediately began trying to
address the feedback in what few days they had left before the final Capstone deadline. Almost
all the testers' concerns were addressed, while a few concerns of both the testers and developers
were unable to be resolved in the time period given. The final project being presented for the
Capstone presentation includes bug fixes to allow user login and signup options, along with
scrolls intended to aid the players solve the final boss riddle, an introduction to the magic system
early on in the game, and making user inputs non-case sensitive. Concerns that were not able to
be addressed at the time of this writing would have involved creating story content to make the
Final Implementation
The final implementation of the project uses a creation design pattern used in the
generation of game objects. The abstract factory pattern was able to create as many in-game
objects as the team needed. The creatures and room objects could be instantiated without specific
D’Orazio, James, Oakes 24
parameters or with all constructor fields specified. The game started with only a few objects for
testing. Once more game rooms were created, additional objects were added. This worked well
while the team had not yet developed the combat system. In the second project sprint, the
complexity of the objects changed as additional fields were introduced like attackDamage. The
Java classes used in the program to generate the creatures were then modified to create specific
creatures with predictable equipment in their inventories. For example, a hobgoblin cultist would
always be generated with a bronze sword if no other parameters were passed to the function.
Alternatively, the game can call the CreatureFactory function specifying a hobgoblin with a
Here is a code snippet from the AbstractCreatureFactory and the CreatureFactory files:
package LairOfTheForgottenBeast.factory;
import LairOfTheForgottenBeast.domain.map.rooms.RoomDynamic;
import LairOfTheForgottenBeast.domain.prop.Item;
Command Line
Our initial design for the command line interface involved setting up a HTML form
consisting of a single text field to enter a command and submit a POST request to a route on the
server.
In the server route, the command string is passed from the client into a CommandTokenizer class
which parses the command from a space-delimited String to a List data structure that represents a
list of words in the command. Then, the list of command words is passed to a
CommandInterpreter class (see Appendix E) which checks the beginning of the command to
identify which command should be executed. For example, in the case of “examine torch”, the
first word, “examine” corresponds to the “examine” command. The CommandInterpreter uses
the first word as a lookup key within the CommandDictionary (see Appendix F), which is a
HashMap that holds a string as a key to get a lambda to the desired command class logic.
Figure 8. Get method for retrieving a lambda within the CommandDictionary Class
D’Orazio, James, Oakes 27
The CommandInterpreter gets handed back the lambda which it then uses to call a
functional interface called ICommand. ICommand allows any class that implements its interface
to have an attached call function that will determine a command's behavior in a unique way for
that class.
package LairOfTheForgottenBeast.domain.commands;
import LairOfTheForgottenBeast.domain.CommandInfo;
import LairOfTheForgottenBeast.domain.GameState;
One challenge that the developers encountered during the design phase was the fact that
the client web page was going to refresh each time the player entered a command. This meant
that a history of commands and command output could not be kept on the console page as
planned. In order to solve this, the developers wrote client-side javascript which handles form
submissions and HTML requests using AJAX; then, upon receiving the response from the server,
the javascript uses JQuery to update the client page (see Appendix D).
One of the biggest problems that came up during the implementation phase was a
problem with the github repository that rendered the game unplayable until it was fixed. This
issue occurred because Kyle (see Appendix B) did not correctly communicate with the rest of the
D’Orazio, James, Oakes 28
team that they were editing several files. What they should have done was create a kanban card
in the GitHub project board (and possibly open an “issue”) in order to fulfill the communication
guidelines established by the team to prevent issues like this. Another team member, Brian (see
Appendix B), worked on the same files during the same time period. The edits made by the two
developers were not compatible and resulted in many severe merge conflicts. One of the
developers spent several hours resolving the merge conflicts, then merged the pull request. Once
In order to repair the application, after attending a meeting with the other team members,
Kyle attempted to roll-back the latest pull request by branching off from main “reverting” the
pull request in the new branch. He then merged Brian’s pull request and resolved any issues, then
attempted to merge Kyle’s pull request; GitHub would no longer merge the commits that had
been reverted, and so the main branch remained broken. Kyle and Brian met in a video
conference, shared screens, and manually integrated Kyle’s code into Brian’s local branch. After
this, Kyle met with Nick (see Appendix B) to integrate this newly-stable version of the project
into Nick’s branch, which Nick then used to override the main branch. This had to be done by
Nick, because he originally set up the GitHub repository and was thus the only one who could
directly modify the security settings to allow overriding main. Once main was overridden, the
project was stable and the developers could once again work on it asynchronously.
Another problem that came up during the implementation phase was the database
connection limit. In our development testing, the team ran into this issue on multiple occasions
The project was not rolled out for permanent use by users because although it is a
playable game, it is missing a lot of balancing and polish. At this point, the project is released in
D’Orazio, James, Oakes 29
“early access” and can be accessed and played at a specific URL, but it does not have an official
full release yet. Currently, only a few users can access the game at once without crashing it. This
is because of the current limit to the number of database connections. This limitation is due to the
current database setup, which works with a free database meant for small-scale projects, but
which can be scaled by purchasing upgrades. The biggest upgrade that would be necessary in
order to support more players would be to upgrade the database to support more connections.
Additionally, increasing the number of dynos would improve the stability and scalability of the
application. This can be done smoothly in Heroku by paying for these upgrades.
Discussion
As stated in the final implementation section, the developers learned several new
programming concepts and implementations, including the Abstract Factory design pattern used
in the generation of game objects, command line interfaces, and some functional programming
techniques using lambdas. We first designed the command interpretation code in such a way that
The developers also learned the importance and difficulty of balancing planning and
implementation within such a limited timeframe; this was particularly pertinent when
considering quick implementation of features versus robust and scalable design. On the one
hand, it was important to spend time planning and implementing solutions in robust, scalable,
and easily-debuggable ways; on the other hand, there was often insufficient time to perform
thorough planning, and it was sometimes necessary to sacrifice code quality in favor of speed of
An idea which the team had not considered before the project but ended up implementing
in the game is the client-server architecture where the server waits for user input from clients in
order to update the game state and send a response back to the client web page, which should
then update to reflect the results of the changed game state without refreshing the page. Most of
the video games that the developers were familiar with prior to the project utilized what is known
Beast. Almost all video games use a game loop, particularly real-time games such as action
References
https://www.mobygames.com/game/adventure-1
https://info.legalzoom.com/article/copyright-laws-and-video-games
Failory.com. (2018). A Dark Room: From Sabbatical Year to $800,000. [online] Available at:
Interactive Fiction Database. (2021). Retrieved from The Interactive Fiction Database:
https://ifdb.org/index
The-artifice.com. (2015). The Text Adventure: Relic of Gaming History, or Timeless Medium? |
Appendix A
After the first two project sprints, the development team sought out people to test the
game and provide feedback. A Heroku application was created to get play feedback from the
testers. A schedule of appointment slots controlled who would reserve the application during the
third sprint to keep the game instance refreshed for each player tester. Each of the five people
were given instructions to create an account on the game application web page and start playing
the game. After each person completed their session, they filled out a usability testing survey
with written feedback. The survey was provided to testers via Google Forms and included
questions related to the intuitiveness of the user interface and game mechanics, the presence or
https://docs.google.com/forms/d/16jmjZkgwLpXv_jhXi5uvVDyrBGw1bNWtZ5Rud2uvO84/edit
D’Orazio, James, Oakes 33
D’Orazio, James, Oakes 34
D’Orazio, James, Oakes 35
Appendix B
Team Members
The team members on this project are Brian James, Nick D’Orazio, and Kyle Oakes. The
team did not assign specific tasks to specific members of the team. Instead, the team utilized an
agile software methodology with a kanban-style task list and each team member volunteered
time to the most current or prioritized task in this “To Do” list. The team collectively populated
Pivotal Tracker and the GitHub project board with user stories and other technical tasks. Each
member of the team was able to claim tasks listed on “To Do” list kanban cards in order to work
asynchronously. In addition to this work, the team held regular meetings at various times in live
video conferencing. These sessions would include live coding with collaboration or planning the
next tasks to work on. The end of a week always included a live session where the team would
update the project report page together and close any remaining tasks that were time-boxed for
that week.
D’Orazio, James, Oakes 36
Appendix C
Introduction
1. What is your target audience? (age, occupation, interests, comfort level with technology,
etc.)
We split the demographic groups into a number of years as 21 or under, 21 to 35,
and 35 and over. The target audience were people who may have played interactive
fiction games at some point in their life.
Target audience:
● Age: 21 and over.
● Occupation: Any occupation.
● Interests: fantasy role-playing games, interactive fiction
● Comfort level with technology: moderate comfort level
2. Who will be testing your project? If you have a focus group, please state everyone's
names (first names okay) and describe how they fit your target audience demographics.
Otherwise, just do this part for your client.
All testers are over the age of 21. Three are between 21-35 and two are over 35,
making an approximately even spread between the two age groups asked. All the
respondents have previous familiarity with Interactive Fiction or Text Adventure games.
3. What are the main tasks you would like your client/group to be able to complete while
testing? Your tasks should be specific and measurable (i.e. Can they sign up and log in?
Can they navigate to one specific part of the site? Are they able to play through the first
level of the game?). To get good feedback, you should have 3-5 tasks to test them on.
Christopher Fey:
1. Log into the game from menu.
a. Success
2. Check command usage from within the game options
a. Success
3. Move between rooms
a. Success
4. Find items and add them to inventory
a. Success
5. Use combat actions – either weapon or spell attacks
a. Success
6. Find the ending room.
a. Success
7. Solve the riddle
a. Success
Dan Sedano:
1. Log into the game from menu.
a. Success
D’Orazio, James, Oakes 38
Focus-Group Testing
1. Although called a focus group, you can have one person test at a time. That is up to you
and your project. You should have at least 3 people in your target audience test your
product.
D’Orazio, James, Oakes 40
2. Set up a meeting(s) with your group to go over your work. This should ideally be
face-to-face so you can get their initial reactions and see how they navigate your product
in real time. If they test on your device, you may also be able to record your screen and
audio to capture their test to review later (with their permission). Other good alternatives
would be to have them share their screens over Hangouts, zoom, etc. while testing or
have them record themselves using the product and narrating what they're doing.
a. We set up individual meetings with each of our 5 testers.
3. Report on their feedback. Were they able to complete all of the tasks? Did they get stuck
along the way? What will you do to improve your project in the short term before the
festival? In the long term?
a. The signup and login pages were crashing, so Roman Baca and Chris Johnson
used the dev Kyle’s login credentials.
b. Many testers were stuck in figuring out how to cast spells. This was due to a lack
of in-game documentation and tutorialization for the magic system as well as an
overly strict spell-string interpreter with rigid word order.
Form Q&A
Link to form:
https://docs.google.com/forms/d/16jmjZkgwLpXv_jhXi5uvVDyrBGw1bNWtZ5Rud2uvO84/edit
D’Orazio, James, Oakes 41
D’Orazio, James, Oakes 42
D’Orazio, James, Oakes 43
D’Orazio, James, Oakes 44
D’Orazio, James, Oakes 45
Appendix D
Client-Side Javascript
function submitCommandForm() {
let isMultiplayer = $("#multiplayer").is(":checked");
let commandString = $("#input-window").val();
let username = $("#username").val();
lastCommand = commandString;
$("#console-screen-text").append("\n"+">"+commandString);
$.ajax({
type: "POST",
url: "/console",
data: {
commandString: commandString,
username: username,
multiplayer: isMultiplayer
},
success: function(resultObject) {
$("#console-screen-text").append("\n"+resultObject.commandOutput+"\n");
scrollConsoleDown();
updateLocationInfo(resultObject.locationInfo);
clearInputField();
updateMinimap(resultObject.mapDims, resultObject.playerCoords);
updatePlayerHp(resultObject.playerCurrentHp,
resultObject.playerMaxHp);
updatePlayerEquipment(resultObject.playerWeapon);
updatePlayerInventory(resultObject.playerInventoryItemNames);
},
error: function() {
appendError();
scrollConsoleDown();
updateLocationInfo();
clearInputField();
}
});
D’Orazio, James, Oakes 46
Appendix E
CommandInterpreter Code
package LairOfTheForgottenBeast.domain;
import java.util.ArrayList;
import java.util.HashMap;
/* Non-static Imports */
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
CommandDictionary commandDictionary;
firstCommand);
try {
firstCommand = cmdArr.get(0).toUpperCase();
lastCommandUsed = cmdArr;
lastCommandUsedMap.put(username, lastCommandUsed);
} catch (IndexOutOfBoundsException e) {
// Do nothing...CommandDictionary has mapping for empty string.
// TODO: This is where repeat last command could go.
if (!lastCommandUsedMap.containsKey(username)) {
ArrayList<String> newLastCommand = new ArrayList<String>();
newLastCommand.add("help");
lastCommandUsedMap.put(username, newLastCommand);
}
lastCommandUsed = lastCommandUsedMap.get(username);
firstCommand = lastCommandUsed.get(0).toUpperCase();
cmdArr = lastCommandUsed;
System.out.println(lastCommandUsed);
}
}
}
D’Orazio, James, Oakes 48
Appendix F
CommandDictionary Code
package LairOfTheForgottenBeast.domain;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import LairOfTheForgottenBeast.domain.commands.Answer;
import LairOfTheForgottenBeast.domain.commands.Attack;
import LairOfTheForgottenBeast.domain.commands.Consume;
import LairOfTheForgottenBeast.domain.commands.Drop;
import LairOfTheForgottenBeast.domain.commands.Equip;
import LairOfTheForgottenBeast.domain.commands.Examine;
import LairOfTheForgottenBeast.domain.commands.Go;
import LairOfTheForgottenBeast.domain.commands.Help;
import LairOfTheForgottenBeast.domain.commands.Inventory;
import LairOfTheForgottenBeast.domain.commands.Invoke;
import LairOfTheForgottenBeast.domain.commands.Look;
import LairOfTheForgottenBeast.domain.commands.Say;
import LairOfTheForgottenBeast.domain.commands.Take;
import LairOfTheForgottenBeast.domain.commands.Talk;
import LairOfTheForgottenBeast.domain.commands.Unequip;
/**
* A dictionary of all the mapped commands for the game. Used to filter
user input.
*
* @author Nick D'Orazio
* @version 1.0.0
* @since 1.0.0
*/
public class CommandDictionary {
/**
* A map of all the verb commands for the game.
*
* @see List
D’Orazio, James, Oakes 49
* @see BiFunction
* @see Map
*/
Map<String, BiFunction<GameState, CommandInfo, String>>
commandDictionary;
/**
* Building the dictionary and putting all the commands in it
*
* @since 1.0.0
*/
public CommandDictionary() {
commandDictionary = new HashMap<>();
commandDictionary.put("", (gamestate, command) -> {
return "Enter a command";
});
commandDictionary.put("HELP", (gamestate, command) -> {
Help help = new Help();
return help.call(gamestate, command);
});
commandDictionary.put("?", (gamestate, command) -> {
Help help = new Help();
return help.call(gamestate, command);
});
commandDictionary.put("GO", (gamestate, command) -> {
Go go = new Go();
return go.call(gamestate, command);
});
commandDictionary.put("LOOK", (gamestate, command) -> {
Look look = new Look();
return look.call(gamestate, command);
});
commandDictionary.put("EXAMINE", (gamestate, command) -> {
Examine examine = new Examine();
return examine.call(gamestate, command);
});
commandDictionary.put("TAKE", (gamestate, command) -> {
Take take = new Take();
return take.call(gamestate, command);
});
commandDictionary.put("GET", (gamestate, command) -> {
Take take = new Take();
return take.call(gamestate, command);
D’Orazio, James, Oakes 50
});
commandDictionary.put("INVENTORY", (gamestate, command) -> {
Inventory inventory = new Inventory();
return inventory.call(gamestate, command);
});
commandDictionary.put("DROP", (gamestate, command) -> {
Drop drop = new Drop();
return drop.call(gamestate, command);
});
commandDictionary.put("CONSUME", (gamestate, command) -> {
Consume consume = new Consume();
return consume.call(gamestate, command);
});
commandDictionary.put("UNEQUIP", (gamestate, command) -> {
Unequip unequip = new Unequip();
return unequip.call(gamestate, command);
});
commandDictionary.put("DRINK", (gamestate, command) -> {
Consume consume = new Consume();
return consume.call(gamestate, command);
});
commandDictionary.put("EAST", (gamestate, command) -> {
Go go = new Go();
return go.call(gamestate, command);
});
commandDictionary.put("WEST", (gamestate, command) -> {
Go go = new Go();
return go.call(gamestate, command);
});
commandDictionary.put("SOUTH", (gamestate, command) -> {
Go go = new Go();
return go.call(gamestate, command);
});
commandDictionary.put("NORTH", (gamestate, command) -> {
Go go = new Go();
return go.call(gamestate, command);
});
commandDictionary.put("E", (gamestate, command) -> {
Go go = new Go();
return go.call(gamestate, command);
});
commandDictionary.put("W", (gamestate, command) -> {
Go go = new Go();
D’Orazio, James, Oakes 51
/**
* Retrieves the dictionary of commands where the keys are verbs.
*
D’Orazio, James, Oakes 52
* @since 1.0.0
* @see List
* @see BiFunction
* @see Map
*
* @return The map of all verb commands in the game
*/
public Map<String, BiFunction<GameState, CommandInfo, String>>
getDictionary() {
return commandDictionary;
}
/**
* Retrieves a value/lambda reference from the dictionary.
*
* @since 1.0.0
* @see List
* @see BiFunction
* @see Map
*
* @param command The key/verb to look up.
* @return A lambda reference for the command to execute.
*/
public BiFunction<GameState, CommandInfo, String> get(String command) {
BiFunction<GameState, CommandInfo, String> lambda =
commandDictionary.get(command);
return lambda;
}
}