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

Gratuitous Space Shooty Game released!!!

And you probably thought I wasn’t still making games right?

After the long and intense development of Democracy 4, which is a HUGE sprawling game with a LOT of code, and a ton of content, and is now in about 10 languages and has 3 expansion packs… it was nice to be able to make something small, and simple, and not at all commercial or serious. With that in mind I started messing around making a space-invaders style vertical shooter, using the art assets I have from an older game of mine: Gratuitous Space Battles.

GSB is pretty old now, but TBH the spaceship graphics for it still look incredibly good to my eyes. I generally think its very wasteful that the games industry hires so many people to make music, SFX and graphics, and then makes a single game with them, never to be re-used in any way. Frankly a spaceship is a spaceship, whether its used in an RTS or a shooter or a turn based grand strategy game.

I know some people worry that gamers will bombard you with abuse for daring to use the same artwork in another game, because they will feel ‘cheated’. This strikes me as utter nonsense. Sensible re-use of assets just makes sense. As a general principle I hate waste, and I love efficiency. Also, not doing something because a tiny, tiny percentage of vocal gamers may complain about it is definitely a losing strategy in gamedev. There are always people who complain about any choice you will make.

After working on this game for a bit, and initially thinking it was a little throwaway thing I’d probably keep to myself, I started to really enjoy its development. I have never made a vertical shooter, but I loved Star Monkey, which is very old, and I am old enough to remember the first space invaders arcade cabinets as a kid, as well as Galaxian (far superior imho) and then Phoenix and the rest. I also spent a lot of time playing Astrosmash on our intellivision console as a kid.

Gratuitous Space Shooty Game is a bit of a mashup of a lot of those shooters, with some extra ideas that occurred during development. My wife playtested it a lot, and HATED the asteroids, so I added a repulsor beam to keep them away from you. Once implemented, it became a very cool new gameplay mechanic, as it allowed you to ‘balance’ attacking ships above you to get some extra shots in before they leave the screen.

During development I experimented with a bunch of ideas, and after a lot of playtesting, I’m happy with what I chose to do. The fact that you can accidentally shoot ship bonuses gives the player an incentive to keep moving and not risk a volley destroying a bonus. Penalizing you for every ship that escapes, INCLUDING the left-right ‘saucer’ ships also adds to the challenge. Making it so that the best power-ups are only dropped by those ships was also a good move from a design POV. Adding friendly ships you have to avoid is an evil mechanic, but its still in there!

In the end I went with 25 levels, and the levels get slightly longer as you go along. I don’t do any adaptive difficulty stuff, although I considered it. I do offer 3 difficulty levels from the start though. The top one is seriously hard. In-between levels you get to spend your cash, earned from shooting aliens and collecting bonuses (and a cool 10% bonus if nobody escapes) on upgrades for your ship.

Right now the game is only on itch, for $3 with a suggestion of $5 if you want to. It will not be a big financial success :D. Because I was doing it for fun, its currently windows only, and fixed aspect ratio of 1920×1080, or scaled to fit fullscreen. Windowed option literally went in the day before release :D. Its English only for now. I may try a google-translate for the limited text at some future point if I do an update to it.

So there you go, its another game by me! the first non-strategy one for a long time. I’m quite proud of it. Its a fun short laptop-friendly game you can play in lunch hour or multiple coffee breaks. If you like the look of it, get a copy!

Programming in just ONE language should be lauded.

I recently read about the news that garbage collection support, which was added to C++, is now actually being removed from it. Apparently most people didn’t use it, or even knew it was officially added, so it is no great loss. It always shocks me to read articles about C++ with a version number, because as far as I am concerned, C++ has no version number and never will, in the same way that a language such as English has no ‘version number’. I’m 54 and its pretty rare that I add a new word to my English vocabulary, and its even rarer for me to learn something new about C++ that I start to use in my code.

