It’s better to use floats for maths and leave ints for indices

Someone showed me a bug in my recent game, Freefall, whereby you can get as far as you like, by just changing speeds continuously, you don’t even need to look at the screen, just tap with a consistent tempo to keep changing speeds. This works because the projectile speeds are set with integers which means they have:

  1. A base speed at which they will hit you with the parachute
  2. Fast (double base) speed they will you with if in free fall
  3. Anything faster than this will miss you because it will get off the screen before it reaches you and is therefore only in there for decoration / to confuse the player

I used integers for practically everything in the game because the low resolution meant that even moving one pixel at a time is a pretty big step (there are only 48px in the vertical axis) and you can’t draw smaller than that.

During testing I focussed on checking that 1 & 2 would hit you at their respective speeds and that you could dodge them if you changed at the last moment. If you change speeds so infrequently the problem is less apparent. If you ignore the projectiles and just tap continuously you will reach a new speed which is between 1 & 2: Because half the time you’re at moving speed 1 and half the time at speed 2, on average you are moving at 1.5 and all the projectiles miss you because none of them move at that speed. You are effectively moving at a “float” speed despite everything being “int”, the game counting movement, speed, position in “int” and being unable to draw anything more high-resolution than an “int”. If you know about this problem then the game because no fun at all, as reaching a high score only depends on how long it takes you to get bored of carelessly tapping.

The solution is that the projectiles should also move at float speeds, ignoring the fact that on the screen you only have 0 to 48 discrete positions you can draw them at. This is also a bit annoying because, seeing as everything is “int” I leaned on the standard library’s image types like Point, Rect etc. for position, drawing, collision detection etc. and I didn’t feel like rewriting all of those. Instead I changed only the projectile’s Coordinates and Velocity to float64. Coordinates was an image.Point, so I introduced a new internal type Point that uses float64 instead of int. Of course, all the other code that uses these immediately broke because it’s expecting a real image.Point, so I added a Pt() method that converts the values to int (rounding to the nearest whole number) and returns a Point of that. This was easy to plug in at the places that needed it without having to tediously convert all of the game code to floats. Now, even though the game can really only draw at integer values, its internal model has a higher resolution that lets it use more intermediate speeds and catch you if you change speeds frequently.

As a result, instead of the previous speeds randomly selected from the integers 1, 2 & 3 the speed can be any random float64 value in the range from 0.8 to 3.0. I kept the 3.0 speed in there because with only the slow ones the game looked a bit boring. I might lower the upper limit a bit if this has made the game too easy now. The increased resolution in between 1.0 and 2.0 adds a lot of projectiles that will hit you while you’re changing speed and the problem is solved: You can now no longer win the game by mindlessly tapping at a constant tempo.

Another lesson from this is that when choosing between int or float64 for numeric types in your game, if the value is about how “much” of something (like here the speed) then use float64 and if it’s about how “many” then use int. Okay, you may be able to count the 48 pixels to the top of the screen and say “how many” but that’s just how it is being rendered. In fact I’d recommend using float64 for basically all of your game logic related numberic types and only using ints for things like the index of items in a list you’re looping through or picking items from, and nothing more than that.

Launched a new game: Freefall

On 27 February I released a new Nokia 3310-style game: Freefall. In this game you control a parachute for humanitarian airdops in hostile territory. It’s my entry to Nokia 3310 Jam 5 and the theme was Fast & Slow so the main game action revolves around controlling the speed of the airdop between parachuting and freefall to dodge bullets coming from both sides.

The aim of the Nokia 3310 Jam is to have fun making a game using the restrictions of a Nokia 3310, so green, low-res, 1-bit screen, monophonic and only 12 keypad buttons. My entry placed 28th out of a 147 submissions and I’m especially proud of this because I did the music, animations, programming and game design all by myself. The game is open source and you can read it in the GitHub repository.

Always prefer accessing GitHub over SSH than HTTPS

