Category: Game

Why I hate Assembly language…

Why I hate Assembly language…

6502 assembler listingI spent several years in the 1980s programming games.

I have a memory of 26 year old me sat hunched over a computer late at night back in 1985. I was working a 60-70 hour week as a partner in a games company. My current game was an American Civil War tactical wargame called Johnny Reb II. I was struggling with some ‘artificial intelligence’ code for the attackers (Confederate troops) to cross a bridge over a river. On the other side the defenders (Union) were trying to defend the bridge.

Johnny Reb II

Artificial Intelligence in games is a completely different thing from ML and Data Science nowadays. Back then it was just a control algorithm for troops reacting to the presence of enemy troops and working out the best routes, targets to attack, whether to retreat and so on.

What made it worse was that the whole thing was written in 6502 assembly language (and later converted to Z80). Back then you had two choices: Basic which was to be honest slow and clunky for writing games or assembly language. If I was doing it now, without a moments hesitation I’d program it in C. But C compilers for 6502 didn’t exist back then.

The Problem with assembly language

The problem with assembly language is (a) it’s slow to write. You can write 10 lines of C in the same time as ten lines of assembly code. Those ten lines of C will do far more than ten lines of assembly code. In 6502 all you are doing is moving values between registers or register <> memory. Maybe add a number or increment one of the three available registers A, X or Y. These were all 8-bit registers so you couldn’t even index easily through 64-bit memory. To do 16-bit indexing you stored the 16-bit address in two successive page-0 locations (addresses 0-255) and then used Y as an 8-bit index. You could do the same in page 0- memory with the X register.

(b). It takes a lot of code to do anything in assembly language. You want floating point arithmetic in 6502? Take a look.  I think Steve Wozniak wrote those for the Apple I/II. What we take for granted in languages like C# or Java or JavaScript is code for high level data structures like dictionaries. I’m sure it could be done but it takes a fair bit of programming. You don’t have those in assembly language; all you have to use is simple and not very long arrays.

In C# I wrote a program to read a 46 MB text file and produce a sorted count of all words in the file.  It used a Dictionary, took me 30 minutes to write and it ran in 5 seconds.  It would take weeks to do the same in assembler. 

6502 Page 0 locations were valuable because they made your code both shorter and faster.

I wrote a cross-assembler for 6502 in Z80 as a way to learn Z80. Assemblers use labels (L20, L30, L31 etc. in the screenshot) and I needed a way to hold them efficiently in memory. I ended up with a 26 x 26 index table of 2 byte pointers. If you had a label ‘ROUTE’ then there would be a pointer to a chain at the location for [‘R’][‘O’]. Each entry in the chain was like this

  • 1 byte length of rest of label (i.e. 3 for ‘UTE’) – 0 marks the end of the chain.
  • 3 bytes to hold ‘UTE’.
  • 2 byte address value

No need to hold the whole word as you know the first two letters. It also makes comparing a label against one in the table was faster because it only needed to match against len(label)-2 characters.

So the next value in the chain would start after that or be a 0 for the end of the chain. Yes most of the index table might be empty (all 26x26x2= 1352 bytes) but every label in a chain used 2 bytes less than the full label text. So with more than 676 labels you saved memory. Searching for a label was just a matter of walking a chain. Labels were just addresses; so a location could hold a value like a count. You’d identify it with a label and use that label in 6502 instructions. No variables in assembler; it’s all addresses…

With 6502 you need to do two passes to generate code. If you have a label in the first page of memory (0-255) then instructions are only two bytes long and are faster to execute than the three byte instructions. So on the first pass you don’t know if a LDA label will be 2 or 3 bytes long. After the first pass through though you do know now, so on the 2nd pass it can output the correct size instructions.

Programming in assembler means you have to write a lot of code and in the early days before I had a development machine that meant I had to save the source code to tape and compile it using a cartridge assembler. The CBM-64 could take cartridges and one of them stored assembly language in RAM just like Basic. If the game did something wrong then the CBM-64 would reset and you’d lose your source and have to reload it from the slow tape. Let’s hope you didn’t forget to save changes before you ran it. I spent a few hours gnashing my teeth over a persistent crash. I was calling a CLR routine when it should have been CLS! d’oh…

Note, from memory it was the Mikro cartridge assembler. See screenshot below.

Miro assembler start up screen.
Mikro Assembler Startup From Github

Jump Tables

So a game back then might be 5,000 lines of code or longer. That’s quite a bit to hold in memory, given that you need space for the game machine code, sprites, graphics etc. as well. Plus it’s wasteful having to recompile the same code over and over again. My cross-assembler did 250 lines per second but divide that by two for the two passes.

So I split up long files into smaller ones and created a jump table at the start. There was no linker so the code was loaded into RAM at fixed addresses. If you had five subroutines in one file then there’d be five jumps at the start to the actual function. And the files that called those functions just had a block of five calls at the start.

That way you didn’t have to worry exactly where the function was located in RAM so long as that file was always loaded at the same address.

 

Switching to Development Machines