Back in the early days of modern computing. I worked in IT. My CV was basically: CNA, MCSE. That was it. That was all you needed to earn £54k a year 30 years ago in IT. There were basically 2 big computer systems, run by Microsoft and Novell, and your IT dude ideally knew them both. That was a long time ago now, and the amount of buzzwords and brand names the average IT admin has to put on their linkedin profile is probably quite ridiculous. However, I think its worse in the land of software engineering.

Again, go back a while and you were probably pretty employable if you could just mention C and C++. Then Java became a big deal, then a bunch of other stuff appeared. I have no idea whats cool now, but it feels like Python, Rust are much in demand. Then you have to add all of the recent methodologies. Do you know Agile and Scrum? How familiar are you with AWS? Whats your AI/ML skills like? PyTorch? Do you know the buzzword technologies that will get you hired this year? You better get a job quick, because the buzzword technologies will change every 2 years. Did I say 2? I meant ever year. No sorry, month.

I recently found myself thinking about poetry and code. My wife writes poetry, so I am exposed to this stuff. As a writer, she spends a lot of time… a LOT of time deciding what words to use in a sentence. Its a big deal. Sentence-by-sentence writing is an absolute skill that takes most people there entire life to perfect. Its worth noting that few poems are praised because they use the latest hip words. Good writing is not a matter of having a large vocabulary. Needlessly obscure word-choice is rightly seen as pretentious and alienating.

We really need to take some of that perspective and apply it to code

Take this sentence: “It is a truth universally acknowledged, that a single man, in possession of a good fortune must be in want of a wife.”

Thats considered literary genius, and it is. But its not using arcane language. Every word is commonplace. And idiot could have put that sentence together! but it took Jane Austen, and considerable experience, and huge skill to do it. We do not mock Jane Austen because she could only write in English. We do not mock her because she only wrote from a woman’s point of view. We do not mock her because all her novels were contemporary, in a similar setting, set in a single country, with a linear narrative. We accept all of those limitations and accept that she brings incredible skill to use a limited set of tools to create genius.

Imagine a modern programmer trying to get their first novel published. “English, yup I could write it in English, French, Italian, Chinese or South Korean if you like? I can do all the genres, yup, no problem. I can do first or third person if you like, and I’m familiar with fractured narrative or linear. If you want it funny I can do that, or harrowing, or in short story form too if thats what you are looking for.”

Madness

For some reason, people think that ‘proficiency’ in a programming language is something as superficial as being able to say ‘hello’ or order a beer in another language. This is insane. I am able to say ‘Hello’ ‘Thankyou’ and ‘Sorry’ In Korean, but you wont see me apply for a job writing Korean-language fiction.

If you have under ten years experience in using a programming language, let me be blunt and tell you that you don’t REALLY know that language. 20 years is better. 30+ years is ideal. Do you really think you speak French like a native after speaking if for a few hours a day for a few years? Of course not. Thats laughable. And here is the thing: A mistake in a language can cause confusion and maybe embarrassment, but unless you are a lawyer writing contracts, its not CRITICAL. Miss-using C++ can cause rockets to crash, reactors to overload, and god knows what else.

Why do we accept a superficial understanding of a language that is safety critical, but expect mastery of a language by anyone paid to use English?

I know C++. Thats it. A little bit of php, but a trivial amount. I use container classes and std::string from STL but thats it. A very few macros. My C++ vocabulary, even after 28 years using it, is tiny. The amount of std library stuff I know is very small. And yet… I can type C++ with as much confidence and speed as I type this blog post. In fact I can write C++ faster, with fewer mistakes than I can English. In many ways, I am MORE fluent in C++ than English. I code almost every day, and love it. I feel absolutely that I know what I’m doing, after 28 years, and a subset of C++.

The world is full of people claiming to have that fluency with 12 languages, and they are often literally half my age (I’m 54). This is utter bollocks. None of those people should be allowed ANYWHERE near mission critical code, or any code even tangentially involved with safety or security. I am sure that they ARE doing those jobs, every single day, because they all confidently think they are experts, and the people hiring them do not know any better. It a recipe for disaster, and its why year-after-year, software gets WORSE. Windows 11 runs dramatically worse than Windows 3.11 did, and it does it on hardware ludicrously faster. Skype is running at about 0.1% of its potential efficiency, has scrollbars that do not function as well as windows 3.11 did, and uses easily 100 times the RAM it needs.

