Game Design, Programming and running a one-man games business…

Writing your own engine for 2D games in C++: basic considerations

So with all the current stuff in the news about Unity/Improbable and the counter offers from unreal, and the big epic vs steam thing going on… I think there are probably a few developers out there who think to themselves… ‘I wish I *did* have my own engine, then I wouldn’t have to worry about ANYBODY else’s code. The problem is… if you are used to unity or similar systems, you might have no idea where to start right?

The windows basics:

To have an app that runs under windows you basically need just two functions, WinMain and a Windows ‘procedure’ function that handles windows message. A stripped down winmain looks like this:

int APIENTRY WinMain(
                     HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR pszCmdLine,
                     int nCmdShow)
MSG msg;

gInstance = hInstance;
GetGame()->InitApp();

//main program message pump loop//////////////////////////////////
while(1)
{
if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )//any for us?
    {
    if( !GetMessage( &msg, NULL, 0, 0 ) )//if so get em
        {
          return msg.wParam;
        }
    else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
else
    {
        if(BActive)
        {
            GetGame()->GameProc();
        }
        else
        {
            Sleep(1);
        }
    }
}
return msg.wParam;
}

The only two exiting parts are InitApp() where I create all the Directx3D stuff, and load in any data I need, and GameProc() which is basically the games main loop. The window proc looks like this:

LRESULT CALLBACK WindowProc(HWND hWnd,
                                 UINT uMsgId,
                                 WPARAM wParam,
                                 LPARAM lParam
                                 )
 {
 switch (uMsgId)
     {
     //main switch statement for handling messages
     case WM_DESTROY:    //end the application
         PostQuitMessage(0);
         GetGame()->ReleaseResources();
         return 0;
         break;
default://default behaviour
        return DefWindowProc(hWnd,uMsgId,wParam,lParam);    
      }
}

Again the only exciting thing there is ReleaseResources() which basically closes down all that directx stuff and releases all the textures and any memory I allocated.

meanwhile inside that InitApp() thing I need to do this:

int width = GetSystemMetrics(SM_CXSCREEN);
int height = GetSystemMetrics(SM_CYSCREEN);

Which gets the desktop res for me to create a window, and show it to the world:

gWnd = CreateMainWindow("Production Line", gInstance, IDI_ICON1, IDI_ICON1, WindowProc, width, height, bwindowed, bborderless, 0, 0);
UpdateWindow(gWnd);
ShowWindow(gWnd,1); 

After that I initialise all the directx stuff, which I have written about a decade ago, its pretty easy to grab all that from the directxSDK. BTW that CreateMainWindow function is mine too, and looks like this:

HWND CreateMainWindow(char* appname,HINSTANCE hInstance,int IDI_SMALL_ICON,int IDI_TINY_ICON,
                       WNDPROC proc,int width,int height,bool bwindowed,bool borderless,int left,int top)
 {
     WNDCLASSEX wcex;
HICON icon = NULL;
HICON iconsmall = NULL;
if(IDI_SMALL_ICON == NULL)
{
    icon = (HICON)LoadImage(NULL,"data/icon.ico",IMAGE_ICON,0,0,LR_LOADFROMFILE);
}
else
{
    icon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SMALL_ICON), IMAGE_ICON, 64, 64, 0);
    iconsmall = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_TINY_ICON), IMAGE_ICON, 32, 32, 0);
}

wcex.cbSize           =    sizeof(WNDCLASSEX);
wcex.hInstance        =    hInstance;
wcex.lpszClassName    =    appname;
wcex.lpfnWndProc      =    proc;
wcex.style            =    CS_CLASSDC | CS_DBLCLKS;
wcex.hIcon            =    icon;
wcex.hIconSm          =    iconsmall;
wcex.hCursor          =    NULL;
wcex.lpszMenuName     =    NULL;
wcex.cbClsExtra       =    0 ;
wcex.cbWndExtra       =    0 ;
wcex.hbrBackground    =    (HBRUSH) GetStockObject (BLACK_BRUSH);

RegisterClassEx(&wcex); 

