Quality code and lots of coffee

Tag: c#

Stats Tracker API

The Stats Tracker API was a freelance project I undertook for a local browser-game development company.

To provide more in depth reporting to their customers they wanted a small client side library they could inject into their games that would track certain events; it would then send these events to an API which would present them to the end user via custom reports – so the project was broken down into 3 parts

API

An exposed API that would log the events from the game, this had to be versatile enough to accommodate data packets of various lengths and structures as the packet structure could not be identified until the event had begun to be processed

Administration Area

The owners of the Stats Tracker needed the ability to manage clients and games within the system. For this an administration area was created which would allow for the administrators to manage Clients, Games, Events for those games and define the parameters that those events would pass in. This would provide the foundation for the structure which the API packets would send.

Client Area

Clients using the system needed access to their own area with a locked down and limited view of their own products, but no more. As this was a multi-tenanted system it was vital that clients did not have access to other clients games or reporting.

The reporting section itself also needed to be able to provide custom views and timescales for the data collected and display it in a visual format. For this I made use of a charting library

Tech Stack

ASP .Net Core MVC

.Net Core as I’ve mentioned on this blog is incredibly versatile – and given the scope of the system I wanted more out the box than PHP provided. MVC provided a fantastic framework to build the API and accept packages and .Net Core Identity allowed the flexibility that was needed in order to build the Adminsitration and Clientside areas. Then because of the cross platform nature I knew that when the app was handed over it could be hosted anywhere. Razor syntax and view models also meant that web pages could be built with relative ease to serve the client facing system’s requirements.

Chart.Js

Chart JS is a free but powerful open source charting library making full use of HTML 5, although the documentation is lacking, Chart.Js can very easily be integrated into custom reporting to provide good looking visual graphs

Entity Framework

From the offset this project had very clear defined objects within the system. Entity Framework provides a fantastic interface between the database and the service layer of your system so that both the API and GUI can communicate with the database without needed to write the SQL yourself. However, in some cases with reporting I needed to write custom SQL in order to optimize queries, and EF allows this alongside it’s usual functionality.

MySQL

Not as bloated or expensive as SQL Server, MySQL provides a very clean straight forward and cheap alternative as a database provider; whats more is that there is Entity Framework support with MySQL so that it can be integrated easily into a Microsoft Tech Stack. Which means for the first time I was able to integrate MySQL with ASP .Net hosted on a Unix Server .

.Net Core 2 – Cross Platform Code

When I started programming properly in 2012 during my degree, there were a few truths. C# and Visual Studio were for Windows. Python and Perl were for Unix and Mac OS was something I just didn’t want to ever touch.

Visual Studio also cost a bomb – I only had a copy because my University was kind enough to furnish me with a 2 year licence for VS2010 which I used in full, then just before my account was suspended managed to nab a copy of VS2013 which carried me til 2016. I tried making a few cross platform apps in the beginning, but unless I was using Mono or something far more basic like JavaScript – then cross platform wasn’t really a thing.

Lo and behold Microsoft go and change up their style – they’re now shipping free version of Visual Studio, and not only that but the community editions are actually quite powerful (this might have always been the case – but since I had free professional editions I didn’t look too hard). Either way I’m impressed with the level of features available in the community editions – Especially with it being free. Then a few months later one of my co-workers Rogue Planetoid mentioned that Microsoft were releasing the .Net Core standard – a cross platform SDK for visual studio, capable of being run on Unix, Mac and still natively on windows.

The framework

This might be old tech as of writing this as the .Net Core 2 standard is released, and I never bothered to give 1 or 1.1 a go – but I finally did get round to upgrading VS2017 Community and getting the SDK from the Microsoft site.  I won’t go into what it was I was working on because frankly that’s a bit of a lengthy conversation [My GitHub for the project], but it was effectively a console application. At the moment .Net Core 2 supports ASP Net websites and Console Applications. So unfortunately my bizarre love for windows forms isn’t yet supported. But I was keen to get my console app running on my Centos server.

First of all you can’t change an existing application over to a .Net Core app – or if there is I couldn’t see the option. So I had to create a new project and then port over my code. Thankfully this provided an excellent excuse to refactor my code. I did particularly enjoy that the code, for lack of a better term, just worked. I didn’t have any 3rd party NuGet packages or extra content, so the basic windows libraries could just be bolted on and the code compiled as normal. Within about 20 minutes I had completely ported over my applications, an hour after that I’d made it a little prettier.

