How to make a PICO-8 game: Part 2

I like to move it.

In the last chapter, I showed you the very basic task of putting a sprite on the screen. That’s all very well, but a bit less interactive than most games are. In this chapter, let’s make it move.

Part 2: Move the player

The first task here is to make PICO-8 check to see if the player is pressing any of the direction keys. You can do this by making use of the btn() function.

The arrow keys (or joypad d-pad, depending how you’re playing the game) are referred to by the numbers 0 to 3. The left key is 0, right is 1, up is 2 and down is 3. If you check to see, for example, if btn(0) is true, then you’re checking to see if the player is pressing left.

You’ll recall that the coordinates of the player sprite on the screen are stored in the variables x and y. To physically make the sprite move left, you need to make the value of x smaller, and to move it right you have to make it larger – remember that the left of the screen is 0, the right is 127. Let’s make it move by one pixel at a time for simplicity’s sake. Ignoring up and down for the moment, this code in the _update() function will do that:

In plain English, this reads as:

“If the left key is being pressed, then decrease the value of x by 1”

“If the right key is being pressed, then increase the value of x by 1”

You could be a little more verbose and use the longer forms if you wish:

When you do a check on a function, looking for a “true” is implied, and I prefer the shorter form of the increment and decrement command, but both work. Just note that when you assign a value to a variable you use one equals sign (=), but when you do an “if” check, you use two (==).

Run your code now, and see how the sprite moves left and right as you press left and right. Magic!

Of course, this only deals with left and right. Let’s add the code for up and down, using btn(2) and (3) and changing y as appropriate:

Now, you’d think that was the end of it, but there’s a flaw here. You may have noticed that the sprite can move off the screen where you can’t see it. That in itself isn’t necessarily a bad thing, but for the purposes of this game we don’t want that to happen.

To fix it, we need an additional check for “screen edge detection”. When moving left, we need to make sure that x is only decremented when x is already greater than 0. Similarly, we can only move up if y is greater than 0.

For the right and bottom edges, it’s slightly more complicated. Although the edges are at 127 pixels, our sprite’s x and y values refer to the top left corner of the sprite, which is 7 pixels before the right and bottom edges of the sprite – the sprite is 8×8 pixels, remember. Instead of then checking to see if the sprite is at 127 pixels, we need to check for 120.

We can add this check at the same point we check for a button press by modifying the “if” statements. For example:

If we finish this off to include up and down, we can complete our code (for now!):

Next time, we’ll add an enemy to chase the player!

How to make a PICO-8 game: Part 1

Let’s Make A Game.

Since I’m now teaching people how to make programs in PICO-8, I thought I might as well put my teaching notes here for others who may find them useful.

A few caveats:

I am not an expert. Yes, there are better ways of doing some of what I’m explaining (and some of the improvements will come in later parts of the “course”), but my “class” consists of children, some of whom will have no coding experience past Scratch so bear that in mind. In particular, I will be using longhand for variables, and objects/classes will be used later on, to keep things readable, simple, and followable. Followable is definitely a word. Also, this won’t teach you how to use PICO-8 itself, just how to program with it. There’s a manual for that.

The game we’re going to create is very simple. There are two sprites, and one sprite is player controlled and chased by the other sprite. That’s it. Told you it was very simple.

Parts of a PICO-8 Game

There are three main functions to deal with in a basic PICO-8 program: _init(), _update() and _draw(). Note the underscores – without them your program won’t work.


This is called at the start of your program when you run it. Unless called again, it runs only once. It’s here where you put all your setup stuff, variable initialisation, and so on.


This is called over and over again, 30 times a second. In here you put your “game logic”, updating variables such as object locations, checking for collisions, increment the score, and so on.


This function is where all the drawing on the screen takes place. So you’d print the score, draw the sprites, and so on in the _draw() function. It is also called 30 times a second if it is possible to do so – if the code is taking to long to run it may drop  _draw() calls so that _update() has time to run properly.

Just a few things to mention before I show you any code:

Firstly, comments in the code (that is, notes to you rather than actual code) are either lines starting

which comments out that line, or

which comments out everything until

Secondly, it’s good practice to give all your functions and variables useful names. PICO-8 does have a character limit so you may need to make them shorter and therefore less useful in the future, but not yet!

Finally, indent your code. When you open a function, a loop, an if/then or anything like that, indent everything in it. It makes it a lot easier to read.

If you follow these three rules, your code will be nice and readable – important if you come back to it weeks or months later, or give it to someone else, but also it helps a lot when things aren’t working as you’d expect.

Part 1: Put some stuff on the screen

First off, we’ll need a sprite to act as the player. We’ll just draw a blank square for now in the sprite editor, and use the sprite slot 1 to store it. We won’t need it yet but lets also create an enemy sprite the same only a different colour in slot 2.

Two basic sprites

Now, in the code editor, lets put the three basic functions I mentioned above:

We’ll choose now what the start coordinates of the player sprite are. The PICO-8 screen is 128×128 pixels, with the top left of the screen at 0,0, and the bottom right at 127,127. The middle will be roughly 64,64 then. We’ll call the x and y coordinates of the player, well, x and y. Why not?

Since they’re being initialised, we put these in _init():

At this point, we’re not going to move it about, but we do need to draw it. Usually in a PICO-8 game, you’ll want to clear the screen at the start of each draw frame, so we’ll make use of the cls() command to do that. We can choose what colour to clear the screen to by putting the colour number in cls(). You can use this palette to chose one:

cls(2) will clear the screen to a sort of purpley mauve, for example.

Then we’re going to draw the player sprite on the screen at 64, 64 – now known as x and y. This is done with the spr() command, and the coordinates refer to the top left corner of the sprite. We also need to tell spr which sprite to use, in this case the player sprite, which is sprite number 1.

And there we go:

Best. Game. Ever.

Next time, I’ll show you how to make the thing move around the screen, but for now, here’s all the code so far:

A short film about communications engineers based on a true story

A film by M. Night Shyamalan.





Tidily cabled, blinking lights on servers. Toolbox open on floor with spare cable ends on the floor.

BT MAN 1, short and wearing glasses and reflective jacket. Unshaven. Has Cockney accent and appears fidgety.

(on phone)
Yes so this end is done. Lights are on, just waiting for the test your end. Connect up…



BT MAN 2 is tall, bald and clean shaven. Has thick Norfolk accent. He is talking to BT MAN 1 on his mobile

Right, to where?

As incoherent chatter is heard over BT MAN 2’s phone, BT MAN 2 listens and nods, then shakes his head.

There is no 4… yes, I’ve checked. There’s just no equipment. Yes, I’m at the right exchange.


(Into phone, frightened)
But I installed it myself earlier today. It can’t just be gone!



File Server Resource Manager can’t send emails

0x8004531c, is the magic number

Upon replacing two aging fileservers with two shiny new ones, this time running Windows Server 2012 R2 rather than Server 2008, I came across a strange issue regarding File Server Resource Manager notification emails (you know, like “your quota is full” warnings and so on). As in, it can’t send them, instead giving this message when you attempt to generate a test email:

Failed to send the test e-mail due to the following error: Cannot send the email due to an error. Check the application event log for more information.

Sure enough, when I checked the application event log on the server running FSRM, I found this entry for SRMSVC with event ID 12306:

A File Server Resource Manager Service email action could not be run.

Error-specific details:
Error: IFsrmEmailExternal::SendMail, 0x8004531c, Mailbox unavailable. The server response was: 5.7.1
Client does not have permissions to send as this sender

What’s odd about this, is that it suggests that the email address I’d given FSRM as a “send-as” email address, can’t send emails via our Exchange 2010 server. On our old file servers, it worked just fine with exactly the same settings. It seems Server 2012 R2 has a new requirement!

To fix it, I created a new “Equipment Mailbox” on the Exchange Server (using the Exchange Management Console) called “FSRM-ServerName”, and gave it the email address “FSRM-ServerName@domain.tld”. Then, using the Exchange Management Shell, I gave the server the rights to use that mailbox:

It now all works as expected (and of course I repeated the task for the other server too), but it’s still a mystery to me as to why it’s unnecessary for File Server Resource Manager on Server 2008 but it is on 2012 R2, when surely the issue lies at the Exchange Server end of things?

Creating a shared mailbox in Exchange 2010

Sharing is fun!

This is one of those jobs that I do so infrequently that I forget the exact required process in the time since the last one I set up. As I occasionally use my blog as a receptacle for recording how-to instructions, I give you How to Create a Shared Mailbox in Exchange 2010.