int flags = 0;
if(bwindowed)
{
    if(borderless)
    {
        flags  = WS_POPUP;
    }
    else
    {
        flags = WS_OVERLAPPED |  WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_BORDER;
    }
}
else
{
    flags  = WS_POPUP;
}

HWND gWnd = CreateWindow(appname,appname,flags,
    left,top, width, height,
    NULL,//GetDesktopWindow(),
    NULL, hInstance, NULL);

return gWnd;
}

TBH the only fiddly bit is finding a program to actually create a decent windows ico .ico file in all of its myriad different sizes. Plenty of them exist, but its something you probably did not realise you need. I also have to use a batch file and a little command line thing to stuff the finished icon into the exe, so that it shows up in windows explorer as well as when the window is launched (weirdly these are different things…).

Thats pretty much all of the ‘initialisation’ code you need to create a windows app. Obviously you then need an actual graphics engine, but thats not *too bad* to write yourself if you are not coding something that is huge and requires amazing performance or tons of shaders.

In 2D, everything is pretty simple. You just need a sprite class (I have a Base Sprite, which is just 4 vertexes and a way to manipulate them by scaling, changing UV values, positioning them etc), maybe a textured sprite (the same but with a directx/opengl texture pointer), and if you want to optimise stuff you need a system that handles vertex buffers.

In general I just have one (big) vertex buffer that I stuff with sprites during the main game render loop, and then call draw() on it every time I need to change the texture or one of the render states.

Input stuff is pretty simple. You should just hook into the windows WM_LBUTTONDOWN messages and others like WM_CHAR, and do some processing on them. Way simpler than using middleware for all that. If you need to know the current state of a key you can use this:

bool CBaseInputManager::KeyDown(int key)
{
bool down = (bool)(GetAsyncKeyState(key)& 0xFF00);
return down;
}

I *do* use middleware for sound, but you can get pretty affordable, pretty simple sound middleware from lots of places these days. I have not updated my sound middleware for a LONG time. I don’t do any fancy sound processing so why would I? Playing an ogg file or streaming one…is not complex.

Now obviously if you have never coded outside unity, then there is a LOT of stuff you take for granted that you would have to now write some code for, but you only need to learn these things once. Loading in a file, or browsing a folder for files, is just a few lines of code. Even writing an absolutely bullet proof ini file loader that operates efficiently and correctly and without bugs is only 913 lines of code by my count, and thats a LOT of whitespace, helper functions and wrappers around it.

If you start writing an engine early, when you are still doing hobby games, preferably simple ones, you will find it quite easy to scale it up as you make more complex games. The code samples in this blog post have been stripped of their error checking, and some game-specific checks and extra processing to make them clear on first reading.

Basically every game I make involves me adding some new functionality to my engine. Production Line was the first game where I had to create an isometric object class, and isometric renderer (basically just a system to sort by Z and then render…), an animation compression system and some metric reporting and user-survey stuff, but that was probably just adding an extra 3-4% to the size of the total engine.

I wrote the multi-threading stuff ages ago (Democracy 3 if I recall), although I seriously improved it this time. The original windowed GUI system was coded for Starship Tycoon (OMG). Most of the directx stuff comes from Gratuitous Space Battles 2. The current text renderer dates back to Democracy 2 for its initial version. The vertex buffer code started in GSB 1.

Don’t get me wrong, there is a LOT of code in an engine, and it DOES take a fair bit of time, but its a big, long term investment that definitely pays dividends. I don’t have to worry if unity supports X or Y, or if it conflicts with Z, or if they are going to remove it without warning next week (or break it). All the code works in a style I like, and with absolutely zero bloat.

The source folder for my engine is 100 files and 620k total. Its not *that* big. Obviously it compiles pretty quickly and easily.

…and don’t forget you can still code using an IDE (Like Visual Studio) with built in code syntax highlighting and intellisense (I recommend visual assist!). Do not fall into the trap of thinking its unity OR just typing in a command line window without any help!

Is 2019 positech website redesign year?