Your computer is an absolute trainwreck of clusterfucks crashing into a dumpster-fire of wasted resources. All the people involved in arranging the trainwreck think they are multi-skilled geniuses, but hardly any of them have any real understanding of the code they write.

It doesn’t have to be that way.

We don’t appreciate Picasso based on how many colors he used, or how many styles he knew. We don’t berate any musician for only knowing one style. In Japan, people who make the SAME SUSHI DISH their entire lives, without variation, are considered legends, and experts. Its the norm in South Korea for restaurants to only serve one dish (but do it WELL).

I beg of you: If you are involved in recruiting software engineers, for the love of god only employ people who have real, genuine experience, measured in years but preferable decades, for stuff where you expect them to be able to code from day 1. No, they will not ‘pick it up quickly on the job’. Hiring interns or juniors is different, obviously.

I know I’m an old man yelling at a cloud, but sometimes old people know a lot about the cloud. I’ve been coding since I was 11, and its taken me this long to realize that programming languages should be treated like any other language. It might not be a popular view, but I want to put it out there. Experience really matters.

Gratuitous Space Shooty Shield tweaks

Maybe there is an easier way to code this, and I’m sure 99% of devs would just unity and copy paste some asset store effect, but I like to code these things myself becausae I like the intellectual challenge, and it gives you total freedom and zero dependencies so here we go:

I just finished coding a ‘shield impact effect’ for Gratuitous Space shooty game, and thought I’d explain how its done. The idea is that the ships are surrounded by energy fields, with various grid patterns, and when laser bullets hit them, they generate a sort of encapsulating ‘wash’ effect over that portion of the shield. To pull this off, I need two things: It needs to be clear where the impact hit the ship, and it needs to feel like it wraps around the target in 3D.

How do you do that in a 2D engine?

The first challenge is getting a graphic that looks like a ship shield in 3D. This is easy. You just get any pattern you want, such as a hex-link pattern:

Then you use the photoshop sphereize distortion filter to give you a nice alpha channel map of a cool space shield:

If I just blap that on top of a spaceship thats hit by lasers, you get a nice effect, but the problem is its non directional, and its pretty clear that its just one image placed on top of another. What I need to do, is to draw this image, but only bits of it at a time, and to wash over the image, revealing it over time.

The way I found was best to do this was to enlarge that texture a lot so it had a ton of empty space, and then use it at twice the size. The reason for this will become apparent, but I’m not working with this:

What I then do, for my shield effect is to use a sort of 2D mesh to wrap around that image over time. That wrap-around effect will originate from the point where the bullet hits the shield. To do this, I get the bullet position, then get the angle from shield center to bullet center, and travel the exact shield radius along that angle from the shield center. That gets me an EXACT location on the perimeter of the shield, even if the bullet is super fast and has already moved inside the perimeter. This is important!

So I now have the impact location, and I want to kind of ‘wash’ the image of the sphere into the players view over time like this:

The red dot is the impact point, the yellow rectangle gets thicker over time as it washes over the sphere. To do this, I ‘virtually’ place the sphere texture on the screen, but do not render it. Its there just as a placeholder for where the ‘full’ sphere would be if it was all revealed. I then calculate how to position that rectangle, and over time I stretch it so it completely covers the target sphere. In order to render the composite image, I render the yellow rectangle, but when I get the UV values of each vertex in the rectangle, I actually look up where they are in relation to my oversized virtual sphere and use that UV value, but the texture of the sphere.

This is why I had to enlarge the canvas the sphere is on, so that those UV values make sense and are still 0 to 1 in both directions. When I do this, I get a cool effect, but its basically a watermelon (shown here with early rubbish shield texture)

