Data-driven design with Unity 3d, Part 1 – Brainstorms, Initial Requirements.
By Mike Wuetherick
This is a slightly-edited re-post of a series that I’ve been writing in quiet isolation (which you get used to doing indie development) on my blog. Currently up to part 4 of the series, they have been received somewhat well by my small subset of beta testers, so might as well throw them out to the world at large ;}
Well, here goes. The story starts back in March. For the year previous, I had been working at DeNA Canada, helping them startup their first Canadian studio (I was employee #2), recruiting, getting coffee makers and all that fun. Somewhere along the way I was immersed in the concept of ‘server-driven’ game development – a concept that I had experimented with in passing on a few titles, but nowhere to the extent that we did at DeNA. Note that I started before Rage of Bahamut had hit the charts – even at DeNA, no one really believed that it would be popular, except for the fact that the Japanese market had/has an insatiable appetite for card battles, and the belief was that similar styles of games could translate across the water. Well, the rest is history, I spent a year at DeNA, learned a huge amount and – most importantly to this series – spent 9 months building server-based games with Unity and discovering the huge potential and power of this kind of game architecture. If you want to know the secret sauce of how DeNA and other top-grossing mobile titles generate so much revenue from their titles on an ongoing basis? The answer is Server-driven game architectures.
Anyways, that’s where the story begins.
With my new-found freedom comes responsibilities. The first is looking for a new job and/or deciding what I want to be when I grow up. The second is, of course, starting to work on a new game of my own. I’ve never been one to sit around and wait for an opportunity to come my way, and might as well continue to push my own personal limits while I work through where I end up after this brief intermission.
After a bit of soul-searching about what kind of title I want to create, there is a definite foundation layer of technology and design that I want to get implemented. These are core building blocks that will be required irregardless of the specific game that gets built, and as such, are something that I can begin to design immediately, ie before I lock down a design.
But first, before I go into detail about these pieces, let’s look at the basic assumptions that I’m going into this new project with.
1.Mobile (android only for the moment due to lack of hardware)
2.free 2 play (IAP)
3.Unity-based php server / back-end
I’ve spoken to quite a few people lately about servers / back-end technology, and there seems to be 2 core camps at the moment:
Ruby and/or node.js or some other esoteric framework that very few people know and understand
I don’t want to go into too much detail about either of these, and when it comes down to it, the simple fact is that I don’t know enough about either to dive into anything with any kind of comfort. The big thing to remember when starting out any technology project is that you want a solution that is not only something you will be able to build and do what you want, but also something that it is easy to find developers to bring on board and grow the team in the future. The further from the ‘norm’ your technology solution is, the more difficult it will be to find programmers familiar with the tech and more difficult it will be to get them productive once you bring them on board.
With a solution like Java at least you are safe in the knowledge that there is a lot of support in both industry and educational worlds to help train your future employees / team members. Node.js / ruby etc? Not so much. Python? Maybe, but it’s also a ‘very object oriented’ system that has it’s own complications.
My personal coding style is very bare bones – for a couple of reasons. I am often jumping between numerous languages on a regular basis, so memorizing the language specific nuances of a particular system isn’t particularly of interest to me, and secondly, I find that the most useful and understandable code (and most easily debugged) is code that doesn’t hide behind alot of abstraction layers / templates / language-specific features. But that’s just me. Maybe I suck as a programmer (and that’s definitely arguable), but looking through code trees of programmers that most definitely do NOT suck, I can feel confident that this is at least a reasonable way of looking at things.
Anyways, I digress – let’s get back to the situation at hand.
To PHP or not to PHP
So having said all of the above, the only server language that I know and trust is PHP. It hasn’t done me wrong in the past, is nicely scaleable and a ‘known quantity’ with regards to finding developers comfortable using it. As well, I can get up and running with php instantly and know that I will make progress very quickly.
So, let’s discuss the above requirements, specifically looking at the re-usable server framework that the projects require.
Server-side data-driven development
When it comes down to it, from a game design standpoint, separating your game’s data into the ‘cloud’ as it were is the best thing since sliced bread.
Always-on architectures get a lot of bad press (see the recent simcity debacle). I understand the concerns about DRM / etc, but when it comes down to it, from a game design standpoint, separating your game’s data into the ‘cloud’ as it were is the best thing since sliced bread.
This doesn’t have anything to do with ‘milking your customers’ or invading privacy in the slightest. The basic fact is for a game designer, being able to push out updates (either new content or simply tweaking the balance of a few items or missions), simply by adjusting some parameters on the server in today’s rapidly evolving market is absolutely necessary for a title to succeed.
Also note that I’m not making any grandious claims (ala Maxis) that I’m going to be utilizing the ‘cloud’ to process the individual AI ticks of the minions in the game or any other such garbage – however, there are some pretty significant ‘must have’ features that any game in the year 2013 should consider ‘must have’ in my opinion. Let’s go through some of them:
Advantages / ‘Must-Have’ features of a server-side / always-0n design
1.persistent / cloud player state saving – move from device to device, no more unlocking / restarting a game from scratch
2.server-side data allows you to adjust the balance / tweak your game after launch.
3.if designed properly, server-side data should also allow you to push out content updates without requiring a new client push. This is particularly important on iOS, when a simple adjustment of the game would previously require a 2 week turn around waiting for the latest build of your game to get pushed through to your customers.
4.integration with a larger user login / registration system, and possibly a 3rd party payment / virtual currency platform to reduce / eliminate the friction for your users to start playing your game, and (dog forbid) start spending money on your title.
Server Design – 4 Elements
What the above means, from a server design standpoint, is that we have basically 2 key elements to our server, and quite possibly 3 or even 4 (depending upon what platform you will target).
The first 2 elements to our server design can be broken nicely into:
1.Static Content (Metadata)
2.Dynamic Content (Player data)
You can consider metadata to be anything static in your game that doesn’t change from player to player. This could be an inventory of all of the weapons in your game, or a list of all of the level names, all of the dialog text in the game, and so on. I would highly recommend that you store all of this static information server-side so that it is easy modified and updated after launch. Yes all of it. I’m not kidding in the slightest. Every weapon, every item in your massive RPG, every character’s details, the whole story of your game. Store all of it on the server and query it dynamically (well, mostly dynamically, we’ll go through how we can cache this and allow offline play etc later on). Yes I did say ‘offline play’ – almost nothing about what I’m proposing here would necessarily prevent offline play, but that’s up to you to decide for your particular title.
The dynamic content in your game is the player-specific user data that gets stored as they start the game and progress through the adventure. This could include their progression through the tech tree in your game, their inventory, unlocked levels, etc. It could also include a more complex savegame system that stores micr0-states of individual objects in a scene if you like. All of this information gets pushed to the server and pulled down dynamically when the player first launches the game / effectively ‘syncing’ their game state. Every MMO that you have played does this kind of thing, and probably a number of other games that you have played in the past 3-5 years as well. Unfortunately not nearly enough do this kind of cloud-saving (in my opinion).
The 3rd Element of our server design is related to #1:
As games get larger and more complicated, the more likely that you will want to be able to push new content or updates to your users dynamically. Building a system that provides this kind of mechanism out of the box will save you a ton of pain trying to deliver patches / updates to your customers. This could be as simple as downloading the texture used by a particular NPC to an entire new level or zone for a game. A tool like Unity provides a powerful http class for handling downloading of content and also provides AssetBundles, which allow you to very easily pack up just about any content in your game and stream it to the user on demand. You could do this truly on demand (only streaming content as it’s needed), or via an ‘auto updater’ setup (run at game launch or otherwise). Either way can work, depending on the platform(s) you decide to support.
The 4th element is more crucial for mobile, but applies equally to normal PC development as well:
3rd Party Integration
One of the most popular 3rd party integrations today is facebook. A major consideration that you need to factor in is whether you want to build your own user registration / login system or use a 3rd party integration. Facebook is one, others on the market include ScoreLoop, Playtomic, and there are a number of other options. One that I’m looking at that seems pretty polished is called PlayPhone, but haven’t decided 100%. I’ll do another post dedicated to the 3rd party integrations because there are a number of factors involved with this decision and more than I want to get into today.
So with the above elements in mind, next time I’ll go into some specifics about how I’m approaching Element #1 and #2. #3 is fairly straightforward and won’t be a huge issue at the start, but I’ll describe how I plan to handle this. #4, as I mentioned above, will be covered separately, although whether I have made a decision on what system I’m going to go with by then remains to be seen.
Data-driven design with Unity 3d, Part 2 – Server design / API and assumptions
As mentioned previously, I’ve started fleshing out the backend for the server that I’m looking to build for my ongoing experiments.
Let’s recap the key points:
The first 2 elements to our server design can be broken nicely into:
Static Content (Metadata)
Dynamic Content (Player data)
You can consider metadata to be anything static in your game that doesn’t change from player to player. This could be an inventory of all the weapons in your game, or a list of all the level names, all the dialog text in the game, and so on. I would highly recommend that you store all of this static information server-side so that it is easy modified and updated after launch. Yes all of it. I’m not kidding in the slightest. Every weapon, every item in your massive RPG, every character’s details, the story of your game. Store all of it on the server and query it dynamically (well, mostly dynamically, we’ll go through how we can cache this and allow offline play etc later). Yes I did say ‘offline play’ – almost nothing about what I’m proposing here would necessarily prevent offline play, but that’s up to you to decide for your particular title.
The dynamic content in your game is the player-specific user data that gets stored as they start the game and progress through the adventure. This could include their progression through the tech tree in your game, their inventory, unlocked levels, etc. It could also include a more complex save game system that stores microstates of each object in a scene if you like. All of this information gets pushed to the server and pulled down dynamically when the player first launches the game / effectively ‘syncing’ their game state. Every MMO that you have played does this kind of thing, and probably a number of other games that you have played in the past 3-5 years as well. Unfortunately not nearly enough do this kind of cloud-saving (in my opinion).
So now that we know what we are trying to do, let’s discuss a bit about how we might achieve this.
As a caveat, I’ll definitely say that my approach is likely going to be far from typical, however the underlying principles are based on many years of experience working with similar systems, both from the web-development standpoint as well as from the game development side of things. My career has floated almost equally on both sides of the fence. Years ago this seemed a bit strange to me, but they have effectively merged with this new approach, and I find the end-result so much easier to maintain.
My primary goal in this experiment is to reuse existing code and libraries where possible to maximize how much I can get done with the minimal amount of code. As a single-person (at the moment anyways) indie developer, there are far greater challenges and tasks on my plate than writing a full-fledged content management system to handle both the static and dynamic aspects of my project, and realistically, there is probably someone who has already written the majority of what I’m hoping to achieve already.
Before I dive into the particulars of the separate systems, lets take a look at a higher level set of functionality that I’m looking for with my Static AND Dynamic systems to see if there is a few common threads that might help me narrow down an approach.
1.Runs on the standard LAMP stack (LAMP being Linux / Apache / MySQL / PHP, although the apache element might get swapped out with a more efficient web server before I’m done). This makes hosting & scaling the system a ‘known quantity’ that doesn’t require esoteric / specialized knowledge to achieve.
2.Reuse / provide as much functionality out of the box without requiring a massive code rewrite or repurpose.
3.Provides me with a web-based interface for editing the game data (either static metadata or player game data). For this reason alone, writing a custom PHP / MySQL app is less appealing. Building a nice easy to use interface for a database app can often take longer than the core functionality itself, so I’m hoping for an existing solution that will solve this problem.
4.Be easily scaleable – either as an existing ‘appliance’ that I can plug into amazon or rightscale or something similarly easy to deploy into a cloud-based system. I don’t believe that cloud systems are the end-all-be-all for scaling an app, but they do provide a starting point for a solution, and having something that I can quickly deploy if need be is crucial. Last thing you want is for an app to become popular and not have a plan for scaling the app ;}
5.Provide a JSON interface (or easy access to data so that I can build my custom JSON API for the server communication layer). I’ve been working with JSON based server API’s for the past year and have really enjoyed how easy they are to work with. This plus the fact that PHP has very powerful built-in support for JSON serialization and parsing gives me a head-start building the server communication layer. I’ll go into this probably next time as we get closer to the client / front end design.
That pretty much covers my high-level requirements for the system. Let’s dive into some details.
Static Content Management (Metadata)
For any game, there is a large amount of static content, what I’m dubbing Metadata, required for the game. Think of this as the look up values for everything from the number of levels in the game, how many enemies a particular wave should contain, details about how strong a particular enemy should be, all the way down to how many XP a particular game event should grant the player.
For a traditional single player game, this data was either hard-coded in the game code (or hopefully a text config file at a minimum). With tools like Unity, the metadata can be thought of as the public interface for your class that Unity exposes in the editor at design time. This isn’t necessarily a hard & fast rule, but it’s a good rough starting point for us to begin working from.
To provide a more specific example, let’s break down one potential class in our theoretical game and figure out what kind of metadata you might want to poll the server for.
Lets assume that our game has a variety of enemies that the player must fight. These enemies probably have Health, Movement speed, Damage (and/or Damage per Second), firing range, and other similar properties. These variables are a perfect candidate for grabbing from the server. If we have them hard-coded in the client, then after our game launches, we will never be able to update or modify these values without pushing out a new client update / patch. If our game isn’t perfectly balanced at launch (and let’s be honest, very few are), we will be stuck with these values until we can get an update / patch for our game out the door. However, if we are polling this metadata from the server at runtime, updating & modifying these values are all of a server-side tweak away. This is exactly the type of thing that every game should be looking into using.
This same method can be applied to just about every aspect of our game. What missions are available in our game, what enemies (and how many) get spawned for each level, etc can and should be retrieved from the server at runtime to allow for the maximum flexibility in our codebase.
Most programmers have heard of ‘data-driven design’. The traditional description of this is to separate the data that drives an application from the code / logic that makes things come to life. What this mean in many apps is having a local database
What I am expressing here is a relatively straightforward extension of this methodology.
Now that everyone understands this (hopefully) approach to the overall design to the client & server, next up we’ll start to design the json server api that we will be using to pass information back and forth and start building up our client/server communication stack. The fun begins ;}(source:altdevblogaday)