I have been selling games a LONG time now (twenty years!). My first game to ever sell a copy was called ‘asteroid miner’ (later renamed star miner). Because in 1998 selling games online was all very ‘new’ I just used the root directory of positech.co.uk to store the shareware .zip file for my game demo, together with images not even in a folder, called ‘image1.jpg’ and other such unscalable stupidity. There was a ‘hit counter’ to show how many people had visited the website. A single screenshot, I think even a banner ad for someone else?

Anyway… the site has had a bunch of redesigns over those twenty years. it now supports https and even has a mobile version of the main page! it scales how much data it displays based on your screen resolution. (omgz). It now looks way better than it ever has, and currently looks like this:

Which is fine, and I like it, but there is a definite lack of consistency from an aesthetic POV the minute you leave the front page. Each game got a website designed ‘at the time’ with whatever cool ideas I had, or whoever I had hired to do the design. They all link back to the main page, and some of them even have ‘other games by positech’ hacked manually into the bottom of the page like this:

That approach never scales, because its just showing fixed games to people regardless how many years later it is, or the genre, or anything like that. Frankly I don’t shift many copies of Planetary Defence these days, so why even mention it. The approach is static HMTL, and its dated. Theoretically what I need is some sort of database driven website that shows my games, and cross links them properly.

Its not like I’ve never done it before, showmethegames.com was a vague attempt at that (although it never gained any real traffic). I could in theory code such a system myself, but I don’t want to spend the time (I am 100% busy developing Production Line & producing Democracy 4). The only motivation I would have for doing it myself would be that I HATE working with CSS/HTML code written by others, which is normally some over-templated bloated mess with at least 50x the code required to do the job.

So the question is…should I even be considering it? No doubt there are some great off-the-shelf products to build an online web store that would make it possible without a lot of hassle, but would I be losing the ‘feel’ of each individual games web page? Some of them have cool backgrounds, or videos surrounded by excellent artwork. Do I really want to reduce them all to the bland consistency of a steam store page style layout just for the sake of my own OCD and obsession with order?

Normally I would say no, but then i can’t help but think that steam, GoG etc all have standardised store pages, and nobody cares? Is the obsession with creating some sort of tailored ‘experience’ for visitors to your gaming website something that died out in the 1990s and we just are not accepting it yet. Its not like videos and lets plays and trailers are not a thing, do people really need a ‘shadowhand’ font on one page and the ‘democracy 3 CSS’ to give a different tone on a different game page?

I think there is an argument that the ‘big AAA studios’ who do this still are only doing it because its effectively 0.1% of their PR budget anyway, and they may as well cover all bases. In the end, isn’t a game really selling based on a screenshot, a short video, a review score, and the name?

The other way of looking at it, is what would be the upside? How many people buy big pharma direct from my website who don’t know we make production line, and would otherwise buy it right then (who would not have bought it at another point). Even if the number is 1% of total big pharma customers (and vice versa of course), is that really enough money to justify the cost and time to totally revamp the website?

I suspect, sadly it is not, and this may be relegated to a ‘wishlist’ thing. My own OCD and the fact that I think the current mishmash looks ‘amateurish’ are what is really driving me here, not any sort of business case. Its not like I’m looking for outside investors who may be put off by the aesthetics of my web page, and I really don’t care what people who are not customers think anyway.

Maybe I’ll reconsider it again sometime in 2029?

The best ever recommendation system for online games stores

The change made by steam from a simple store front to a dynamic one based on who is logged in was a huge improvement. I was extremely pleased to see them do that. I find that for me, their algorithm actually works pretty well, and other stores are definitely not as good (yet). But lets stop congratulating things that already exist and remember three really important facts here.

Its 2018 and computers are fast as fuck

Most online web stores have a LOT of money

Most online web stores have a lot of clever coders working with them.

And now lets imagine all the factors we REALLY should be able to plug into some clever neural net that decides what games to show somebody. Starting with the trivially stupidly simple ones;

SIMPLE FACTORS

The genre of the game as defined by the developer vs the players preferred genre from playtime of other games or stated preferences