Firstly, open up the Exchange Management Console (EMC) and navigate to Recipient Configuration and Mailbox. Right-click on Mailbox and choose New Mailbox. If you already have a mailbox that you wish to turn into a shared one, you can skip these creation steps.


Choose User Mailbox and then New Mailbox:

shared2 shared3

Continue reading “Creating a shared mailbox in Exchange 2010”


Snakes alive!

When I have some free time at work, I’ve been logging on to Codecademy and providing myself with some CPD 1 by working through the tutorials on programming languages.

Now, I’m not a fantastic coder, not by a long shot, but I have created programs in all sorts of languages over the years – starting with Sinclair and BBC Basic, up through AMOS, a bit of C and C++, Perl, Pascal and most frequently, Visual Basic and PHP. I’ve dabbled with Processing (mainly for Arduino related stuff) and a bit of Javascript (primarily making use of jQuery). Through work I’ve used Scratch and similar “visual block” languages like the environment for coding Microbits.

I would say that even if I can’t code in a particular language, I can usually understand something written in one: After all, most modern programming languages are very similar, easily readable and differ mainly in just syntax and convention.

pythoncompleteSince Python seems to be the language of choice these days for people learning to program, I decided to pursue the Python course on Codacademy, and in the last week finished it up. I have used Python before, mainly for writing stuff on the Raspberry Pi, but I’d not actually learned it.

I have a few thoughts on the language itself. Perhaps unsurprisingly, it’s very much like PHP so once I’d learned the different conventions it was quite quick to become fluent in the basics. One thing that I found difficult, and unusual for languages I’ve used before, is indentation.

Good Programming Practice dictates that as well as annotating your code (haha! We all do that, right?) you make use of whitespace and indentation to make your code readable. When you have a subroutine, function, loop, or whatever, you indent the code within it. As an example (in no specific language):

This is especially useful if you have nested elements:

Of course, I try to stick to this but inevitably while editing, re-editing, moving and reusing code things often end up with the wrong levels of indentation. I recently changed the template for part of my website (news on that in another post, hopefully) and the mess of divs in the HTML almost drove me to kill a kitten. Horrible.

Anyway, my point is that we coders 2 aspire to have neat and tidy code. Python, however, enforces it: Loops and so on come to an end not with a closing keyword or brace of some sort, rather they come to an end when you stop indenting them. That was a struggle, especially so when debugging. Have I used the wrong code, or have I forgotten to press tab? Error messages in Python are helpfully quite verbose and direct, thankfully, but it was still a hurdle. I suppose that’s the point though, forcing you into good practice rather than just expecting it.

The Codacademy course itself was pretty good. I did find that some sections overlapped with others, sometimes not exactly contradicting each other but using slightly different (but equally valid) convention, presumably due to a range of people writing each section. A couple of exercises had horrible bugs in them which caused problems. One of them required you to read and print three lines from a file, but even if your code was 100% correct, it would fail unless (as I found from the help forum) you edited the file you’re supposed to read from first.

Minor quibbles like that aside, I enjoyed the course and learned a lot. In particular, I finally got my head around objects, which I’ve struggled with several times in the past. Codacademy itself is also great, and I’m now going to go back and finish my unfinished Javascript course and then move onto something else. SQL maybe?


  1. Continuing Professional Development, in case you were wondering
  2. Ha! Hark at me calling myself a coder.

What is locking out my Active Directory user?

Get your locks off.

Every now and again, we find that a user gets constantly locked out of the network, seemingly because they’ve managed to get their password wrong so many times in a short period that the auto-lockout policy is triggered. We unlock the account, but invariably a few minutes later they’re locked again.

In the past, this has almost always been down to some mobile device they have with stored, old and now incorrect, credentials. This device is repeatedly trying to authenticate in order to access email or our wireless system, so the first port of call when troubleshooting is usually the question “Have you got a phone or a tablet you use?” and normally that’s the end of it. Well, once they turn it off or update stored passwords or whatever, anyway.

This week we had something else. The user in question has never used a mobile device to access anything we have at work, and yet their account was still being locked out every five minutes. Eventually, an old desktop PC in an office, hidden under some paperwork and untouched for a fortnight turned out to be the culprit. Outlook was merrily trying to communicate with our Exchange server using the user’s credentials from last time they used that machine, and Active Directory quite rightly decided enough was enough and locked them out.

Troubleshooting the Active Directory lockouts