To fix that, I just need to set the color values of the ‘inner’ vertices at the top of the rectangle to be fully transparent, and I then get a nice fade effect over the sphere. To be honest, that looked fine, and I was happy with it, but even though NOBODY would notice, something annoyed me…

When you imagine something wrapping around a sphere like this, from a top-down view, you would notice that the speed at which the ‘frontier’ washes over the sphere is non-linear. In other words, I’m not taking any account of the curvature of the sphere itself. To do things right, the speed at which that rectangle washes overs the sphere should vary along the length of the top of the rectangle. To do THAT, I need the rectangle to actually be a tri-strip, so I can curve the top edge. And not only that, the speed at which the center point of that edge moves needs to be a nice curve defined as a sine wave…

In other words I need to achieve this:

That wireframe thing is my yellow triangle. Over time it will wash over the whole shield right to the back. here is two overlapping impacts:

You can see whats going on quite easily in the wireframe version there. The game is way too fast and gratuitous for anyone to notice, and TBH I am still tweaking it.

One of the really fiddly bits was getting that curve just right. I had to start at the left hand top of my yellow triangle, and go across the top edge, noting my progress along there. I then interpolated between the extent to which the ‘height’ of the rectangle came from a fixed point (I picked the top left at the ‘back’ of the shield’) or from my sine-eave inspired non-linear curve of the point that represented the center of the rectangle.

At the end of all that I then basically have a single tri-strip. I then run some separate code to derive UVs from the ‘virtual’ sprite, and just render it. For those who care about the details, here is the code for what I’ve described:

void GUI_ShieldRipple::CalculateVerts()
{
	//place relative to the shield
	float radius = PParent->GetGlowSprite()->Width / 2;

	//we have a tristrip here that is angled at RippleAngle and whose bottom center is at
	//InitialImpactOffset from the current shield center;
	float shieldcenx = PShip->GetWorldPosition().X;
	float shieldceny = PShip->GetWorldPosition().Y;

	//derive bottom center
	float radangle = D3DXToRadian(RippleAngle);
	float cosangle = COS(radangle);
	float sinangle = SIN(radangle);
	//note this is the inverse because the angle is from offset to cen and we want the reverse
//	WorldPos.X += (sinangle * ourspeed);
//	WorldPos.Y -= (cosangle * ourspeed);

	float botcenx = shieldcenx - (sinangle * radius);
	float botceny = shieldceny + (cosangle * radius);

	//now turn 90 degrees to the left to go to the start
	float angletostart = RippleAngle - 90;
	if (angletostart < 0) angletostart += 360;
	radangle = D3DXToRadian(angletostart);
	cosangle = COS(radangle);
	sinangle = SIN(radangle);

	float botleftx = botcenx + (sinangle * radius);
	float botlefty = botceny - (cosangle * radius);

	//invert for right
	float botrightx = botcenx - (sinangle * radius);
	float botrighty = botceny + (cosangle * radius);

	//how wide is each block of the tri-strip
	int prims = (MAXVERTS - 2);

	float chunkwidth = PParent->GetGlowSprite()->Width / prims;

	//now deduce chunkheight, which is basically our travel over the shield at the center point
	//we have non linear progress here, and we deduce that from a cosine wave curve imagined from 
	//Pi to 2xPi
	float cosinput = D3DX_PI + (D3DX_PI * Progress);
	float adjusted_progress = cos(cosinput);
	//now convert to 0 to 1 instead of -1 to 1
	adjusted_progress = (adjusted_progress + 1) / 2;

	//this gives us the center value, of the middle of the sphere
	float chunkheight = radius * 2 * adjusted_progress;

	//get top of the strip above the botleft
	radangle = D3DXToRadian(RippleAngle);
	cosangle = COS(radangle);
	sinangle = SIN(radangle);

	float innerx = botleftx + (sinangle * chunkheight);
	float innery = botlefty - (cosangle * chunkheight);

	//start botleft then up, then to 1 along and down...then up
	float currx = botleftx;
	float curry = botlefty;
	
	float offsetx = (botrightx - botleftx) / (prims/2);
	float offsety = (botrighty - botlefty) / (prims/2);

	unsigned long fullcolor = RGBA_MAKE(20, 234, 221, (int)(255.0f * Intensity));
	unsigned long nocolor = RGBA_MAKE(20, 234, 221, 0);
	for (int n = 0; n < MAXVERTS; n+=2)
	{
		Verts[n].dvSX = currx;
		Verts[n].dvSY = curry;
		Verts[n].color = fullcolor;

		//to get innerx we need to adjust between the full corner value and the middle adjusted
		//value based on our progress
		float progress = n / (float)prims;
		//convert that progress to a nice curve
		progress = sin(progress * D3DX_PI);

		//thats the extent to which we get the adjusted value rather than the base value of   chunkheight being radius
		float newheight = (radius * 2 * (1.0f - progress)) + (chunkheight * progress);
		float newinx = currx + (sinangle * newheight);
		float newiny = curry - (cosangle * newheight);

		Verts[n + 1].dvSX = newinx;
		Verts[n + 1].dvSY = newiny;
		Verts[n + 1].color = nocolor;

		currx += offsetx;
		curry += offsety;
	}
}