The weighted-values of all the tags associated with that game against the similar weighted values of tags that apply to the games the player has played (weighted by time and tag relevance).

The current price of the game compared to the usual purchasing p[rice at which the player either buys or wishlists / follows the game. (don’t show $59.99 games from a publisher who rarely discounts to someone who never buys a game over $5).

Really dumb stuff, like if the game is a sequel (determined by a scan of the name) to a game the player liked (or opposite if sequel to ignored), or made by the same developer.

Super-super-dumb stuff, like the platform must match the platform the player usually plays, and skew towards multiplayer if they only play multiplayer stuff, language option should include those the player usually has for the store interface.

NOW LETS GET CLEVER

We need to build up a major hidden customer profile that contains as much information about the player as possible. Stuff they enter into their profile page is a cute start, but its the absolute tip of the iceberg. Does the player have a lot of friends who are playing game X, and can we weight that by how *close* those friends are (by statistical analysis of the chart frequency and posting in similar discussions). Do those players have large average play times, or better still, have thy left multiple comments, or positive reviews. If so, factor that in when showing the game to them.

Is the player a bargain hunter? what percentage of their games were bought at each price point and each discount percentage. skew the game presented to them that match this purchasing pattern.

Do we know the players birthday? if so, send discount coupons to their close friends for games that are on their wishlist, to encourage them to buy those games for them in the week before their birthday. Skew those coupons to match the calculated likely purchase level that we can get from each friend.

NOW LETS GET EXPERIMENTAL

We only know about a game what the developer tells us, and use that as the final information on that game. Asking players to tag games is great, but surely we can go further. Internally we can know if a game is viral from the amount of instances where someone buys a game, and then a close friend of theirs buys that same game within a certain window. The virality of a game should act as a positive that results in us showing it to more people.

We can also re-evaluate all of the reviews left for a game to get a more accurate picture. If a player leaves 95% negative reviews, then they are basically just a bit grumpy, and we should skew the relevance of their reviews to the score. A player leaving overwhelmingly positive reviews, probably needs analysis to see what percentage of games they review, and if they were dissatisfied with other games but never leave negatives. If analysis of their playtime/refund rate, forum-participation and chat mentions suggests that this is not the case, and they are unusually positive, maybe skew down the relevance of their reviews too?

Reviews cores for a game being the same for everyone is a joke. Maybe everyone hated the game except for the 30 players who we estimate to be young Chinese players who tend to like funny games with certain tag combinations. If I match those reviews profiles really closely, I should see a review score FOR ME, showing how much people like ME, like the game.

Computers can analyse video pretty well now. Get an algorithm to watch 100 hours of youtube videos (or uploaded player videos) of every game, and try to draw some statistical analysis from it. Is the game clearly a fast moving, high contrast particle-fest bright explodey sort of game? Make a note. Is the game a slow paced, relaxing game with subtle color scheme? make a note. Is it clearly a brown man-shooter? etc…

Its 2018. I shouldn’t have to explain to people that production line has a similar aesthetic or feel to factorio and big pharma. an algorithm can do that for me.

Maybe some of this is impossible, or even undesirable. Its certainly a challenge. But the online store market wars are heating up. If you run a games store and do NOT have a bunch of coders attempting this sort of thing…well maybe you should look into that?

We donated another £9,416.88 to war child. Yay!

For the last few years Positech has done this thing where we basically take all of the money we earn from steam sales of Democracy 3 or any of its DLC during the War Child Armistice, and give all of that money to them. We just got our royalty reports and crunched the numbers, and this year that sum is £9,416.88, which I think is pretty good.

Basically if you bought democracy 3 or its DLC from the 6th-13th November this year, we gave all the money (well, our cut of it) to charity. This is the third time we have done this. The first time (which was the original armistice event), it was £15k, last year it was £10.1k, so its going down a bit, but on the other hand, we have contributed about £35k now, which isn’t at all shabby. To put all this into perspective,.. Positech is basically one full time employee (me!) and some contractors, although Jeff (D3:Africa,D4) is pretty much full time now). Imagine how awesome it would be if we could persuade some really big profitable games companies to do the same thing?

