Rooms / Design Document / Group D

Rooms - Design Document

Group D

1. Design Overview of ROOMS (Thom)

ROOMS provides users with three major facilities: a massively multiplayer game world, a content creation and distribution system, and a website, the primary location for users to interface with these.

1  The game world consists entirely of sub-worlds known as “rooms”, each containing one or more of what is typically described as a room. The vast majority of these sub-worlds are temporary and randomly generated on the fly, however some are created by players via the “editor” (see 2.), and transferred to the player and loaded during runtime. Players start in one of these rooms, and upon exiting it are placed in another random room. Traveling back into the door from which they came takes them to yet another randomly generated room, and not the room from which they came.

2  The content creation system, known as “the editor”, allows users to design, create and distribute their own content throughout the Rooms gameworld. Users are permitted to customize Rooms, Monsters, Items, and their Characters, known collectively as “editables”. The editor provides an interface for changing the attributes of these editables, as well as their pictorial in-game representation, via either a URL upload or a minimal bitmap editor located on the ROOMS website. Users may base their creations off of existing creations made by them or others. Any existing “editable” must be customizable as an prototypical version of the item being edited. The finished editibles will be randomly distributed throughout the game, and players will have a mechanism for tracking the associated statistics (times encountered, etc.).

3  The ROOMS website will primarily contain three things: The editor, user profiles, and a page which embeds the game as a Flash object. In addition to this, various pages will hold static information about the game, primarily help and information pages. The user profiles allow users to add “friends” (other users with whom they may organize and start game sessions, chat with through the game’s minimal built in chat system, and view creations).

To implement these features, the game itself must be very flexible, as we wish to avoid frequent game updates (at least, newly created content must not require an update or patch to the game), and we want users to be able to take any existing piece of game content, and create a new piece of content by changing one or more attributes of the existing content.

ROOMS’ client and server is written in Haxe, and its website is written in PHP. Writing the client and server in the same language allows us to reuse a great deal of code. Since synchronization concerns require the client and server to run the game separately and simultaneously, this code reuse is a huge benefit. Additionally, choosing Haxe as our language allows us to target multiple platforms with little extra effort (most notably Flash and C++). Because libraries exist to allow games to run unchanged on the Flash and C++ platform. Due to this, ROOMS will run on both Flash and mobile platforms. Our primary focus however, at least during the initial stages of implementation, will be the Flash platform.

ROOMS uses the Component-Entity-System pattern for its game logic (which will be discussed at length in subsequent sections), and a very loose interpretation of Model View Controller for its overall architecture. ROOMS’ game logic resides in the ROOMS.Model package, a rooms includes a very thin view abstraction which serves as a wrapper around the abstraction layers provided by Flash/NME, so that should some platform-specific be required, it won’t affect the rest of the codebase.

ROOMS.Controller.Server houses the server-specific portion of the logic, which will largely involve running many instance of the game with no view and with no primary player (Our design of ROOMS.Model intentionally avoids the notion of a “primary player”, and instead uses the Entity abstraction to reference all game objects). Similarly, ROOMS.Controller.Client houses the client specific concerns for running the game. This includes connecting to the server, resynchronizing when requested by the server, and transmitting player actions to the server.

ROOMS high level package structure

2. Design Patterns used in ROOMS (Thom)

Many of ROOMS’ features are contingent on a great deal of flexibility from the game objects. The most important way we enable this is through the use of the Prototype creational design pattern, and the Component-Entity-System structural design pattern. Component-Entity-System, while not a Gang of Four design pattern is commonly used in game design (large frameworks such as Unity rely heavily on the component-entity-system pattern), and used heavily enough in the design of ROOMS that mentioning it here is warranted.

The Prototype pattern is used to facilitate ease of extensibility for users of the editor. A key feature of the editor is the ability to select a “parent” for whichever object you are designing. For example, if designing a monster, the user can select any monster used in the game as a “parent” for that monster, and automatically inherit all the attributes applied to that monster. This way, we can facilitate a data-driven subclass-like mechanism, without having to actually create the code for a new class (this point is important, as creating a new class would require updating every client, not to mention rebuilding, or somehow patching the running server, which is undesirable).

In this diagram, Data is an abstract superclass of ItemData, MonsterData, and CharacterData, the three user-customizable data sets. (As a side note: A minor, unimportant point is that data is parameterized on its subtype to reuse the code in its body. If clone() returned Data, then clients of data would be forced to cast, which is undesirable. The other alternative is to retype the code in each subtype of data. This would be more difficult to maintain). They support the operation clone, as any instance of a Data type may be used as a parent of a new instance. It’s worth noting that we chose to maintain a pointer to the parent instead of having clone() actually copy the data. This is because every data is immutable (within the game), and holds values such as a monsters maximum health, or a weapon’s damage. This makes a full copy an unnecessary waste of space.

The second design pattern prevalent enough in ROOMS to merit discussion is the Component-Entity-System design pattern, also known as CES. CES is used to decouple the functionality of game objects from their abstraction. The implementation of this design pattern centers around three class hierarchies: `Entity`, `Component`, and `System`, and a single class, the CESManager. The `Entity` class wraps a list of component, and has operations to add, remove, and determine the presence of a given component. Entities are instantiated with an Abstract Factory (or similar) creational pattern to ease creation and to prevent Systems from depending on the concrete type of a given Entity. Each component holds an id number, and some number of data values. Each system supports two public operations, appliesTo, and apply, each taking an entity, and holds no public data values.