Its a lot of C++ to just generate that effect, but I love coding this stuff. I might change it so that the top left and right points of that rectangle are in fact the mid point, so the curve goes flat then inverts. I think that may look better. Also I’ll fiddle with render states and lightmaps to make it fizz more. In the meantime I uploaded a video to twitter showing it with, and without the wireframe. There is a lot going on, and there can be multiple overlapping effects at once. Thats another reason I needed to use a virtual shield texture for UVs, this way everything lines up perfectly, even with multiple impacts:

Gratuitous Space Shooty Game will be on sale on itch soon

A longer perspective on the unity pricing fiasco

So everyone in the games industry by now is aware that unity, the company that makes a very popular game engine, announced a new pricing scheme, whereby as well as charging you monthly for everyone who you wanted to employ to use their software, they also felt that you should pay them every time anyone, anywhere installed any software that had been made using their engine.

LOL

There is a lot of online outrage, and justifiably so, and to be honest, there is not nearly enough outrage enough. My perspective on this is different, because I’ve never used unity (I tried once and despised it), and have nothing at stake here. Every game I have made has had its engine coded by me, and I pay nobody anything for the privilege. I thought it might be worth blogging my view, because I think its a different one to everybody else. I’ve been thinking it over, and reckon the best way to articulate my thoughts is a series of separate points

Point #1: You probably don’t even need a commercial engine

A lot of people who read this will be indie game developers like me. A lot of you probably make 2D games. 2D games are great, they sell well, they can be very commercially successful, and there is little to no stigma making a 2D game. Some of the most popular games you can buy are 2D. 3D games are harder to make, from an engine POV, but if you don’t want to pay for a commercial engine, then there is a lot of mileage in 2D gaming. I’ve had a 25 year indie gaming career doing entirely 2D games, sold millions of copies, made millions of dollars. Production Line was isometric, but still just a bunch of sprites. None of the games I have shipped needed a commercial engine. Prison architect was a smash hit without needing a commercial engine. If you are wondering how successful you can be before needing to license an engine, the answer is: Hugely fucking rich and successful.

Point #2: If you need an engine, lots of free ones exist

Unity costs money, but many other engines do not. A good friend of mine paid $80 for a simple 2D game making program and has shipped 10 games with it, and made a living doing so. He is not the only one. There are more game engines than would possibly fit in a normal blog post, and no shortage of reviews from developers to guide you in making a choice. Free engines also have the bonus of coming with source code, so if you don’t like something, you can just change it.

Point #3: Lock-in is always a nightmare for consumers. Why are you surprised?