It got easier when we switched to development machines. The CBM-64 had a parallel port as did the development machine (Tatung Einstein-a CP/M computer) so a little bit of handler code in the CBM-64 set up the CIA chip to wait for data sent down the parallel cable and put the code directly in RAM. It took no time to load the handler from tape after a crash and then send down the whole file.

Modern CPUs do all sort of optimizing tricks and that’s even before you use vectorization. Compiler writers know how to generate code that uses these tricks but it would take quite a while to learn them so you could use them in hand-written assembly.

Conclusion

Writing in assembler in the 80s was easy to learn. Nowadays I wouldn’t know where to start- the Intel and AMD CPUs have a lot of different chips in their families so there are variations in what instructions are available. Oh and don’t forget there’s ARM CPUs as well.

Writing in C (or even C++) is a lot easier to get into and I very much doubt if you’d get any better performance in writing things in assembly. Also, it would take a lot longer.

Playdate gets nearer to release

Playdate gets nearer to release

playdateBack in May 2020 (nearly two years ago) it was originally announced and the updated release date now looks to be late 2022. Also it’s $179 not $149. But they have given a lot more details; you can for instance see the hardware spec.

Also more relevant is the way of creating games. Either in Lua + C or just C. The dev tools illustrated are running on a Mac but according to this Twitter thread (worth a read), they’re available for Windows, Mac and Linux.  The SDK looks impressive enough- “It includes helpful functions for things like font handling, drawing, animation, sprites, tilemaps, collision detection, A* pathfinding, audio synthesis, crank handling and more. You can download the SDK which includes a simulator now from the dev page..

Would I get one? I’m toying with the idea. A mono display of 400 x 200 is a bit retroish and my days of creating those types of games are probably long behind me, but it’s tempting.

Dealing with artists for game graphics

Dealing with artists for game graphics

Factory graphicsI’m working on three game projects (my side projects), One is Flutter front end plus C# back end, another is the same but a different type of back end and the third is a mobile game with C# backend but its put to one side until the others are done. These are all side projects.

I’ve bought graphics and they do up to a point- e.g. kenney.nl is very good. But sometimes you need something a bit better or that’s not covered by that library.

Now one of the things I’ve done is use low costs artists from sites like Fivesquid.com and fiverr.com. Many of these artists are very good but live in countries where things are a lot cheaper than here in the West. Exploitation? Maybe, but they are happy to do the work and it saves me a fortune. What might cost me a couple of hundred pounds here in the UK can be done for say £20.

But I’ve found when dealing with them that you can’t take anything for granted. You have to have a bit of patience and explain everything including your expectations. And make sure you nail the price down exactly. I had arranged everything with one to do 35 small graphics and he wanted £35 for each graphic. Despite his advert saying 5 graphics for £10!

So I’ve found, you need to specify file format (.png or .jpg), layout- single files or in a sheet in a grid. Also fivesquid have a thing where when the order is delivered, you have three days to mark it complete or asks for changes. One artist said it was complete but hadn’t quite got it ready and the three day period expired before I’d received anything. So I could hardly accept nothing. It was though a genuine mistake on the part of the artist and I did get the graphics eventually.

It’s that book again

It’s that book again

Basic Computer games bookOne of my favourites and one that I actually bought twice in my life and of course I have mentioned before. Originally I bought it back in 1982 and more recently in 2015 along with the sister “More Computer Games” book. The reason  I mention it because there’s an ongoing project to do the games in it in languages other than BASIC.

The languages they’ve chosen are:

  • Java
  • Python
  • C#
  • VB.NET
  • JavaScript
  • Ruby
  • Delphi / Object Pascal
  • Perl

I no, it’s sad. No C… But given that it includes C#, I’ll let them off.

Why C# for the server?

Why C# for the server?

https://commons.wikimedia.org/wiki/File:Csharp_Logo.png
From Wikimedia

There are plenty of other programming languages that would do.  Programming languages are just tools but C# comes with several advantages.

  1. I know it pretty well, having been using it since 2005.
  2. With .NET 6 (and 5), it’s easy to create applications that run on Linux. This lowers the cost for hosting. I’m setting the game on a low cost VPS.
  3. Also on Linux, ASP.NET works pretty well for both Websites and Web Apis.
  4. I like some of the recent changes in C#. And Visual Studio 2022 Community Edition is pretty good. For instance the JSON handling has got better and better.

Do you know what Hello World in C# looks like now? Here it is in its entirety.

Console.WriteLine("Hello, World!");

That’s a console application. One line! Follow the link for more details about the C# templates. Note, there’s no usings there either. That’s because applications now start with a default set in C# 10 and .NET 6 (you get both if you install VS 2022). And if you want a particular namespace that you’ve written to be available to all source code in a project, you can just add this:

global using xyz;

And it becomes available everywhere without needing any more usings.

 

Nearly finished translating asteroids to C++

Nearly finished translating asteroids to C++

Asteroids screenshotI always wanted to do this and have most of it done. It just needs a bit of polishing plus making it cross-platform. It wasn’t the hardest  thing I’ve done although I did start by trying to make the common part for asteroids, player ship, bullets and aliens, the bit that managed position and velocity into a base class.