Since I was finally moving my code over to the same server as the database I decided to remove the API calls and use a direct MySQL connector – now this meant that I did have to get a NuGet Package – specifically MySQL.Data this currently supports the standard .Net framework but it isn’t supported on .Net Core yet unless you get the RC or DMR version. I installed that, did some upgrades and compiled the app.

Setup on the Unix server

So – running it on Centos; I initially went and downloaded the 64 bit runtime binaries from the Microsoft blog local to my server, I then unzipped them and followed the generic instructions. Microsoft instructions tell you to unzip them and leave in your home directory for use but I wanted to put them in more of an application directory, so I did the following.

cd ~/ 
mkdir dotnet
cd ./dotnet
wget https://download.microsoft.com/download/5/F/0/5F0362BD-7D0A-4A9D-9BF9-022C6B15B04D/dotnet-runtime-2.0.0-linux-x64.tar.gz
tar zxvf dotnet-runtime-2.0.0-linux-x64.tar.gz
cd ../
mv ./dotnet /etc/

This then meant my .Net Core directory was at /etc/dotnet/… and I now needed to register the new application. Microsoft tells you to execute this in your command line but I found that each time you restarted your shell session it would forget what you’d set up, so in the end I added it to my local .bashrc file.

nano ~/.bashrc
#then at the bottom of the file added
export PATH=$PATH:/etc/dotnet

Save and now I could run any dotnet applications with the command dotnet such as “dotnet -h”

I did have some trouble on my first application run due to some missing libraries, but they were pretty easy to install through the usual package manager

yum install libicu libunwind

Package & Run my App

So I’m used to a console application building and dumping an executable in the output directory with an App Config and some, .Net Core uses JSON files and DLL’s for it’s binaries, though they shouldn’t be treat any different really, the main difference to factor in is that your unix installation doesn’t have a GAC – the GAC is the global assembly cache; when you run an application on windows, normally if the code references a DLL it’ll ask the GAC where the install path is, so it can be referenced and used as normal, even if that DLL hasn’t been shipped with the application.

Unix obviously doesn’t have a GAC – so when you try to run your application you need to make sure that instead of just moving your JSON and DLL files up to the server, you actually publish the application and move everything. To show you what I mean, below is the difference between the standard “Build” output of a .Net Core application vs the “Publish” output of the application.

The publish job packages up everything, including runtimes and referenced libraries, so in order for this to run on Unix, I needed to publish the application and move that output onto the server. Once it was on the server I could get away with just moving my main DLL up, but you must publish at least once or you may start to get runtime errors.

Once it’s all on your server, let it run.

dotnet ./ADFGX\ Server\ Module.dll

or if you want it to run in a background session kick it off with a screen

screen -dmS DotNetApp dotnet ./ADFGX\ Server\ Module.dll
screen -x DotNetApp

Conclusion

All in all I’m very pleased with the .Net core stuff, it’s downsized the number of IDE’s I need to have installed and means I can now start hosting some more windows technologies on my Unix server which should save me a few pennies as well.

Hopefully in the coming months we see Microsoft bringing out some more application types and looking forward to more NuGet support. But what I’ve seen so far of .Net Core seems really stable, very easy to set up and really easy to migrate your existing stuff over to.

Legend of Drongo

DrongoThe Legend of Drongo was a project I started as a means to familiarise myself with C# programming concepts for my studies.

Following my studies the project was mothballed and is now being worked on in sprints as and when I have the time. As a project it is a product of the accumulated skills I have gained over the past 4 years of development experience, so naturally some areas of the program are poorly designed and executed.

However I am constantly making changes to the engine, and one day hope to release as an indie game.

The bulk of the project is a game engine in which users can traverse a ‘world’ comprised of interlocking data types, these data types can be configured in an accompanying world editor which incorporates windows forms to allows users to create and edit custom worlds to be played through the game engine.

Retiring Legend of Drongo

The LOD project has been going since 2012 and it’s starting to get to a little stale. As a developer I feel I have advanced far beyond the original intent of the game and I think I’m ready to hang it up before it keels under it’s own heavy, bulky and unnecessary code.

I had intended on making Drongo into a UI based game, using windows forms to generate graphics, however this is proving to be a great deal more difficult given the current flexibility of the code. The way the data is generated and saved and used is all outdated and poor. It was never really designed, more so just thrown together into some working model.

So I have decided to abandon the UI development of Drongo. I will revert the code back to a Console Application using only text as input and output, and just leave it with that. Eventually I may finish the environment but I do not plan on adding any more features to the game. As of now the UI for Legend Of Drongo has been scrapped and any fixes to the engine will be applied to the old console app setup.