Every time a company talks about walled gardens, what they mean is they want to screw their customers. Starbucks will blatantly open a dozen unprofitable coffee shops in one town to force every competitor out of business, then shut the excess ones down and milk that profitable local coffee monopoly. Its a known business strategy, and its evil as fuck. Apple HATE the idea of shipping a USB connector with their phone (a supra-national government had to force them to do it), because they want to keep their customers locked into their ‘ecosystem’. The same was true of itunes, which they deliberately made crash, and buggy and slow on anything that wasn’t apple hardware. Its all about the ‘ecosystem’. Let me help you recontextualize this. When someone in a suit (or a black turtleneck) talks about their ‘ecosystem’, they actually mean a different word: Prison.

The ideal for these predatory businesses is to make it impossible for you to leave. Governments always have to intervene to prevent big business acting this way. Unity was VERY keen to force you to be reliant on them for everything. You buy your art assets in the UNITY store. You use the UNITY engine and the UNITY editor, and sell ad space using the UNITY ad system. Steam is similar. Steamworks is not a charitable gift. They want you to lock your achievements, your stats, your community, your interactions with your players all within steam. This way you will never leave. You can’t, they have you. Unity owns all your tech, steam owns your community, youtube owns your video channel. What do you own? Your office chair maybe? Expect to see Herman Miller asking for a share of your game revenue soon.

The actual walled garden apple execs enjoy thanks to us.

Point #4: Engine coding isn’t that hard

I knew we were heading for an apocalypse the minute we started seeing job adverts for ‘Unity programmer’. Thats not a language, it a proprietary product by a single, private company. If you really want to be 100% dependent on the whims of a private company for your future employability, go work there! Do not pretend that you can ‘exist independently within the ecosystem’. Unity LOVED the idea that people would stop being AI programmers or C++ programmers. Unity programmers have no place else to go..

..but actually, when you look at game engines, especially 2D ones for indie games, they are really *not that hard*. Its not 1990 any more. We are not having to worry about makes of mouse or video card. Directx makes things very simple for you. Its just a few hundred lines of code, at most, to have access to the graphics card, to be able to load in textures, play sounds, and respond to user input. This stuff is super-well-documented and TONS of sample code exists. Reading user input is really, really easy. Creating a sprite, loading a texture from a folder, and drawing it onscreen is actually pretty simple stuff. Particle systems and multithreading are NOT simple, but also not rocket science. Do not underestimate how much FREE stuff there is out there explaining how it all works…

Point #5: Software subscriptions were the line we shouldn’t have crossed

I remember back when adobe started trying to get people to subscribe to photoshop, thinking that this must be an April fools joke, or the rambling of a delusional coke-fueled imbecile who staggered into the board room. The idea that SOFTWARE was something that had to be rented instead of purchased was a joke to me.

Heres the thing: Microsoft are actually pretty fucking good at their job. Windows 11 will still play a game I made in 1998, without errors, or compatibility screwups or grumbling. If there ARE any issues, there are tons of compatibility options to make it work. Why mention this? Because its evidence that its pretty clear that you can write software that just keeps working, and working and working.

Software subscriptions are a joke. This is a way to force you to continually pay, without limit, for a package of software that should have been an affordable on-time purchase. Photoshop is an image editor, its not doing protein folding. Microsoft word is a word processor, thats it. This is stuff that we, as a technological society, kinda worked out how to do 20 years ago. The overwhelming majority of ‘new features’ added to Microsoft office in the last TWENTY years are useless, and go completely ignored by everyone. Photoshop was done, finished. So was Excel, and Word. But they wanted to find a way to make you keep paying…

I have no problem with unity, or any game-development engine/IDE saying ‘Hey guys! We just finished a BRAND NEW version of our popular and much loved engine. If you want to upgrade from your current version to this one, its $500!’. Thats a perfectly viable, perfectly understandable business. But I guess if you are TERRIBLE at running your business, stupidly think you need 8,000 staff at unity, blow a bunch of money on an ad-monetization company, buy a movie SFX company, then suddenly realize you are losing money like crazy, then you have no choice but to try and squeeze more money from existing customers on a regular basis. Don’t expect Unity’s CEO to understand game dev BTW. He is a pure-management type with a background at pepsi and Hagen Daz ice-cream, A golf company and sara-lee, the donuts people. He neither gives a fuck about, or understands the games industry.