I then spent a day wrestling with the compiler trying to access this in those methods that used this and in the end found it easier to make it into its own class and had an instance of it in each of the classes. I.e. using composition rather than inheritance.

Rewriting in C++ made things like saving high scores to disk and reloading a bit simpler using C++ strings.  Now I just have to get my main PC up and running and then polish the code and publish it on GitHub.

 

 

 

Another Minecraft game in C

Another Minecraft game in C

MinecraftIf you remember back in November I mentioned a Minecraft server that was written in C.  Well now there’s another one that has appeared. Just lIke the other one it uses SDL2 and OpenGL and includes full source code.  This one uses clang.

It’s cross-platform for Windows and Mac and there are two different binaries, one for creative mode and one for survival mode.

It’s still a work in progress and needs sound effects and music, saving and loading levels and multiplayer to complete it. If you are learning C and want to see how a game like this is programmed, download the source code from GitHub and start studying it.

Core War in C

Core War in C

Core WarCore war is an old game concept that dates back to 1984. If you imagine a simple CPU with small programs written in assembly language trying to wipe each other out, that’s Core War and you can read about it in a lot more detail on Wikipedia.

Inevitably for a game of that vintage there is a C implementation on GitHub by developer Emil Wallner. There’s an animated version of the screenshot showing the game play in action.

The programs (representing viruses) are small assembly language programs that move themselves around the virtual memory and duplicate themselves and try to wipe out the opposition. I’ll always meant to write one of these myself but for now there’s this.

The game of 2048 in C in your browser

The game of 2048 in C in your browser

2048 game playing in a browserBack in 2014, an Italian developer called Gabriele Cirulli devised a puzzle game called 2048. It has been implemented on many platforms (I have it on my iPhone) and here is a link to a C version of it (in 300 lines) by developer Nishchith Shetty that plays it in a browser using WebAssembly.

The idea behind the puzzle is that you combine the numbered pieces by moving pieces intro same numbered pieces. 2 into 3, 4 into 4 and so on.

WebAssembly is the technology that lets you run programs in many languages (including C and C++) in your browser at speeds up to 50% of native code.  It’s also used in Blazor where you can write C# programs that run in the browser.

To convert the C code to WebAssembly, you have to install a transpiler (a program that converts one programming language to another) called Emscripten, then it’s a single command line instruction to build the WebAssembly from the C sources and SDL2. Or you can just play it online here.

I’ve been meaning to do a WebAssembly version of my asteroids game using Emscripten. it’s just been sheer laziness that I haven’t got round to it.

 

More notes on my Webassembly web development with Blazor

More notes on my Webassembly web development with Blazor

Web networking
Image by Gerd Altmann from Pixabay

This is another post in the Inselkampf series. Having spent much of my career creating “desktop” application, web always feels a bit different. If it’s a website then HTML/CSS/PHP + MySql is a reasonable way of working. But when its a web application like a browser game that uses a SQL database, then there’s a bit of architecting involved.

I’m using Blazor because it lets me write C# that runs in the browser. I’ve never been a JavaScript fan though I realise many people are. I also have to use database. As I’ve said before Blazor gives you two choices- The WebAssembly version that runs completely in the browser and the Server version that talks to a server using a protocol called SignalR.

I’m trying to be clever by using the WebAssembly version but having the C# talk to a restful interface. Restful just means it has a bunch of http calls to do things like update, fetch data, login etc. On the server runs a ASP.NET program implementing this. It’s headless, as in its not outputting any webpages to the browser but just returns data in JSON (or maybe MessagePack).

This avoids having a SignalR connection for every user logged into the site which is one way to bring a server to its knees. When you create a Blazor Server application, it has a few disadvantages. As Microsoft says: when you use Blazor server.

  • Higher latency usually exists. Every user interaction involves a network hop.
  • There’s no offline support. If the client connection fails, the app stops working.
  • Scalability is challenging for apps with many users. The server must manage multiple client connections and handle client state.
  • An ASP.NET Core server is required to serve the app. Serverless deployment scenarios aren’t possible, such as serving the app from a Content Delivery Network (CDN).

I’m also not using the Microsoft authentication but rolling my own. Yes it’s possibly not perfect but I’ve done it before. This way I get to generate recovery numbers. (Both GitHub and Gmail offer these). A bunch of one off codes that are used to authenticate you, if you’ve lost your password or messed up your email then you login with your account number and an authentication code. This is the only way you get to change email and/or password. You just have to keep the codes safe.

Rolling my own Interface

So things like logging in, getting current status, updating game play are all done by making a call to an HTTPS routine. This is all behind the scenes so players see nothing. Values are sent as POST parameters and also include a nonce. This word (that unfortunately means sex offender in UK English!) , refers to a special code that has to be supplied with each call to the server to authenticate it. Successful logging in returns a nonce that has to be added as a parameter with every call to the server.

The program on the server that serves the restful calls is a simple ASP.NET Razor pages application (Well maybe Razor, I’m not sure if I need them). Behind the scenes I’m using MySQL which was installed as part of VirtualMin (the excellent software I use to setup the VPS).