I wanted to start this blog post off with a quick summary of what I intend from this series of blog posts. I am developing an online cricket management game with my brother, and I thought it would be of interest to many people if I blogged the process and talked honestly about the code used, the decisions made, the challenges we face, and the ideas behind the game as we progress through development. In this first post I will look at how we began the project, and the first version we developed, which we ultimately scrapped, as we gained so much knowledge during the development process, from our mistakes, and learning from other resources, that we decided the best, most robust, and possible quickest way to get the game finished, was to start again from scratch in a far more structured approach. I intend to give a brief overview of what we did, the mistakes we made, and the plan for the future. So how did I start developing an online game?
Back in 2010 my brother and I were playing a couple of online cricket management games, and we were talking about what we could be done better, and how we would go about the process. Back then we were both novice developers with little experience, but one thing led to another and we played around with a few bits and pieces, from a neat little demo my brother made of displaying a pitch map in the browser, it ended up in an entire game called Next Gen Cricket (Website here: http://www.nextgencricket.com/).
The initial game was built in PHP with a MySQL database. This is perfectly capable of supporting a large site. Many of the largest sites in the world are built with PHP: Wikipedia, Youtube, Yahoo, and Facebook (they were initially written in PHP, they created HipHop to help improve performance, see the HipHop page on github for more information). I see many developers cringe at the word PHP, my opinion is that PHP is an excellent language, but it is more open to bad practices than a lot of other languages like C# and Java.
Being new to development still, and having never developed anything of the same scale of an online game, we fell into a lot of those bad practices. We didn’t have any agreed naming convention. Tables and Fields in our database had spaces in (which made some of the code a little bit more complicated to deal with), fields were not consistently named across tables (sometimes we used “last name”, sometimes we used “Surname” for example). This all created issues, largely with remembering what we called fields, whether they started with an uppercase or lowercase letter, what name we used for a field, whether a table name was pluralized It all seems small, but overall it created a lot of complication where it wasn’t required.
In addition to this, there was the data structure of the data in our database. As a novice I had never come across some simple database theory, so I just plowed ahead and created what I thought was right. The initial database contained lots of information in one table, including everything about a player in one table, including how much they earned, their bonuses which team they belonged to, all their skills, personal stats, and names. This limited certain options straight away. Contracts were implicitly tied to a player, which doesn’t seem too bad, but once you begin to take into account the possibility of a player being a “Free Agent” (not contracted to any team), you begin to see that this requires a special case (No team to put against a player, NULL in the team field). This is OK, but not ideal, especially when you start to look at foreign keys.
The better solution here was to separate contracts out into a separate table. This logically made more sense, we are now grouping related data into a separate table. The Player’s skill in batting does not logically belong with the contract of the player (one may effect the other, but they are two separate entities). However the bigger advantage came when dealing with situations such as the “Free Agent”. Now a Player can have no contract, and that indicates they are not a member of a team. We don’t need to handle this case anymore, a lack of an entry in the Contracts table for that Player now indicates the player is not contracted to a team.
Another big issue is actually coding in a way that scales efficiently. Separation of Concerns (SoC) is a really important principle for being able to scale, extend, and redevelop the application. When we first started developing Next Gen Cricket we made huge errors with regards to this. There are several levels this can be taken at, but worst of all was integrating business logic with presentation logic. Ideally an application should have data separated from the code that displays that data. For example:
$awayteamdata=mysql_query('SELECT * FROM `Teams` WHERE `ID`="'.mysql_result($fixtures,$i,'away').'"');
<td style='background-color: #<?php echo $awaycolor1; ?>; color: #<?php echo $awaycolor2;?>; width: 250px; border-color: #<?php echo $awaycolor1;?>;' class="tableteam"><a style='color: #<?php echo $awaycolor2;?>;' href='<?php echo SITE_ROOT."orders/".mysql_result($fixtures,$i,'mid');?>'><?php echo mysql_result($awayteamdata,0,'Team Name');?></a></td>
$hometeamdata=mysql_query('SELECT * FROM `Teams` WHERE `ID`="'.mysql_result($fixtures,$i,'home').'"');
<td style="background-color: #<?php echo $homecolor1;?>; color: #<?php echo $homecolor2;?>; width: 250px; border-color: #<?php echo $homecolor1;?>;" class="tableteam"><a style='color: #<?php echo $homecolor2;?>;' href='<?php echo SITE_ROOT."orders/".mysql_result($fixtures,$i,'mid');?>'><?php echo mysql_result($hometeamdata,0,'Team Name');?></a></td>
This is pretty awful code right here. I am selecting data here within my presentation logic. This presents us several problems. Firstly the code is difficult to follow. It is not clear how my data is presented, as the presentation logic (the <td>) is lost among the business logic. It would be much nicer if I separated this out into two files:
public function __construct($fid)
$fixture=mysql_query('SELECT * FROM `Fixtures` WHERE id = "'.mysql_real_escape_string($fid).'"');
$HomeTeam = new Team(mysql_result($fixture,$i,'home'));
$AwayTeam = new Team(mysql_result($fixture,$i,'home'));
public function __construct($tid)
$teamData=mysql_query('SELECT `color1`,`color2`,`Team Name` FROM `Teams` WHERE `ID`="'.$tid.'"');
$this->Color1 = "#" . mysql_result($teamData,0,'color1');
$this->Color2 = "#" . mysql_result($teamData,0,'color2');
$this->TeamName = mysql_result($teamData,0,'Team Name');
$data = new Data($_GET['FixtureId']);
<td style='background-color: <?=$Data->HomeTeam->Color1;?>; color: <?=$Data->HomeTeam->Color2;?>;' class="tableteam">
This is much simpler to follow. Our business logic is clearly separated into classes to represent individual entities. We then present our data in a nice structure for our presentation logic. Our presentation logic is now a much smaller file. The two examples don’t quite have the same purpose, but it should be clear it would be much nicer to see what is happening, and to update files in this example. If we wanted to change the display we simply make the relevant changes in our presentation logic. Similarly, if we wanted to change how we processed or fetched our data, we only need to make the change in our business logic.
PLEASE NOTE: The code in these examples use the legacy mysql_ functions. These are deprecated, and I would recommend looking into PDO which is a much better way of fetching data from databases. I have used mysql_ functions here as the original example (code written over two years ago) used this, and the second example is only meant as a better way of separating concerns.
Further Separation of Concerns
The above is just separation of concerns on a simple level. The nature of PHP makes it easy to fall into these bad practices, especially when learning (which the first code extract is an example). I have spent some time developing a framework to try and make the separation of data much easier in PHP, something I will look to finish when I get the time.
However SoC does not just involve the separation of presentation logic from business logic, it can be taken far further to separating the layers in your application. The code above ties our system very closely into a MySQL database, but what happens if I want to upgrade to a different database? I need to go through my entire database and rewrite all the code that explicitly references MySQL. The PDO class mentioned above goes some way to addressing this issue, however we still have to make sure wherever we have SQL code, this is compatible with our new database, so it still requires updating.
To help resolve this we can bring in separate data layers. We use a Repository layer to access the data from our database, and similarly, save the data back to our database. Our business logic then only accesses data from our repository. The repository handles anything related to our data source, so if I want to update my database, I only need to update how my repository fetches, and saves the data. As long as it still makes this available in the same way my business logic is not affected in the slightest. I can even switch from a SQL database to a NoSQL Database or even a file based data source, and I only need to adjust the code in my repository to handle this new data source. An excellent resource to learn more about this is on msdn – The Repository Pattern.
The New Version
In our new version of Next Gen Cricket, we have moved away from PHP to C#. There are a number of reasons for this. Both myself and Rob use this in our day to day work, so we are far more familiar with this at present. Another is the tools available to help with many common issues. We have decided to use the Entity Framework as this handles retrieving all our data and placing them into related objects nicely. This also sits in our Repository layer, and we could easily decide to later replace the Entity Framework with a NoSQL solution or something similar, and only have to change our repository layer. We then have a Service layer which performs the business logic and then makes the data available to our front end.
With regards to a web front end, we have decided to use MVC4, again another reason for using C#, as this easily handles the separation of business logic from presentation logic. The controller fetches the data from our service, and places this into the model. The view then holds the presentation logic to present the data in the model.
We can then also produce an entirely separate match engine which also retrieves it’s data from the Service Layer. This match engine will be separated into separate parts, a physics engine to handle the physics (flight of the ball, bouncing, etc), and a match simulator which handles the logic behind a match. We can separate other parts of the match engine out into separate parts as well, such as looking to create a separate section for player AI. Further to this we also plan to make available an API which will also work from the Service Layer. You can see the versatility separating layers provides.
Overall the entire structure has clearly separated areas, each with their own purpose. Any changes are likely to be made in one particular layer. For example if I need to change the layout of a page, I simply change the view. Certain changes will require changes to multiple layers, but this is usually a simple process as there is usually a clear path through the layers. If I want to add an extra batting skill, I make the change in my data source, update the equivalent class in my repository, update the equivalent class in my service… until the change is reflected in my view.
With all I have said about the issues we ran into with the first attempt at the website, I would forgive you for thinking we had developed a huge pile of junk that didn’t work. This was not the case at all. We in fact developed a fully working large, complex website that I was proud of. So what’s the point in starting again you might ask? Well it was a good example of how a working website need not be a website developed with good practices. Many large websites have problems. For example, WordPress is an excellent bit of software for blogging, but I hated writing templates for it, it just wasn’t well structured for it (in my opinion).
The problem with our first website was not the output at all. It was the maintainability, and the ease of expansion that were the problems. Good practices allow easy development, and provide the tools for providing good user interfaces on many devices. With the original version of Next Gen Cricket, I was not 100% happy with the match engine, but changes to it, and tracking the code was a pain. So much so, I rewrote the whole thing three times, and never quite got it right. I also had issues with the design of certain pages, but changing the layout was complex.
So the lessons I learnt were several. I would never undertake a project this size without first planning the structure. This time I have sat down with Rob and discussed the basic overall structure, the individual parts of the website, and how we are going to fit it all together, and make it possible for expansion. An agreed naming convention is certainly important, so that one developer can quite easily figure out what the method he is looking for is called, or how a property may be capitalized, all the small things that can take time to get right. Layers should be kept separate, with every layer being responsible for one thing only, whether it is a user interface, storing data, or making that data available, they should be handled separately. Finally it is important to try things, and make mistakes, and not be afraid to start again. Without first attempting Next Gen Cricket I would never have learnt half the things I know now. I would likely not be working as a software developer, and I certainly wouldn’t have had all the fun I had along the way!
I’m very much looking forward to producing Next Gen Cricket V2. The game has been a part of my life for so long now. This post is just the first in a series that I hope to bring you, detailing the process we go through in making the new game, to hopefully share what I have learnt, and what I am going to learn along the way. I hope it is interesting for many of you, and help inspire at least one of you to also develop an online game!
Posts In Series:
- Developing an Online Game – The Previous Attempt
- The Repository Service Pattern – Developing an Online Game