Final point #6: Unity’s dysfunctional management and terrible business is their problem not yours.

Its pretty clear that the top management at unity do not code, do not make games, never have, never will, don’t care, and here is the very worst bit: are absolutely fucking clueless at running a business. Its laughable. My company is way, way more profitable than unity, and I manage that with just me. The important point is: THIS IS THEIR FAULT. Its not yours. People saying ‘to be fair, unity do lose money’ are implying that somehow game devs made them lose money. Nope. Game devs have been paying these people through-the-nose for years for an engine that is so bad that even unity could not make a game with it.

I really, really hope that this is a turning point and people tell unity to get stuffed. This is a company that cannot be trusted, should not be relied on, that you should not deal with. Now I know that they have ‘tech we wont explain’ to ‘track installs’ which no doubt phones home to unity, I am not even going to have any unity games installed on any hardware I own. This is a casino and F2P ad-tech company LARPing as a game dev tech firm. I do not trust them one bit. Asking for a subscription fee should have had them laughed out of the industry. This latest madness is just proof they will never change, only get way, way worse.

Code Breakdown for Gratuitous Space Shooty Game

I code my games in C++ using visual studio 2015, and some help from visual assist from whole tomato (basically improved intellisense). I coded my own engine, but as GSSG is a simple 2D space shooter, thats easily good enough. I thought just in case anyone who reads my blog is learning C++, it might be interesting to describe some of the code.

The core part of the game is a function called GameProc, which is what gets called from the WinMain function in a loop, assuming the game is running, and its super simple:

void Game::GameProc()
{
GetInput()->Process();
GUI_GetSounds()->Process();
GGame::GameProc();
}

Thats the whole game loop! But obviously most of the relevant stuff happens in other classes. The basic principle is important though. My games reads all asynch user input (basically its checking the keystates for the keyboard), then it processes the sound engine, then the core game does its thing in a separate class. User input from mouseclicks and key hits is handled differently. I go through the windows messages for my app, and handle them as they happen outside this loop.

The fun stuff happens in that second GameProc function, which looks like this:

void GGame::GameProc()
{
	HRESULT result = GetD3DEngine()->GetDevice()->TestCooperativeLevel();
	if (FAILED(result))
	{
		if (result == D3DERR_DEVICELOST)
		{
			Sleep(50);
			return;
		}
		else
		{
			RecoverGraphicsEngine();
		}
	}
	if(PCurrentGameMode)
	{
		PCurrentGameMode->ProcessInput();
	}
	if (BActive)
	{
		GetD3DEngine()->BeginRender();

		if(PCurrentGameMode)
		{
			PCurrentGameMode->Draw();
		}

 		GetD3DEngine()->EndRender();
		GetD3DEngine()->Flip();
	}
	else
	{
		ReleaseResources();
	}
}

This is more interesting! Lets go through it. This code first checks to see if we somehow have lost the focus of the graphics driver, and if we have, it just pauses for 50ms and checks back later. Ideally everything then recovers from losing directx, and gets rebuilt. This sort of stuff isn’t really a problem now, as everyone is using non-exclusive borderless windowed mode, so its kinda legacy. The main game stuff comes next. The current game mode reacts to input, then assuming the game is still running, we begin the scene, draw everything and then end the scene, copying the backbuffer to the screen with flip.

So where is all the actual game code I hear you ask?

The trick is that PCurrentGameMode pointer. This is a pointer to an object thast represents the current game mode, and which one is selected and current is based on what we are doing. Right now my game has one object for the main menu, one for the (debug only) level editor, and one for the main game class. To make it interesting, lets check out the code for the main game objects call to Draw():