How to go about finding what machine is doing this, though? Well, first port of call was the Microsoft Account Lockout Status tool. This will show you when the lockout occurred and which domain controller(s) logged the event and activated the lockout.

Active Directory lockout status

Usually the PDC emulator will record this event, but you may see other DCs also record bad password attempts.

Now you know which domain controller to check, you can open Event Viewer on that DC and check the Security log. Naturally, you’ll want to filter this as it’s likely you’ll have millions of entries to sift through. The key filters are the timeframe (if it happened today, limit it to the last 12 or 24 hours) and the Event ID you’re looking for is 4740:

Security Log Filter

Once filtered, you’ll have (hopefully) just a handful of events to look through. One or more of these will point you at the naughty machine which is the source of the invalid logon attempts.

Filtered List

Open up these events, and somewhere you’ll get information like this, revealing the (removed in this case) computer name:

Computer NameHopefully knowing the name of the computer will enable you to resolve why the lockout is happening. Check it for processes that are trying to authenticate, maybe remove all the stored credentials in Windows Credential Manager, or perhaps just a reboot will resolve it. Actually physically finding the computer? Well, you’ve an inventory, right? Otherwise it puts me in mind of this quote from

<erno> hm. I’ve lost a machine.. literally _lost_. it responds to ping, it works completely, I just can’t figure out where in my apartment it is.

DFS related intermittent file share outages on Server 2008

Resolving the mystery of the excessive disk reads.

We recently had a problem where one of our two main Windows Server 2008 file servers (usually the same one, but sometimes the other) would suddenly stop responding to network requests. Ping was fine, and you could RDP in (albeit very, very slowly), but file shares appeared to vanish as seen from client machines.

It was intermittent, and even when looking at Resource Monitor on the server, it wasn’t clear what was causing it. No specific process was hogging all the RAM or disk access time, but disk reads cumulatively were through the roof. If felt like a failing hard drive, but every drive on the RAID had been replaced (separately) fairly recently, and disk checks threw up nothing unusual. Indeed, for most of the time everything was perfectly OK and a restart or just waiting for a while returned it to normal.

dfsrsThe usual suspects were ruled out – virus scans, backups and so on, and we were at a bit of a loss as to what it might be. Then I found if I sorted disk usage in Resource Monitor by Image Name (I’d been sorting it by Read, to show the most disk-heavy process first) I realised that one process appeared many hundreds of times – dfsrs.exe. This process deals with DFS replication, keeping folders synced between servers, and it seemed this was the cause. Unfortunately, I couldn’t just turn it off as we need DFS replication to keep user home folders on the server synced between the two main file servers, but now I could see where the problem lay, I could find the root of the issue.

Which was, of course, Google Chrome.

We use roaming profiles for our users, and to speed up logging on and off, some of the Application Data folders are redirected back to a folder on the network. It has worked well, only now, when we have fairly recently moved to having users on DFS shares, we’ve hit this snag. You see, Google caches a lot of stuff and constantly creates and updates a multitude of files in the user’s Application Data folder. Every time this happens, DFS has to sync it. With a few hundred users all using Chrome (it launches on login!) that’s one hell of a lot files to keep in sync – even if they’re very small.

Obviously, most of this data is fleeting and temporary, but DFS doesn’t know that. Thankfully, there was a solution: exclude some of these folders from syncing. Sure, the cache won’t be the same between the two copies of the folder, but that isn’t important as it’s deleted when Chrome is closed anyway.

In the DFS Management console, find the Replicated Folder, right click, and choose Properties.


You’ll see this window, with the two fields “File filter” and “Subfolder filter”:


It’s here you put the names of all the files and folders you don’t want to sync between DFS servers for that specific replicated folder. Chrome specific folders that were hammering the sync and can be added include:

Application Cache, GPUCache, ChromeDWriteFontCache, Session Storage, Pepper Data, Cookies

While I was there, I took the liberty of adding some other, non-Chrome folders that also didn’t need to be there, like Flash Player and Distiller 10. I also put thumbs.db in as a file exception as that was coming up a lot too. Note that “~*., *.bak, *.tmp” is filled in as default.

Important: this system literally just matches based on the file and folder names. Yes, it’s stupid. If your users create a folder called “GPUCache” somewhere else in the replicated folder, it won’t get synced. So be careful what you do choose!

Everything is much better now, with the server barely being worried by disk reads, as it should be.