ArduGolf - 18-Hole Mini Golf


recording recording_holes

Non-FX version (includes default course only):

ardugolf.hex (76.8 KB)

FX version (streams courses from flash chip, supports multiple courses):

ardugolf_fx.arduboy (38.9 KB)

Technical Details

Physics: as simple as possible. The ball is the only dynamic object and box-sphere is the only collision type. There is no broadphase; most holes have only around 15-20 static box shapes. State consists of the position, velocity, and angular velocity of the ball.

Rendering: huge credit to a1k0n’s post on 3d rendering, which convinced me that this game should be possible. Though the renderer in ArduGolf is written from scratch it incorporates ideas from this post:

  • vertical scanline rasterizer to to align with display addressing
  • Bayer dithering (ArduGolf uses 5-level instead of 17-level)
  • subpixel rasterization (ArduGolf uses 3 subpixel bits instead of 4 to prevent issues with large triangles around the edges of the screen, but the number of subpixel bits is adjustable at compile time. Unfortunately, the circle rasterizer for rendering the ball does not support subpixels yet)

Some care was needed to support rendering an environment all around the camera:

  • True perspective divide
  • Triangle clipping against near plane (three cases to handle: 1, 2, or all 3 vertices behind near plane)
  • Dynamic face sorting (not sure if a presorted approach can still work here)

Newton-Raphson division supports perspective divide and triangle clipping. The framebuffer is used for temporary storage during vertex transformation and face sorting. Some hand-coded methods for fixed-point multiplication may come in handy to others.


2022 Jun 9: fix overview bug (thanks @clintonium-119)
2022 Jun 7: initial FX version, streams hole info from flash chip, leaving about 9KB prog free to implement other stuff; course/hole selection UI; remove buttons from volume graphic at title screen; allow pressing B to cancel ball-in-hole camera fly by
2022 Jun 2: restart hole menu item in practice mode; animated “Hole in One!” overlay; sound ui at main menu and sound effects on hit, collision, and ball-in-hole.
2022 Jun 1: adjust holes 3 and 11 (holes-in-one possible on both); aiming left/right starts off slower but accelerates while button is held down, allowing for more fine-tuned aiming


This looks fantastic!

Can I add it to the FX Cart web site? If so, will you be sharing the code as I would also like to compile it for the 8BitCade XL which uses a different screen.

Actually for that matter can I add your Chess game?

1 Like

Damn the little rendering you got looks amazing I wanna try it out on the hardware. Yeah hhmm emulator doesn’t seem to be happy with it. I will invoke the amazing @FManga and see if he has any ideas.

How did you make that gif without the emulator?

And you used badges! Sick!

1 Like

Ah the old ‘fmulsu’ instruction. Gets you every time.

It looks amazing😍! I applaud standing👏


That looks unreal :smiley:

I’m gonna have to at least take a stab at this one, but I imagine I won’t be able to get this working on an SH1106 screen due to the way it’s addressing works. But I have to give it a go.

EDIT: It works on SH1106 without any work on my end (beyond compiling the hex with the appropriate display selected in the IDE). Starduino doesn’t and I’d assumed I’d be out of luck here too. This is great :grin:

Games like this is why I love the Arduboy space. It’s so constrained at the hardware level, in so many ways, that we get to be blown away by games that really push the envelope.

It looks like a blast to play too! Exactly the kind of game I’d love to chill out with on a small device. :clap:

1 Like

Certainly – here is the code for ArduGolf and here are the title screens:



I used RetroArch for the original gif (I used RetroArch during development instead of ProjectABE) and my win32 port for the new ones that I just added (it has basic gif output).

1 Like

How is that possible? :thinking:

The teapot looks like it doesn’t render either.

This is such a solid game it’s exciting to think that the platform is expanding beyond the hardware!

Sorry, I did have to compile the hex using Mr Blinky’s arduino plugins. But I have to do that for every game. What I mean is that no additional work was required. Some games need some additional tweaking. I had (incorrectly) assumed this would be one of them - that there would be some custom rendering involved that would need accounting for.

