Arduboy FX-C: A Credit Card-Sized Retro Gaming Device

This site contains affiliate links (including Amazon, eBay, AliExpress, and others). If you buy through these links, I may earn a commission at no extra cost to you. As an Amazon Associate I earn from qualifying purchases.

I recently got my hands on the Arduboy FX-C, an open source 8-bit gaming device that’s about the size of a credit card and comes loaded with over 300 games.

I’ve been playing with it for about a month now, and this thing is seriously cool. It’s incredibly thin, gives off great retro vibes, and because it’s based around an Arduino-compatible microcontroller, you can actually build your own games for it.

Spoiler alert: I ended up building one of my own, called Mostly Logic, which I published on GitHub: https://github.com/MostlyBuilds/mostly-logic-arduboy

Seeed Studio sent me the Arduboy FX-C for free so I could check it out. If you’re thinking about picking one up, you can find it on Amazon using my affiliate link: Arduboy FX-C(Amazon). Use code 4Z3K882A for 10% off!

Check out my full Arduboy FX-C video review below, where I take a closer look at the hardware, play some of the included games, and build my own game from scratch. If you want to follow along with the programming portion, I’ve also included the sample code from the video further down in this post.

Hardware & Design

The first thing that surprised me was just how small this thing actually is. It’s roughly the size of a credit card, but a little thicker at around 5.8mm.

The front of the case is clear, so you can see the PCB underneath, while the back is metal. The buttons have a surprisingly good clicky feel for something this thin, and it uses USB-C for charging and flashing.

I’ve been carrying it around with me for the past few weeks and feel like I’ve barely scratched the surface of the 300+ games that it comes with.

The hardware is built around an ATmega32u4, which is the same microcontroller used in boards like the Arduino Leonardo and Micro. That also means the Arduboy is much more than just a tiny game console. You can write your own games and flash them directly onto the device.

Building My Own Arduboy Game

Of course, it wouldn’t be a MostlyBuilds project if I didn’t try building something for it.

You can develop Arduboy games using tools like the Arduino IDE or VS Code, but I ended up using Arduboy Cloud. It runs directly in Chrome and includes a code editor, sprite tools, and even a built-in Arduboy simulator. It’s a really impressive all-in-one development environment that runs entirely in your browser. You can write and run an entire game in the simulator without even owning an Arduboy, then connect one over USB and flash your game directly to the device when you’re ready.

I started with a really simple demo where I could move a block around the screen using the D-pad. From there I added a cannon, projectiles, and deflectors that could change the direction of the projectiles.

That little experiment eventually turned into a complete game that I’m calling Mostly Logic.

Mostly Logic

Mostly Logic is a small puzzle game where you place deflectors to route projectiles through each level.

I ended up building seven levels that progressively introduce new mechanics, including switches, gates, and tripwires. There are also a few animations and some hidden features that I had way too much fun adding.

I published the complete source code on GitHub if you want to try it out or poke around the code.

Once the game was finished, I used the Arduboy cart tools to add it alongside the other games on my FX-C. There’s something really satisfying about scrolling through the launcher, seeing your own game sitting there, and actually playing it on the physical hardware.

Sample Code

If you watched my YouTube video and want to mess around with the sample code that I demoed, I’ve included it here:

#include <Arduboy2.h>

Arduboy2 arduboy;

// Cannon Sprite
const uint8_t PROGMEM cannon[] = {
  8, 8,
  0x7e, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x18,
};

// Position values for the cannon sprite
const int cannonX = 10;
const int cannonY = 28;

// Position values for the current projectile
int ballX = cannonX + 8;
int ballY = cannonY + 4;
// Crude boolean for tracking if the ball is moving up
// rather than the default horizontal position.
bool movingUp = false;
// Track the lastShot time in milliseconds
unsigned long lastShot = 0;

// Position values for the white square that can be
// positioned by the user via the D-pad
const int squareSize = 8;
int x = 50;
int y = 50;

// Position values for a deflector block that is placed
// by the user.
int blockX;
int blockY;
bool blockPlaced = false;

void setup() {
  arduboy.begin();
  arduboy.setFrameRate(60);
}

void loop() {
  if (!arduboy.nextFrame()) return;

  arduboy.pollButtons();

  // Handle D-pad button presses to set the x/y position for
  // the white block that the user can move around the screen
  if (arduboy.pressed(LEFT_BUTTON) && x > 0) {
    x--;
  }
  if (arduboy.pressed(RIGHT_BUTTON) && x < WIDTH - squareSize) {
    x++;
  }
  if (arduboy.pressed(UP_BUTTON) && y > 0) {
    y--;
  }
  if (arduboy.pressed(DOWN_BUTTON) && y < HEIGHT - squareSize) {
    y++;
  }

  // Place a deflector block when the user presses the A button,
  // and set the position based on the x/y values of the white
  // block that they can move around.
  if (arduboy.justPressed(A_BUTTON)) {
    blockX = x;
    blockY = y;
    blockPlaced = true;
  }

  // Detect if 2 seconds have passed since the last projectile
  // was fired.
  if (millis() - lastShot >= 2000) {
    // 2 seconds have passed, create a new projectile next to
    // the cannon
    ballX = cannonX + 8;
    ballY = cannonY + 4;
    // Reset movingUp since we are starting from the beginning
    // by the cannon
    movingUp = false;
    // Update the lastShot to the current time so we can start
    // checking for the next 2 seconds to be over.
    lastShot = millis();
  }

  // Dynamically adjust the position of the projectile
  if (movingUp) {
    // The ball is moving up, so decrease the Y value to
    // represent that.
    ballY--;
  } else {
    // The ball is moving horizontally, left to right, so
    // increase the X value.
    ballX++;
  }

  // Detect if the projectile has hit a deflector block
  if (blockPlaced && !movingUp &&
      ballX >= blockX && ballX <= blockX + squareSize &&
      ballY >= blockY && ballY <= blockY + squareSize) {
     
      // Hit a deflector block, set movingUp to true.
      // Note: this is very crude and assumes the projectile
      //       is moving horizontally before impact, and
      //       only handles a single change of direction (up).
      movingUp = true;
  }

  arduboy.clear();

  // Render the cannon sprite
  Sprites::drawOverwrite(cannonX, cannonY, cannon, 0);

  // Draw the deflector (if placed)
  if (blockPlaced) {
    arduboy.drawRect(blockX, blockY, squareSize, squareSize, WHITE);
  }

  // Draw the white box "cursor"
  arduboy.fillRect(x, y, squareSize, squareSize, WHITE);
  
  // Draw the projectile
  arduboy.fillCircle(ballX, ballY, 1, WHITE);

  arduboy.display();
}

Final Thoughts

I really like the Arduboy FX-C. Even if you have zero interest in programming, there are a ridiculous number of community-made games available for it, and there’s just something really fun about having such a tiny dedicated gaming device.

If you do want to experiment with programming, that’s where I think it gets even more interesting. The Arduboy community has built some great tools around the platform, and it’s surprisingly easy to go from messing around with a few lines of code to running something you made on the actual device.

I also think this would be an awesome way to introduce someone to programming, especially a kid who is already interested in games.

Check out the full video above if you want to see the Arduboy FX-C in action and watch me build Mostly Logic from scratch.

Links

Follow me on YouTube @MostlyBuilds if you’d like to see more projects like this.

Catch ya in the next one!