The next semester is well on its way, and development has resumed. Over the winter break, Unity released a new version, so we upgraded our project to 5.5.1. This new version caused some slight repository issues with Visual Studio 2015 Tools for Unity, but we got them resolved.
Onboarding our new members took quite a bit of time. We needed to explain the process of how the entire project is setup along with how it functions. This was a good chance to update our readme with (more) up-to-date information about tool installation, script execution order, and repository configuration.
Much of the last few weeks has been spent fixing bugs and improving code. On fresh clones of the project, models were being imported incorrectly due to a script that was not completely tested before it was pushed at the end of last semester. This script ended up also impacting the water reflection/refraction, which ended up reflecting incorrectly.
We fixed many inconsistencies between the client and server projects. For example, our crafting station did not have a collider on the server. There were also a handful of old prefabs and assets that were no longer in use.
We have finally gotten around to implementing a day/night cycle. The sun rises and sets while the stars rotate during the night. Our ambient lighting can still use some tweaking, but
A drop system has been implemented to randomize items that may drop from enemies that die. Stats on these weapons can be standard or “modded” prior to being dropped.
Due to our previous outline shader not working at all, we have replaced it with a new one that looks much spiffier. We have also add the much coveted player names above each model (Horray! Now we know who is who). Nodes now also have a flag that allows them to spawn properly oriented to the normal of a surface.
We have begun implementing a new message display system for information from the server. This includes things like pickup notifications and such.
Movement has been updated so the player slides down and cannot jump up steep slopes.
After discussing the world event system, the base has currently been added. A new clock UI is currently being created which will replace the old fading icon. This system will allow for event firing to be synced to a time (tick).
We are two days away from the official end of the semester. We feel much more confident about our game and direction than a month ago. Numerous bugs have come and gone, features have been written, torn down, and rewritten, and beautiful assets have been imported, broken, and re-imported.
A month ago, we had an impromptu playtest that showed us a very broken game. Now, we have a lot of complete features and graphical improvements that have really turned this project into a game.
We have a bunch of new models, and virtually no programmer art left in the scene. We have models for the Krunchos, the primary enemy in the game, and animations for fighting them. We have assets for the core interactive parts of the game, the crafting station and the boat, as well as improved environmental assets for trees and the logs around the fire.
We had a fair amount of trouble properly importing assets from Blender into Unity, but we’ve streamlined the process and created a smooth workflow for adding new assets.
We put a lot of effort into polishing up and fleshing out the gameplay. Some core features, like resource gathering and crafting, have a lot of bugs. We still have a lot of work to do extending them, but the core functionality is there and we have been working to fix minor bugs as they show up.
The boat, as the central goal of the game, is completely functional, and with the new assets provides a good visual experience for the player.
We’ve added more resources and fixed up the gathering process, so it is both more intuitive and less prone to breaking.
Combat is now more functional. We have added environmental damage like acidic water and falling from great heights. The player will respawn at the campsite in the event of an untimely death.
A new feature has also been implemented, codenamed The Darkness. It took quite awhile to create a basic version, but we finally came to a consensus on how to implement this feature. While it still needs work, it is a functional part of the game that is important. We will reveal more details at a later point.
After many, many, many debates on what we wanted this game to be, we’ve come to an agreement on the core experience and why people would play this game.
The initial and most influential design for the game was story and game feel. We wanted the player to feel like a colonist who was embarking on a new journey for humanity. This affected the game play as well as environment and enemy art assets. The visual feel of the alien planet as well as the unfamiliar resources the player must collect are examples of how this design continues to permeate into the play experience.
The world was designed to give the player the full game experience, so that they could have a sense of what the larger scale game would be after their play session. Everything from the starting position and location was tailored to direct the player towards the goal while also allowing for exploration and choice.
There is an overarching goal for the current build of the game and the player is encouraged to complete it. The environment pieces and terrain were made to influence the player’s experience and urge them towards reaching the end state.
The content of the game was designed thoughtfully around the potential play time. Additionally, we tweaked the numbers to make the game feel more fun and less of a grind. The rate at which players level up, the stats that are on each piece of gear, the enemy stats for combat, and the color scheme were all taken into account when we designed the world and how we wanted the player to experience our game.
Major decisions have been concerning the design of the player experience such as what happens when they interact with water, other players, and the darkness as well as when they die. Each of these factors have come together to create a hostile world in which each milestone accomplished by a player is incredibly rewarding.
We’re sad to say that two of our team members will be leaving. Trevor will be graduating this semester going to work for Liberty Mutual. Elizabeth will be going on co-op.
Our new members will be Ashwin (Gameplay Programmer), Rachel (3D Artist), and Julieanne (Concept Artist). Welcome aboard!
Over the Christmas break, we’ll be refactoring our current systems to make them more robust. This will allow our new team members to more easily build upon our existing framework.
The past month has been busy for the entire team. With many discussions on the experience we wish to represent in the vertical slice, we have finally figured out what components we need for our upcoming playtest, and have been working towards those goals.
Our team has finally come to a conclusion on what our studio name will be: Mumble Bear Studios. Logo coming soon!
The biggest change with our entire design is the player control scheme. After discussing what we wanted players to be doing in the game, we concluded that click to move style gameplay was not the best option. Over the course of two weeks, we implemented WASD style movement controls. This style of movement left huge gaps in our framework for updating player positional data, so we needed to refactor it. We needed a tick counter in order to tell when user input took place (and in what order). After adding a tick counter to the client and server, we needed a way to sync up the current tick.
Our logic for this is quite simple. First, we have the client send its current tick to the server. The server receives this information, and now knows how many ticks behind the client is. The server then replies with its current tick. When the client receives this data, it has all the information needed to sync up the current tick AND calculate its ping to the server.
After fixing the positional sync problem, we created a simple implementation of client side correction. If the player’s position on the client differs from the server by a certain threshold, we automatically snap their local position back to where it is on the server. We had initially discussed other implementations (that were much more complex, such as Valve’s Source networking), but due to the amount of time we have decided against using a more difficult solution for the time being.
Another big system we implemented was Actors. An Actor is an entity in the world that has movement logic, such as enemies and NPAs (non-player actors). Actors are correctly spawned in on the client when they are within a client’s region.
We created Actor spawners that allow for us to create a region where enemies are created (essentially a spawn zone). Players can fight and kill enemies.
With the addition of each new system, we noticed there was no global notification system to inform the player of illegal responses and actions. We implemented an error message system that allowed us to inform players of the results of actions. These messages appear on-screen and disappear after a few seconds. We use this system to inform the player in situations such as when they are too far away from an object or when their inventory is full and they try to craft an item.
The next mini-system we added was stations. A station is a subtype of entity that represents only types of entities that can be interacted with to open a GUI. Each station holds a specific GUI ID that is sent to the client when they interact with it. The GUI with that ID is then displayed client side. The main action for a station is activation. Clients send activation packets containing the station ID they want to use/perform an action on. The server receives these packets, processes them, and returns the results to the client.
Furthermore, within the last month we added the crafting system. Using the resource tool, we can create recipes that are loaded onto the server dynamically at runtime. These recipes are populated into stations that require them. For example, the anvil/forge station is populated with recipes that turn ore into bars. The system is highly dynamic and unquestionably easy to use due to the resource tool.
In order to smooth out our client to server (and vice versa) workflow, we began creating Unity editor scripts that create menu buttons that perform useful functionality with a single click. Below are listed some of the mini-tools that have been created.
Start database servers
Start backend servers
Network layer logs
Another workflow tool was created for asset package sharing between Unity projects. One of our biggest issues has been (and still is) keeping the assets between client and servers projects synced. We have to worry about every thing matching: layers, tags, GUIDs, and references. It is extremely easy to break the logic of the entire project by transferring over an asset and forgetting to transfer its dependencies at the same time.
To alleviate this, Justin created editor scripts to allow for automatic exporting and importing of the selected objects within the editor. This has been invaluable in speeding up our development workflow.
Elizabeth has been hard at work on the newest iterations of the terrain. The starting location for the player has been completely revamped to more appropriately drive the player in the correct direction.
New flora models and textures have been created and placed throughout the scene to flesh out the natural feel. The campfire area has been populated with bench and fire models with particle effects.
Here’s some whiteboard art done by her for you to enjoy.
This past week has been focused on resource management and starting iteration.
Due to the large volume of objects that need to be managed, it would be nigh impossible for us to manually change prefab values by hand. This led to the creation of: 1) dynamic data and 2) a resource editor tool.
In order to speed up our development process, we needed to be able to change data about resources without having to rebuild the entire game. We have refactored our code to automatically load resource data from files created by the editor tool.
Resource Editor Tool
While working with raw data files is an option, it is not viable in the long run when dealing with hundreds of resources. We would have to manage items, item data, resources, and resource data by hand.
Trevor has begun work on a resource editing tool that will allow us to modify resource data without having to work with raw data files. It has the ability to create and delete resources, along with modifying, adding, and removing properties for each individual resource. This will help speed up our development and iteration process.
After finding a bug with the total length implementation in our packet library, we dabbled with the idea of using reflection instead. The implementation was simple: all packet classes would uses properties, then the total length could be calculated at automatically. This left no room for errors. After discussing the issues with reflection speed, we decided to scrap the total length in our packets. Since each packet knows what data it needs to read and write to the buffer, and we do not batch packets for sending, there was not any need for this field in our header.
But after this, we still needed a standardized method of serializing and deserializing packets. Max refactored the packet library and created core functions for reading and writing many data types to/from buffers. When serializing packets, each packet need only call WriteHeader(), then WriteX() for each data type that it contains. Deserializing is the same process, but uses ReadX() functions.
We have begun work on the first iteration of the vertical slice terrain. The majority of work has been creating environment assets and textures for them. Testing has begun on physics based environment animations and weather effects. Below is an in-engine render with updated models, textures, and animations.
The past week has focused on two main things. The first was our overhaul to switch from chunks to spheres for sending packet updates. The second was to implement and test more gameplay.
The biggest struggle with sending packets is spatial partitioning. It is important that we only send packets to clients that need to know in order to reduce bandwidth. If you are on the other side of the continent, there is no reason for you to receive updates about a player moving half a step.
Our original idea was to use a grid-based chunk system. When players performed actions that other clients needed to know about, only the players in the same chunk area would receive their updates. This idea originally worked very well. It was only until we started trying to deal with chunk borders that it because complex. The issue became when players would need to see and/or interact with other players in a chunk adjacent to them. Even if two players were standing directly next to each other, but were in different chunks, they would be unable to see each other.
This is where our borderline concept came from. Between chunks, there would be another area called a borderline. Each borderline would stick into multiple chunks. So when players entered a borderline, they received packet updates from players in all adjacent chunks. This solved the problem of interacting with nearby players from different chunks, but created an entirely different issue: how would we lay out all the chunks and borderlines? Manually placing all chunks and borderlines would be a tremendous amount of work. On the contrary, a statically sized chunk would prevent us from being able to place chunks logically around differently sized areas. Thus we had to figure out another way to handle this.
Our solution is a concept called ‘Regions’. A region represents a player or entity’s area of influence. This region is represented by a sphere collider acting as a trigger. When entities enter a player’s region (or players move so that an entity enters their region), that player begins receiving information about them. The same functionality also happens when players move away from entities.
Upon removing the old chunk system and implementing the new regions, we only encountered one issue. When game objects are destroyed, the OnTriggerExit function is not called. Since it is not called, we would not have had a way to update players about entities that are deleted. The solution to this was a function in the Physics class called OverlapSphere. The entire purpose of this function is to do a 3D raycast using a sphere. Any colliders that have bounding volumes within or colliding with the parameters are returned. Additionally, this function accepts a layer mask, so we can check only again certain layers.
With so many libraries and modules now in use, we needed to be able to trust that each section worked on its own. This lead to the implementation of unit testing. Tests are being created to check the functionality of each module. Prior to pushing on our main source control branch, the entire project is tested to ensure a (mostly) working state is maintained.
We overhauled our logging system to use a single static class with multiple channels. Each channel represents a stream of log messages that are outbound to a file. Additionally, a channel’s verbosity can be changed to control how much information is logged.
Simple client usability tweaks have been added, such as logging in when you press enter. We have added skill experience to the skills menu. We also added placeholder textures for the first two tiers of items for use in the players’ inventories.
Player interpolation has been implemented to properly smooth out movement. The player’s waypoint now disappears when they reach their destination. Players now move to a node if they are not close enough to interact with it.
The base mining logic has been implemented such that ore nodes can now be mined by players. Players receive items when they successfully mine a node and nodes properly despawn when they are exhausted or their despawn timer triggers.
The new player model has been added into the project. Basic walk and idle animations have been implemented. Some animations have slight issues with vertex weights that still need to be fixed. The animation controller has been created and works properly transitioning between states.
We have begun work on the new vertical slice terrain. New environment models and textures are being added.
Concept art for the mining skill has been started as well. The below image features the sacred geometry with an initial design sketch.
Our focus for the next week-long sprint is having multiple types of nodes that are interactable. We would also like to have the first major iteration of the basic terrain done so we can begin iterating on it. Additionally, we would like to properly implement and use our resource manager for dynamic resource loading.
The past week has been busy for the entire team. The main development has been focused on standardizing the structure of our codebase and projects while working towards the vertical slice goal.
The first major decision we made was to unify the names of the core components on the client and server into these three:
Initially, between the two projects, each of the previous managers had names that may or may not have been completely related to their jobs. This caused much confusion when communicating with each other.
The game manager handles all game logic on its own thread (the Unity thread). It is essentially the Unity Update() loop that chains through all game objects. It currently also handles parsing and processing of packets. We may decide to move the parsing on the server to another smaller, middle layer in the event that the main game thread becomes bottlenecked from too many packets.
The entity manager handles assigning IDs to entities. Each ID is used for one game object in the scene that needs to be synced between client and server. All subsets of entities receive IDs from the same ID pool, such as skill nodes, NPCs, and items.
The network manager handles all packet sending and receiving. No processing is done in this class. On the game server, the network manager has a second thread that handles the connection for this game server to the master server. This involves sending/receiving pings to test whether the connection is still live and handling incoming commands, e.g. receiving new player login tokens and receiving routed packets.
Standardizing the way code is written and formatted was another issue we discussed. After doing mini versions of code reviews, we found many places where different variable names were used while the underlying data they contained was the exact same. For example, our IDs for each player used names such as ‘playerId’, ‘userId’, and ‘owner’. This led to much confusion when using different names while speaking that were actually referring to the same data. As such, we went through our code base and cleaned up all instances where this confusion existed.
We also came up with the code formatting guide. We will use tabs, not spaces. Private class members will start with an underscore (‘_’). Public class variables will be UpperCamelCase. Additionally, variables will not be abbreviated (e.g. _nm versus _networkManager).
With multiple people working on the same codebase, comments are one thing that are very important to have. Issues can arise when there are too few or too many comments in the code. For functions, if its name tells us exactly what it does, there is no need to put a full comment block describing it. In the event a function does not do that, a full comment block will be required-in Visual Studio, you can use “///” to auto-generate the block.
For comments within functions, if it is not immediately obvious what a block (or line if it is complex) is doing, a comment will be placed above the respective line(s).
An extremely important part of development is your logging system. A good system allows you to:
Write information to a file
Have timestamps on each statement
Have custom tags on each statement
Log at different levels (e.g. critical, error, info, debug, verbose)
When a runtime bug occurs, this will make it much easier to debug.
Our logging library is named Terralog. It contains all of the above mentioned functionality. Currently, two logs are created per Unity project: the Unity log and the network layer log. By separating these two, we can more easily focus on which layer the bug is occurring at. This week we were able to fix a bug in our network layer using the timestamps on lines to verify our timing was incorrect.
With regards to instantiating resources, we discovered a big flaw in Unity’s architecture. In order to be able to instantiate a prefab, a script needs to have a reference to a GameObject prefab. With the high volume of different objects that we could potentially need to instantiate on the client and server, this would lead to copious amounts of memory being hogged up.
When you create a script with a GameObject that is assigned in the inspector, that game object is loaded into memory when the executable runs. Now, imagine having to create a script with hundreds of GameObjects assigned. This would mean every single one of those objects gets loaded into memory as soon as the game starts. The more items we add to the game, the more memory the game would use.
The alternative to this is to use the function Resources.Load<>() in the Unity API. This function allows you to load any type of resource dynamically at runtime as long as you know its path. These dynamically loaded resources must be placed within a folder in the Unity project called ‘Resources’.
For our project, the issue was translating IDs in packets received from the server into resource paths that can be used for this dynamic loading. Our solution to this was a resource manager. It is a singleton class dedicated to all dynamic resource loading. It contains a map of ID to resource location that is dynamically read at startup from a data file. With the map created at runtime, we are able to only need to update one file with new IDs and paths rather than changing hard coded strings and recompiling.
Zoning and Layers
With the creation of the dynamic resources, we were able to empty more of the project game scene. We are now able to instantiate the zones at runtime based on the data received from the servers.
We additionally moved all game objects in the scenes to corresponding layers. This allows for optimizations with the physics matrix and when doing raycasts.
Content creation is well on its way. The skills related to the vertical slice have initial mechanics and items, but we have yet to test them. The server side logic for the mining has been implemented as well, but client side has no handling for the action animation yet (we are also waiting for the models/animations to be finished).
Additionally, we now have spreadsheets with many data calculations for timings, experience, and other details. This will allow for simplified iteration when we arrive at the point for content balancing.
Modeling and Animation
The initial implementation of the player model animations did not work properly, so Elizabeth has been in the process of redesigning it.
The new implementation structure takes up less space and is easier to implement for when multiple models are integrated since they will use the same Maximo skeleton base.
To correctly implement the animations, Elizabeth had to take the initial model file and strip the skeleton of its animations. This skeleton was then reposed into a new base “standing pose”. In Unity, the imported .fbx had to be configured to give the inspector access to the skeleton. For future use (beyond her initial tests) the transformations of the hands, feet, hips, shoulders, and head will be left out for optimization. These bone transformations will be left for equipping items. From there each animation is configured and then used in making the animation controller. The code for the controller should not take too much time.
The final implementation should require the skeletons in the model initially, but all animations can be reused per model. This will save file space and reduce the work load from what we initially thought.
For modeling, Elizabeth began working on environmental pieces for the vertical slice. She has started creating artistic limitations and guidelines for mapping out the models needed for each area and their color palettes. All environmental pieces will most likely have toon based materials to give them a cell shaded look, with a focus on the specular color choice to enhance dimensionality.
The following images are some renders made in Blender. The fans are not as distinct with the heavy shadows formed by the trees. The lighting itself was a three part, soft blue light contrasted by a deep rose light to balance the colors of the objects together. A third hemispherical light was added near the ground under the trees to illuminate where the shadows were hiding. Not depicted are some basic waving animations made for the trees, as they did not move as naturally as we wanted. Hopefully Unity’s physics based animations will give the desired flow to the objects.
With the loss of Elizabeth’s laptop came the gain of a stylus for one of her tablets. The featured image represents the base for the upcoming skill icons. Each icon will be based on sacred geometry.
The image below is of the smelting skill. This concept art is partially a conceptual understanding of our design choices. The symbol overlaying the character and imposed into the background will be the icon/logo for the smelting skill, and its design will be projected into the base suit which the player will wear when utilizing a skill. The idea is based on the phrase “You wear what you are.” by Wes Anderson. During playtime, we hope it will stress the importance of how few equippable items there are and allow players to recognize a player’s skill tier by their equipment. This is a risk we take since having less gear in an MMO removes an almost assumed reward system for this type of game.
We are beginning week two of our vertical slice development and things are moving along slowly. By next week, we hope to be in the midst of testing our first skill’s gameplay mechanics and dealing with all the bugs that come along with it. Additionally, we look forward to having the updated player model and animations.
Phew! That was long. We hope you enjoyed the read and we hope to see you next time…
Since this is the first development update being posted, it’s going to be quite lengthy. We need to catch up posting all the stuff that was implemented prior to this blog being setup.
Over the course of this past summer, we discussed and designed the initial server-client architecture that we would be implementing. The following image shows our current design. In the future, we plan to make some minor changes, but this is the main server structure.
Our backend architecture revolves around three types of servers: authentication, master, and game servers. The authentication (auth for short) server handles all login/account creation requests coming from a game client. Connections to the auth server are made using the Secure Socket Layer (SSL) standard for secure transactions. The auth server also generates unique session keys upon login which is used throughout to verify the current user.
The master server handles individual game servers and database transactions. When the master server boots up, it listens for connections from each game servers. After a player logs in and authenticates successfully, the master server looks for the game server running the zone the player was last in (for example, zone ID 1). In the event no game server is running zone 1, an existing free game server will be assigned to run zone 1, or in the event there are no currently free and running game servers, a new server process will be started. Ideally, after our vertical slice (see below) is complete, each zone will be running on a dedicated game server, so there will be no need to dynamically spin up servers.
The last server type is the game server. Every game server is running a Unity3D compiled executable handling game logic and player input. Each game server will host one zone and handle all game logic for it.
For handling persistent data, we discussed the types of databases we could use. Using a SQL database would allow for a rigid structure that did not often need to change. On the other hand, a NoSQL database would help with player characters and properties (e.g. custom item modifiers and properties).
We decided to use two types of databases. MySQL would be used for dealing with super-persistent data, e.g. user accounts. With each user account, we were able to define what data was needed and what the types of that data would be.
Since at this point in development we don’t have a solid idea of everything the final MMO will have, the rigid structure of MySQL would not allow for easy development. So for world persistence and character data, we decided to use MongoDB. The flexibility of object handling in Mongo allows for us to easy add and remove properties to items without affecting the entire structure.
If at any point during a game’s development networking is brought up, it introduces a second problem into the equation. Due to the nature of our game being an MMO, we needed to think about this problem from the beginning. Our research done in a previous class to build an MMO led us to realize the difficulty of networked game development.
Initially for selecting our protocol, there was no choice as viable as using UDP. The overhead that comes with using TCP is not acceptable when dealing with real-time applications. Thus, we decided to write our own reliable UDP protocol. The main reasons for this are as such:
With the physical hardware limitation of approximately 1500 bytes (yes, bytes) per packet payload, we’re limited on the amount of data that can be sent in an instant. Because the TCP header takesup 10% of the overall data, we would be allowed an even smaller max data size since the header room is reserved.
TCP does a lot of things that we deemed uncessesary for our protocol, for example packet checksums and many other options.
While UDP does not guarantee a datagram sent will be received, we can write our own reliable network library to do the same thing as TCP, but with less overhead. Additionally, there are times when a packet does not need to be guaranteed to reach the other end point, such as a move packet or a ping.
Our reliable-UDP (rUDP) implementation is called Terralite. It contains functionality for multi-connection sending and receiving of data. I’ve listed the currently implemented functionality below:
Non-reliable packet sending
Reliable packet sending and acknowledgement
Large packet splitting for transmission and remote reassembly
We plan to add a connection handshake, but at this time, there is not one.
As with any project this large, there is no guarantee that all of the initially planned elements will even be feasible and/or even exist in the final versions. In order to minimize the amount of extra work done that will not be used in the future, we decided to make a vertical slice of our MMO. This vertical slice will be a prototype with the main elements of gameplay in order to test each element. This will allow us to iterate over each element and fix any issues we come across.
The vertical slice will feature elements from four of the planned non-combat skills. These are Mining, Smithing, Felling, and Engineering. Additionally, it will feature melee combat using one of the offensive combat skills. I’ve added a working copy of the vertical slice area below. This area represents a good sized chunk portion of the final world. Scale has not been decided yet.
Art + Modeling
The MMO will feature a low-poly, modern art style. Below are some reference images that we’ve compiled from Google Images that represent the feeling we are trying to achieve.
I’ve placed a concept art piece by Liz below that features some of the color palette that we’ll be working with.
For our meeting today with Dr. Schwartz, we demonstrated two clients logging in, authenticating, and connecting to the same game server. Both clients were able to move around and see each other moving, along with sending chat messages to each other. Inventory interactions worked as well, such as equipping, unequipping, and moving items around within their inventory.
Our current development plan is to work towards the vertical slice being complete (or mostly completed) within the next six weeks. We are currently working towards adding and using the official player model and its animations. For gameplay development, we are adding the first skill Mining, which will involve spawning and despawning ore nodes and adding player interaction with these nodes.