If you are wondering what on earth war child is, you can read all about what they do on their website here.

And if you are somehow here not knowing what Democracy 3 is, its a game we made about politics and elections and running the government, and we have a website about it here.

Three Years with an electric car in the UK (Tesla model S)

So its roughly three years ago that I bought my dream car, a Tesla model S 85D electric sedan. I wrote a blog post about it at the time, and another after a year of ownership. I thought it would be fun to look back after three years and see what I thought now I’ve owned it for so long.

So the first thing to note is that this is a model Tesla do not make any more. It has an 85KwH battery, and they only make 75 or 100 now. If I had to buy a new one now, I’d go with 100. I don’t *need* it, but I’d rather not go down to 75 given the fact I live somewhere so remote. YMMV. I still wouldn’t get the super fast P model or the insanely fast Ludicrous version. My car has the old fashioned ‘false vent’ front rather than the slightly snarly pinched front, which I prefer, but other than that, its pretty much the same car they make now. I have autopilot hardware 1, which sadly is not upgradeable. I would *like* to have AP2, but not enough to buy a new car, not for a long time anyway. AP1 is still pretty amazing.

In terms of reliability, its been superb. nothing has gone wrong *at all* since the original door handle issue I had, which was quickly and permanently fixed. I do get the occasional glitch with the playback of USB mp3 files or podcasts through the built in podcast browser thing, but a quick swap between sound sources almost always fixes it. This could also be something to do with the fairly flaky network coverage where I live.

Mechanically its been fine, no noticeable battery degradation at all, performance still awesome, same tyres, nothing replaced, nothing rattles, nothing broken. Still awesome.

Cost-wise its hilarious. I worked out recently I spend more money on having the car cleaned 4x a year than I do on my fully comp car insurance. ‘Fuel’ wise, it still works out at about 4p a mile, and its too new to need an MOT. Its been serviced once, and there was absolutely nothing wrong with it. I’ve never owned a car so staggeringly cheap to run.

Probably the biggest *problem* I’ve encountered has been my own self-imposed dumbness on charging it on two occasions (in 3 years). Once was me being really tired and not wanting to bother stopping on a trip back from London with a low battery, so ploughing on regardless, and having to go *pretty slow* for the last 20 miles to make sure I made it. Another was me forgetting to plug it in one day, and then going on a long road trip anyway with not quite enough charge, and very cold weather (reduces range slightly). This was entirely my own dumb fault, the car warns you and helps you manage it etc. I’ve never actually run out of charge or been stranded anywhere in 3 years.

The thing that surprises me about the car, is that in the three years that I’ve owned it, NOTHING has come along to compete with it whatsoever. The Nissan leaf is way cheaper but even the new version has tragically short range by comparison. The BMW i8 looks a bit ridiculous and is overpriced. The Audi e-tron and Porsche Taycan are apparently meant to be competitors, but neither is widely available and they have no supercharger network like Tesla does, nor are they able to buy direct without a middleman taking a cut. Most of the ‘tesla-killers’ are just fantasies in a legacy car company’s power-point presentation right now. Basically I am EXTREMELY pleased with the purchasing decision that I made. I was never really a car obsessive (despite making a game about them now) but I can honestly say its the best thing I have ever bought.

There is still part of me that would prefer to drive a Tesla Model 3 (not available in UK yet), although the crazy model S performance has spoiled me and I’d need a performance version. I would prefer its smaller size, mainly for ease of parking, but I have to say I really would miss the large touchscreen. The model 3 one looks tiny by comparison (although it still dwarfs those in most cars). In an ideal world I’d also have an all-glass roof, which wasn’t an option when I got mine (I have a sunroof).

I’ll likely keep the same car for a few more years yet, as there is nothing wrong with it, they hold their value very well, and the battery degradation is a rounding error. If you have off-street parking, and can afford one, I cannot recommend them highly enough. If you want a referral code (you get free supercharging for six months as I recall) mine is: http://ts.la/cliff7605