Ah ok! I was like whoah someone crafted a magical hex.

1 Like

:slight_smile: Yeah, if only. I updated my original comment to better reflect what I meant.

Seems like the emulator issue was fmulsu. Updated with another version that avoids using that instruction.

Just looked up the operation, that’s a pretty fancy and specific instruction. How are you working around using the instruction? Are you just doing the same operation in multiple steps? I suppose this instruction can run in less cycles so you’re losing some speed?

Very curious, very impressed!

I also noticed the documentation mentions something about a possible overflow condition depending on some kind of number formatting of 16 bit numbers so I don’t know if that is at all related to the crash?

Anyways, awesome work! This might just be my new favorite game!

I don’t know if there would be an opportunity for some kind of level editor for this?

1 Like

I’m with you there. It’s a blast. And a really well-balanced challenge level. Everything about this is so polished. Can’t believe it’s an initial release. Love the panning cameras, and the ability to get an overview or change the pitch between strokes.

Custom courses loaded to the FX… that would be sweet :grin:

1 Like

It turned out to not be too bad: fmulsu does the same thing as mulsu but shifts the result left once. The intended purpose is for multiplying two 1.7 fixed-point numbers to get a 1.15 result instead of a 2.14 result – then you can get the result in 1.7 format by grabbing the high byte. So each fmulsu can be replaced with a mulsu and left shift: example.

The emulator implements fmul and fmuls but not fmulsu. The ProjectABE disassembly view clued me in to this (each unknown opcode is an fmulsu):

As for a level editor, my flow was to make the level geometry in blender.

After exporting to .obj from Blender, the CMake build process for the Windows build automatically converts the .obj files into header files. Then the physics shapes are defined in a basic IMGUI-based editor which is included in the repo:


Seriously next level! Thanks for sharing!

Awesome … I was able to add them to the overall cart and curated cart.

I will have to compile the XL version when I get home.

I’ve played a lot of this yesterday. Definitely my new favourite.

I do have a couple questions/suggestions.

I find a couple of holes might benefit from some minor tweaks:

On hole 11, the first angled wall seems to completely deaden the ball more than the others. Even going at full power, the ball barely gets up the first section of the ‘loop ramp’. I could just be projecting my desire on the ball here though :laughing: And perhaps that’s by design that you can’t on the first shot.

On hole 3, a full power shot almost makes it up the ramp after the first corner, but can’t seem to quite get there. Would be nice to have the potential for a hole in 1.

A couple questions/feature suggestions come to mind as well. I realize this is the initial release, and that you may well have other updates/features already in mind, but I thought I’d list a few, just cause this is such an amazing game, and has tremendous potential for expansion.

  1. Any plans for sounds? I think a nice stroke sound and, especially, a sound when you cup it would be really satisfying, and probably all the sounds you’d really need in this game.
  2. A little celebratory “Hole in One!” text overlay could be a nice touch.
  3. 2 player stroke and skins modes? This would be amazing, IMO. Not may Arduboy games lend themselves to a great 2 player experience, but this one certainly would.
  4. Saving/viewing best scores/round histories
  5. Restart hole option in practice mode.

Again, without any of these suggestions in place, it’s already a near-perfect experience. Thanks so much for putting this in our hands. It’s really got me rethinking what’s possible on the Arduboy. I’m sure a lot of people are going to come up with amazing 3D experiences as a result of this.


Thanks a lot for this great feedback! I agree with your thoughts on holes 3 and 11 and will try to tweak them later today.

Prog space is an issue for adding much more functionality. What I think would be cool is to have an FX edition that loads courses from the flash chip, and maybe streamline the editor process a bit so others can more easily make courses. I just got an FX recently but haven’t toyed around with the flash functionality yet. Moving the current 18-hole course out would free up about 8 KB which would allow adding sounds or more game logic and UI like for two-player modes.

Presently at least, there’s probably enough prog left for the hole-in-one overlay, saved scores, and a restart hole UI. I’ll work on those. :smiley: