Category Archives: C#

Space Invaders Part I

I am not a developer by trade and any experience I have is of using C# and various iterations of Visual Basic in the distant (7+ years) past. I use PowerShell in my day-to-day but this can’t really be described as a genuine programming language. One of my ‘bucket list’ items for 2025 was to figure out how to write a Space Invaders game and something I have been procrastinating over for months. This was mainly a project in how do I write it but also served as a great way to learn or at least re-acquaint myself with a programming language I’d lost touch with. Since this was to be a fairly steep learning curve, I figured I should give myself a fighting chance by choosing a language that :

  1. I am somewhat familiar with
  2. Is suitable for such a project.

So for part 1, C# it was. I say part 1 because now I have a good idea of how to put the game together, I would like to take this further and write a version in another language and possibly even a recognizable version in PowerShell. This should give me some exposure to other languages I currently have little to no knowledge of (I’m looking at you, C++ and Python).

But you can get AI to write the whole thing, surely? Well, yes, true and I’m not going to lie, to some extent, using AI is almost unavoidable. When starting on a particular subroutine I almost fell out my chair with the way it read my mind about what I wanted to do next. Really. It’s not like I’m new to this (AI in general or looking for fixes to programming issues) but I’d start to type the name of a routine to make the saucer fly across the screen and it would largely write the thing for me before I’d finished typing the name of the sub. Blown away. That said, not everything was quite right and many times its assumptions weren’t what I wanted so going through the code to fix these issues wasn’t just ‘satisfying’ but necessary.

Then there were annoyances which I genuinely wanted AI to solve but try as it might, it just couldn’t. First versions occasionally left artifacts of the laser fire on the screen that wouldn’t go away. Co-Pilot kept making suggestions but either these didn’t work or worse still, broke the code. And it was during these frustrating times that my free access ran out and I was left to fend for myself (more or less). Back to Stack Overflow for fixes (in the end this solved itself when I was forced to adopt the OnPaint method for sprites – more on this later).

Eventually I had a working game on my desktop development machine which I was quite proud of. It looked just like the real thing and although I’d furnished it with a few more flourishes than I’d originally planned (my starting goal was to make a very basic game that could be ported easily from language to language) I was happy with it. Then I tried it on my laptop. Oh dear. Every time I fired a laser it slowed the game down. Sound was also hogging the UI thread too…my God, this computer must be several million times the speed (and memory) of my old Beeb that used to run this game, so why is it having such a hard time?

This called for a re-write to some extent. Quite a large extent, in fact. I had to put the main game loop on a background thread; the sound had to be pushed out onto a background thread too (this helped a lot but still isn’t perfect by any stretch). However the really big change was to replace the way the sprites were presented. My initial version had all graphics as a separate PictureBox – this was ideal as it was simple and would potentially make future versions eas(ier) to write. Unfortunately this proved incredibly resource-intensive and although it ran OK on my desktop machine, it really struggled on my laptop. Begrudgingly I had to bite the bullet and swap this for the OnPaint Method. Although the learning curve for this increased (dramatically in fact), this did have two main advantages:

  1. The OnPaint method is significantly more performant. Each PictureBox is a full windowed control, which means it has its own window handle (HWND) and processes system messages. For a game with lots of objects like aliens, bullets, and lasers, creating and managing a PictureBox for each one consumes substantial system resources and this led to poor performance and noticeable lag, esp on my laptop. In contrast, OnPaint performs a single, highly optimized drawing operation directly onto the form.
  2. Smooth Animation (Double Buffering): The OnPaint method works seamlessly with the form’s DoubleBuffered property. By setting this.DoubleBuffered = true;, all drawing operations within OnPaint are first rendered to an off-screen buffer and then drawn to the screen in a single operation. This improved animation noticeably.

There are other benefits to this too which I’ll leave out here for brevity’s sake and ultimately it was worth the effort to get the game working with this method instead. The PictureBox version can be found here and the OnPaint version here. Links to the full project are also at the end. I still think there is value in the PictureBox (and single threaded) version if only as the academic exercise of creating the game in it’s simplest* form.

*It’s not in it’s simplest form. I could have made it a lot simpler. As I said, I got a little carried away.

GAME FLOW

Although I won’t pretend I started out with a ‘design’ in mind, this is something that kind of presented itself as I got further into the project. I have used VS2022’s Mermaid Editor extension to help create a flow diagram of how the whole thing works:

Flowchart illustrating the game loop and events for a Space Invaders game, including game setup, player actions, collision checks, and game over sequences.

I have, somewhat lazily, embedded the flying saucer as a project resource and this is the only graphic in the project that remains as a PictureBox. So in short, this is on the form and not ‘created’ in code. The same can be said for the hi-score form which I have designed in the editor rather than created in code. I make no apologies for this and feel free to change and use what you like for your own project, should you wish to. All the graphic and sound files will, as a result, need to be in the same directory as the exe file (“EalingAttack.exe“). Oh yes and on that subject, I had various names for it throughout the project. It started with a reference to my road (BirkbeckInvaders) before eventually settling for EalingAttack (my borough in London). As such you’ll see references to these and they could do with cleaning up in an ideal world. Finally, I have added descriptions of what everything does throughout the code for anyone who’s interested.

I haven’t decided when the next installment will be yet but don’t hold your breath. Ideally I need to start spending some time with the family again :-). I promised a follow-up article on 6502 assembly as well which I still haven’t got round to yet. I’ll probably tackle that first though as it will be a shorter project but again, in my own time which could be whenever.

CONTROLS:

Oh and I forgot to add a controls screen so it’s:

Left/Right arrow for the turret movement and spacebar to fire. As alluded to above, sound is still an issue on some machines, particularly the background sound. If this noticeably affects gameplay, you can toggle it by pressing ‘S‘.

Finally – feel free to create your own upgrades and leave links in the comments.

GITHUB :

bondy666/Space-Invaders: Learn to program Space Invaders in multiple languages

Either clone it or for those who just want to play the game go to Code > Download zip, unpack and run the exe. I promise, there are no nasty surprises (apart from the bad coding).

Simple Configurable Front End SCCM

The business of adding a front end for a PXE-driven SCCM OS build is generally a pretty important consideration if you want to specify some basic information prior to deployment. It’s also something that I’ve felt has never been properly addressed by the SCCM development team. To be fair you could argue it’s not their job to do this but with more functionality being adding to every single aspect of SCCM in every new release, it does feel like something that probably should be looked at in the future.

For now, there are plenty of examples of great front ends on the internet – look up ‘Pretty Good FrontEnd’ by Johan Arwidmark or ‘Pretty Good Front End Clone’ by Maik Koster. These two have been around donkey’s years. One of my favourites is Nicolaj Andersen’s very neat ConfigMgr Front End which offers a whole world of features. Additional infrastructure is necessary to accommodate this however, in the form of web services.

So why create another? Well I’m certainly not pretending to  set the world alight with some kind of ingenious new approach but I always felt there was just a little too much fiddling about with most of the solutions I saw elsewhere. What I wanted was something I could ideally just drop straight into my WinPE image which would just work.  There are certainly features I could add (and may indeed do so if enough people ask) such as ability to remove certain sections, eg, domain, OS, etc. However in an effort to keep things simple I have left this for now.

The Front End

This is a typical illustration of what it looks like in my lab. Most aspects are configurable via a small ini file (yes I know it’s a bit 90’s but let’s face it, it’s a damn sight easier to use than an xml file for this kind of thing). The ini file below is configurable for the OUs in your environment, the domain (or domains) and even colour and font size. One area I went a little off the beaten track is the ability to select different images you want to use in your task sequence. This is great in my lab as I often want to test stuff out on different OS’s and will routinely add a new image when necessary to my tried and trusted task sequence.  As such I’ll detail this a little more.

If you want to use the same task sequence but have different images available in that sequence, you can enter them in the ini file. Just be sure to enter the appropriate option/filter in appropriate task sequence step. For example, in the image above we have  a number of different OS’s which relate to separate images. Under the INSTALL section of your task sequence you might have one or more separate steps to Install Windows 10, Install Server 2016, etc. On each of these steps, click Options and add a Task Sequence Variable condition, eg:

TS VARIABLE: OSDImage Equals <Windows 10 1803>

It is important that the text in the OS box above equals the OSDImage value of your condition. 

Of course, you can just add a description in the Config.ini file instead and have one image step in your task sequence with no condition set and all will be well. I suspect this is what most people will want. The option to do it this way is just there if you want it.

CONFIG.INI

Typical Config.ini settings below. This file must always exist in the exact same folder as the NewFrontEnd.exe executable.

:: [ORG_UNIT] - Enter all OUs you want displayed in format OU=Dept, OU=Org, DC=domain, DC=suffix one after the other.
:: [DOMAIN] - In most cases, this is more for show but can be used to build a workgroup machine too if WORKGROUP is specified underneath the primary domain.
:: [OS] - If your task sequence can build more than one image, add it here, eg Windows 10 1607 LTSB. Then add a task sequence variable condition called OSDIMAGE and equal it to the image name in your TS.

:: [MISC]
:: LOGO, recommended max size is approx W:120, H:120 for a font size of 8-10
:: BACKGROUND, Enter standard OS colour names, eg Red, DarkRed, Marroon, MidnightBlue, etc
:: FONTSIZE, recommend, 8-10 but it will go bigger. Seems to jump in 2s, eg, 8,10,12, etc. This has a bearing on the size of the form.
:: FONTCOLOR (American spelling, sorry) see BACKGROUND, above.
:: SMSTSPREFERREDADVERTID, If specified, enter the Deployment ID of the task sequence you want to run. This will override any other advertised task sequence either 'available' or 'required' and the wizard won't show.

:: HIRESDISPLAY, If HIRESDISPLAY=True the size of the form is increased so it doesn't get 'scrunched up' on the display. This has been tested against a Surface Pro 4.

:: NOTE - [ORG_UNIT], [DOMAIN] and [OS] should all have at least one value (ideally) so the interface has something to show. Settings under [MISC] can be removed or ignored by adding a semicolon before the setting.

[ORG_UNIT]
OU=Workstations,OU=Bondynet,DC=BONDYNET,DC=org
OU=Servers,OU=Bondynet,DC=BONDYNET,DC=org
OU=Secure Workstations,OU=Bondynet,DC=BONDYNET,DC=org

[DOMAIN]
BONDYNET.org
WORKGROUP

[OS]
Windows 10 1803
Windows 10 1607
Windows Server 2016
Windows 2012 R2
Windows 10 1607 LTSB
Windows 7
Windows 8.1
Windows Server 2008

[MISC]
LOGO=logo-3.png
BACKGROUND=LightSteelBlue
FONTSIZE=8
FONTCOLOR=Black
SMSTSPREFERREDADVERTID=PR120019

WinPE Setup

So how do you get this working in WinPE?

  1. Create a share somewhere and drop NewFrontEnd.exe, Config.ini and your company logo png into it (and/or possibly RunFEUI.vbs – see end of post)
  2. In SCCM go to your chosen boot image, right-click | properties | Optional Components. Select Microsoft .NET (WinPE-NetFx). This is a C# application so it needs this option available in your boot image binaries.
  3. Select the Customisation tab. Under Prestart Command Settings enter “X:\sms\PKG\SMS10000\NewFrontEnd.exe”
  4. Select Include files for the prestart command
  5. Select the share you created above with the files in for the source directory.

If you want to, add a background, click OK  and you’re done. After the update distribution points wizard has completed, double check the Last Update information in the bottom section of the SCCM console to ensure the time matches the time you ran the wizard and everything has updated as it should. This is important as it hasn’t usually finished updating just because the wizard progress bar has completed.

.

For The Adventurous.

One of the neat things about using the above method is that there is no ugly command prompt in the background as it brings up the front end interface. However the downside of this is that all the files are inside your WinPE image so if you want to update them you have to go through the above process once again which is both time consuming and laborious. One solution though is to simply point to a script that will map a drive to a share that exists elsewhere on your network and execute the files from there instead. This facilitates updating the files on the fly.

In the zip file included below, there is a file called RunFEUI.vbs. Simply open it and edit it to fit your environment (ie edit line 4 with the appropriate drive mapping and account).

DOWNLOAD HERE:

NewFrontEnd_v1.2

Please ask any questions or suggestions for improvements in the comments below.

[*** UPDATE ***]

I have added a new variable, HIRESDISPLAY=True. If you have a Surface or another slate type device, it is common to see forms get squashed up. Set this if you need a larger form to display.

Can’t run PowershellInstance.invoke() from C# (but code is fine)

I recently wrote a GUI to duplicate MDT database roles based on the excellent Powershell commandlets written by Michael Niehaus:
http://blogs.technet.com/b/mniehaus/archive/2009/05/15/manipulating-the-microsoft-deployment-toolkit-database-using-powershell.aspx.
Although the Powershell code worked fine when executed directly in a Powershell window, I was seeing mixed results when executing the same code in C# through PowershellInstance.invoke(). Specifically, when I compiled the executable I was able to run the powershell code through the utility without issue, whereas it failed for my colleagues for some reason.

THE FIX

It seems that what I needed to do was ensure that the code was compiled specifically for the platform I was running it on as opposed to ‘any CPU’. In my case this was for x64. You can set this under the project properties in Visual Studio:

Platformx64

However, after making this change, I found I was getting compilation errors along the lines of:
An attempt was made to load an assembly with an incorrect format: [path to exe]

To fix this, I needed to change Generate serialization assemply to Off and everything compiled as expected. More on this here.