Conceptually, an Entity is a bag of Components, and a Component is a set of key value pairs which some Entities would have, and some would not. The systems are where the Component specific logic lives, which prevents coupling between related components. Systems which need to communicate with each-other communicate by changing values on a given Entities component, and not directly.

The first of the System’s methods, appliesTo, takes an Entity and determines whether or not that Entity has the necessary components for the system to work on it. Were performance not a consideration, this function would be called for every System on every Entity during each game update (in a realistic implementation, these values would be cached). The second operation supported by Systems is apply, which performs a systems actions upon an entity. For example, a MotionSystem would move the x and y position values of an entity based on its dx and dy, and decrease the dx and dy values based on some friction value. It follows, then, that the MotionSystem requires x, y, dx and dy properties, and these are supplied by the PositionComponent and MotionComponent, respectively. The RenderSystem might render the entity on a screen at each update, given that they have a RenderComponent (containing an image), and a PositionComponent (containing x and y values). (Realistically, a RenderComponent would want to avoid redrawing unchanged entities, and would want to ensure that animations were sufficiently smooth. Fortunately, considerations such as these require no change to our design.).

The CESManager is the glue which holds all the active systems and entities together, and orchestrates the application of the different systems to the Entities they hold. It is where implementation considerations such as caches would be kept, and would be responsible for updating the game at a reasonable pace.

This design pattern is composition-heavy, and allows a great deal more flexibility than a class hierarchy would, as this allows us to create new types simply by the composition of various components. Additionally, systems solve the potential problem of component dependencies. Components are not allowed to know about other components on their entity, however Systems are allowed to know about any number of components. The drawback to this design pattern is the lack of static type information available to programmers. There is no way to statically determine, for example, that a RenderSystem requires a RenderComponent and a PositionComponent, or to statically ensure that every entity passed to it has both of these. However, given that many of ROOMS intended features explicitly require dynamism and runtime flexibility, this is an acceptable tradeoff.

An example class diagram showing the use of the Component Entity System pattern in ROOMS

3. ROOMS Game State Diagram (Nikolaj)

This diagram describes the possible states that the game can be in and the transitions between them. Since the various game states are associated with different interfaces and functionality it is crucial to distinguish between them. The main distinction in functionality is between the In-Game State and the other states. In the In-Game State players interact with the extremely dynamic game world while the other states are menu interfaces that predominantly remain static.

After game initialization the game enters the Main Menu from where Character Selection or the Options menu can be accessed. In the Options Menu options such a Graphics and Controls can be modified. From Character Selection a new character can be created or an existing character selected. All of these states are associated with menu interfaces taking mouse input. In these states most of the in-game mechanics on the client-side can be suspended. By choosing the play option the game then enters the In-Game mode during which the player can navigate and interact with the game world. In this state all in-game mechanics are fully active. From the In-Game state the player can also access the Options menu, the Inventory or NPC dialogue. In the Inventory and NPC Dialogue states the game continues in the background while a menu object is layered on top of it. In-game mechanics are not suspended but the controls are modified. Instead of navigating the gameworld the player navigates the menu. A game session can be terminated at any time from within the Options menu state.

State Diagram for ROOMS’ User Interface

3. Entity Relationship Diagram (Mevludin)

Most design decisions for the ER diagram was flexibility, to allow future game changes with little to no changes to the database schema. The game contains users, characters, items, monsters and rooms. And since these are all represented differently, there needs to be a table for each one. There will exist relational tables which connect these tables. A design decision has been made to remove the Entities and TypeLookUp tables. The Entities table was used to stored the instances of rooms, monsters and items. And the TypeLookUp was to set a type system for rooms, items, character and etc. But both of these were unnecessary because since they complicated the design. Also, another design decision was to remove the Attributes table which was used to store attributes associated to monsters, items, room, characters or anything else that would exist later on. The table would store multiple attributes associated with one ID. For example, one item could contain multiple attributes, and each would be a separate row in MySQL. Instead, a field called Attributes is created for each table that uses attributes, and will be stored as a JSON string which would contains all the attributes. The reason for this change is because the data flow communication between components is via a JSON string, so there will be no need to encode or decode the JSON string when a component needs to fetch from the database or store to the database.

To support the entity class flexibility, connection between any two tables with a relation is possible. Our ER diagram demonstrates this through Users, Rooms and Characters tables. The Users table has a one to many “own” relation to Character table, since a user can own many characters. Also the Users table has multiple one to many “created” relation to Monster, Item, and Rooms tables because a user can create a monster, item and room using the editor. The Rooms table has multiple one to many “Contains” relation to Characters, Monsters and Items tables. These relations are used to show that multiple characters, monsters and items can exist inside a room. If a new table is created, the room can be made to contain the table by a “contains” relation. A possible new table would be a non-playing characters (NPC) information table. These NPC’s would be able to give characters quests. So this relation allows the NPC to exist within the room.

Also, the Characters table has a one to many “own” relation to Items. This may be used as inventory. But other “own” relations can exist. For example the character can be able to own monsters, or rooms. This allows characters to have monsters as pets and/or allow the character to be able to summon the monster for help. And character owning rooms could be made to allow them to “teleport” to a room which has an NPC for the quest they might be doing. These examples are not part of the game but are used to show the kind of flexibilities this schema allows.