That is not to say that this is the end. I have been considering for a long time to shelf the project and start fresh with my newer knowledge and attempt to make a Visual Engine from scratch, using elements from the first project. Which is why I’m happy to announce development on Legend-Of-Drongo-II, which will hopefully have some good progress as time goes on.

.Net Framework

My introduction to C# .Net began in 2013 in my final year of University during my introduction to Threading, & Windows Communication Foundation. From there my knowledge of .Net expanded to Web Forms, Windows Forms, Console Applications, MVC  and Cross Platform apps using Xamarin and UWP.

My coverage of .Net begins with 1.1 (due to supporting a very legacy project) and overhauling it to .Net 2, then eventually .Net 3.5 to ensure it was part of a supported framework. Newer applications built in the .Net 4.x family made up the majority of my projects and the professional products I worked with.

I first started to take notice of .Net Core in 2017 with the release of version 2.0 – the ability to run .Net applications on a cross platform meant that I could start to develop much more complex and modular code on my virtual Unix boxes, Raspberry Pis and EC2 instances.

While my focus on .Net has been with C#, I have also worked on some projects written in VB .Net.

Retro Graphics Engine

As part of the ongoing improvements to my text based adventure game, I decided to develop a retro style graphics engine to go with the text based aspect.

This meant having to upgrade the Console Application I had developed into a Windows Application without having to do a major rewrite of the engine; I did by creating methods which would complete the same job as the original Console method, but using a form instead of a console.

The central idea I had for my graphics engine would be to add a new string parameter to some data types and store the relative path to an image for that item. This would mean having to keep all the images in the file system with the game, so hopefully we can keep the size down.
Since I have moved the player command interface from a never ending loop to a regular method with a string input (so the UI remains responsive) I simply added a new method at the footer of the player input which triggers a drawing of the room.

The drawing method starts by checking if the Room/Building has a background image, then paints a panel with that image. If there is no image then it retains the previous. Then the method iterates through every item, enemy and NPC, and for every one of those items that has a valid image, it creates a picturebox element and adds it as a control to the panel.

Through this simplicity the game was able to build environments quite dynamically, when items are picked up or enemies killed the environment was updated.
The biggest issue I had was with placement, originally thought that I would pre-define some locations and the game would just place whatever data item at that place, however this meant that there could only be a finite number of images on the screen, and that no matter what the screen the images would always appear in the same place, which would not always make sense.

So I decided I could actually incorporate image painting into the world editor. If I extended the room editor form with a similar panel I could draw the room, and all I would need to do would be to add functionality to the PictureBox elements to be able to position them, then when the room is saved to scan through the locations of the panel, and assign the Location attribute of the PictureBox back to the data item. For this I had to add a Point attribute to the data items, and that meant having to add in System.Windows.Drawing reference to the project.

So originally I designed that when each picturebox was made, it had a mousemove method which would reposition the picturebox to the position of the mouse
public void DragNDrop_MouseUp(object sender, MouseEventArgs e)
{
PictureBox picBox = (PictureBox)sender;
if (e.Button == MouseButtons.Left)
{
picBox .Location = new Point(e.X, e.Y);
}
}

However there was a problem. The mouse event argument “e” had both X and Y attributes which held coodinates relative to that control. So when I started to move the control it would send the coodinates from within the panel, which would move the picturebox to the mouse location within the panel. But when the cursor was inside the picturebox the coodinates would be sent from within that control so all at once the picturebox was being sent coodinates to within the panel, and from within itself, but in both cases was being moved within the panel. Obviously this was a problem.

The solution, was to not use the global coodinates of the MouseEventArgs. It also passes in a Location attribute, which holds how far the mouse has moved in the X and Y axis. This meant that we could figure out the new position of the PictureBox if we took how far the mouse had moved and added it onto the original position, as below
public void DragNDrop_MouseUp(object sender, MouseEventArgs e)
{
PictureBox picBox = (PictureBox)sender;
if (e.Button == MouseButtons.Left)
{
int X = picBox.Location.X + e.Location.X;
int Y = picBox.Location.Y + e.Location.Y;

picBox.Location = new Point(X, Y);
}
}

This meant that the world designer would now draw the the room, and the user could paint it as they saw fit, and on saving the game would save the location of the data item so when the game is played, the environment was presented in a much more suitable fashion.

There is still an issue of items being carried. Default items in the inventory will not store Point data, and when an item is picked up and dropped in another room it will retain it’s original position, which may not always make sense but one step at a time.

© 2025 Joe van de Bilt

Theme by Anders NorenUp ↑