void GUI_Game::Draw()
{
	SIM_GetGameplay()->Process(); 
	GetD3DEngine()->ClearScreen(RGBA_MAKE(0, 0, 0, 255));
	GetD3DEngine()->ClipViewport(GetGame()->ScreenArea);
	if (GetGame()->GetGameModeName() == "game")
	{
		SetRT("rt_offscreen");

		GUI_GetBackground()->Draw();

		if (SIM_GetGameplay()->GetGameMode() != SIM_Gameplay::PREGAME)
		{
			SIM_GetShipManager()->Draw();
			GUI_GetAsteroids()->Draw();
			SIM_GetBulletManager()->Draw();
			SIM_GetPowerupManager()->Draw();

			GUI_GetParticleManager()->Update();
			GUI_GetParticleManager()->Draw();
			GUI_GetFloaterManager()->Draw();
			GUI_GetShieldStrengths()->Draw();
			GUI_GetDropLabels()->DrawAll();
		}

		PostProcess();

		GUI_GetInterface()->Draw();
		switch (SIM_GetGameplay()->GetGameMode())
		{
		case SIM_Gameplay::GAMEOVER:
			PGameOver->Draw();
			break;
		case SIM_Gameplay::POST_LEVEL:
			break;
		case SIM_Gameplay::PREGAME:
			DrawPreGame();
			break;
		}


		GUI_GetWindowManager()->Draw();

		if (BPaused)
		{
			DrawPaused();
		}
	}

	GetD3DEngine()->RestoreViewport();
	DrawBorders();
}

There is a lot of hacky nonsense happening here, but this is just a little hobby game, so I’m not too ashamed :D. So what does this do? Well the very first line of code does all of the actual gameplay stuff. I have an object of class type SIM_Gameplay, and I call that here and do all of the game simulation stuff. This moves the alien ships, handles scores, collision detection, and anything like that. All of the game mechanics are processed here, neatly separate from the graphics code.

Then I clear the screen to black, and clip the viewport (where we render) to an area I defined to be the gameplay screen. This is not the full screen, because I’m fixing the aspect ratio for this game to be some multiple of 1920×1080. This is the ‘ScreenArea’ which is just a RECT structure.

Then I get a bit clever. I set the render target to be an offscreen copy of the backbuffer I called rt-Offscreen. This is where I do 90% of the drawing in the game. I then go through a bunch of various singletons which access different visuals objects that get drawn, from back to front in painter-algorithm style, no Z buffer needed.

Finally I call PostProcess(). This is where I handle some fancy shockwave effects. I fill up yet another offscreen buffer with special images to donate any visual distortions I want to have, for when ships have shockwave explosions. I then copy the whole of that rt_offscreen to the backbuffer, using a shader which combines it with the contents of the distortion buffer to give me a nice distorted shimmer effect. Then finally I set the new render target to be the backbuffer, and draw the UI overlay stuff normally, so its NOT distorted by my shimmer effect.

Then I have some hacky places where I draw certain UI elements if the game is over, or not started yet, and then any windowed stuff, and finally some hacky code to draw GAME PAUSED if relevant.

Finally I restore the viewport so that I can fill in any surrounding borders for unusual aspect ratios and not have anything ‘leak’ out onto the edges.

This code is all a bit messy, because I haven’t nicely settled on a naming convention for a lot of those functions. Am I calling Draw() or Update() or DrawAll() its kinda random! Plus that UI stuff thats on the end of that function is a mess. I’m handling things THREE different ways here! An enum (GameMode) to call different functions, a complete window manager UI PLUS a special case there for if the game is paused. What a mess!

It all works and feels bug free, but its not clearly software engineered at all. I will definitely go back and re-arrange stuff and re-factor it so everything is laid out nicely. The reason I do NOT code like that at the start of the project is because I often throw things in quickly to see if they are a good idea, and I don’t want to type out a whole bunch of complex engineering layout baggage just to discover that this is a bad game mechanic or that this thing looks awful :D.

This is just the way I code, it doesn’t make it officially good, or fast, or better, its just what works for me!