This is to avoid accidentally cloning a repo as read-only when GitHub defaults to HTTPS links, and then having to edit the gitconfig later to get an SSH URL you can push to. Add these 2 lines to your global .gitconfig file in your home folder to override all github.com URLs from HTTPS to SSH:

[url "ssh://git@github.com/"]
     insteadOf = https://github.com/

Why though?

Note, this is not for all git remotes, only GitHub. I have a similar setting for the GitHub Enterprise instance we use at work. Generally though, for most remote servers I’m fine with whatever it gives me, which is usually HTTPS.

The difference becomes important if I ever want to contribute (i.e. push) to the cloned repo, as is mostly the case when cloning my own repos or work code. Continue reading

Ebiten vs PyGame

The following is a copy of a response I wrote to a university student asking in the Ebiten Discord server whether they should use Ebiten or PyGame for their first time making a game:

Having used both I can say that PyGame provides much more out of the box but that this is not just a pro but also a con. For example in pygame there is a concept of “sprite” that has movement and you can tell it move left, move right etc. In Ebiten it surprised me to find that there is no such thing but it’s nice for two reasons: Continue reading

Launched a new game: Cr1ckt

Direct link to game: https://sinisterstuf.itch.io/cr1ckt

On the 1st of December Tristan, Rowan and I released the first version of Cr1ckt, a tricky platformer where you need to jump to avoid water and get to the fruit. It’s our submission for the GitHub Game Off 2021 game jam, an annual challenge to make a game based on a secret theme within the month of November. The theme this year is “BUG” so apart from playing as a cricket it also has some fun, intentional bugs.

It’s got downloads for major desktop platforms Windows, Linux & Mac, as well as Android. They’re quite small so you should be able to download and play quite fast. You can get the downloads or play online in your browser on the game page at sinisterstuf.itch.io/cr1ckt.

As hobbyist game developers in our free time this is one of the Continue reading

3D-printed caps for protruding bolts

When I attached our children’s swing to the ground there was still a significant piece of sharp-ish threaded metal sticking out above the bolt head and I was worried about them falling on it. Grinding the end off might still leave some sharp parts, so I thought it safer to print plastic covers for them.

I designed the caps with OpenSCAD, using the ScrewsMetric library for the bolt-shaped inset.

You can see the source code for Continue reading

3D modelling replacement knobs for back massager

small wooden knob

small wooden knob

There’s this fantastic device we have at home that I’m fairly sure is for giving back rubs, or maybe massages in general, like on your legs or something. I’ve tried it a few times but mostly the kids play with it. However it bothers me that there’s holes in it where the little knobs are supposed to be, so it doesn’t roll properly. I think the kids pulled them out, but maybe Continue reading

First time in Hacktoberfest

This year was my first time participating in the online Hacktoberfest event.

I often use code from GitHub and occasionally publish my own projects there but I realised I rarely contribute to other people’s code. Hearing people talking about the event on the Ladybug Podcast, I was inspired to make a small pull request. The boost I got from something so insignificant being merged lead me to look through my favourite projects’ issue lists to see if there was a bug I could fix or a missing feature I could implement.

Continue reading

Fixing a typo across multiple repos

Yesterday I found a typo in a pull request description while browsing another team’s project which I stumbled upon. I mentioned it to the author but it turned out that that part of the text came from the repository’s pull request template, which means every pull request will have this amusing but irritating mistake. I sent them a pull request, modifying the template, to fix the mistake at the source and avoid it in future, and thought that would be the end of it.

It turns out that template was written once and then copied across to new repos, which means this typo actually exists in almost all the pull requests in all of that team’s projects. Well that escalated quickly. This is the point where the average person probably says “OK whatever, it’s not worth it for something so small, there are too many repos, it’s just a small typo, never mind” and stop. A very determined person might actually start opening browser tabs and psyching themselves up to do pull requests. I open my terminal emulator and start writing a for loop. Continue reading