NConsole — A Custom 8-Bit Console Built Inside Godot

Hi everyone!

console

I’d like to share NConsole, a homemade 8-bit game console I designed from scratch and built inside Godot 4.7. It has its own CPU, instruction set, video and audio hardware, cartridge format, assembler, and debugger. No existing console is being emulated here — this is an entirely custom machine.

The console

  • N8 CPU: 8-bit processor with A/X/Y registers, a 64 KB address space, around 120 opcodes, flags, a stack, subroutines, and a VBlank interrupt.

  • Graphics: 160×120 resolution, 16-color palette, tile-based backgrounds, scrolling, sprites, and fixed status-bar rows.

  • Audio: four channels — two pulse waves, triangle, and noise — with note lengths and volume decay. Audio register writes are synchronized to CPU cycles.

  • Cartridges: a custom .nc8 format with banked program ROM and tile sets.

Development tools

The project includes a two-pass assembler with labels, local labels, expressions, and bank support. Tiles can be defined directly in assembly source.

There’s also a built-in machine-code monitor with breakpoints, memory write watches, single-stepping, execution tracing, and a label-aware disassembler. Press F2 while a game is running to open it.

Games

Both games are written entirely in N8 assembly:

  • Snake

  • Gem Hopper — a side-scrolling platformer featuring two levels stored in separate ROM banks, stompable beetles, gems, and a soundtrack.

Under the hood

The emulated hardware — CPU, video, audio, memory bus, and cartridge system — is implemented as a native C++ GDExtension. The assembler, debugger, 2D display, and interactive 3D console model are built in GDScript.

The project currently has 296 automated checks, including end-to-end playthroughs of both games. GitHub Actions builds for Linux, Windows, and macOS.

You can integrate the console into your own Godot project or run the included games using the provided 2D screen or interactive 3D model.

It started as a spin-off of a larger project: a Unix-like OS simulation for a hacker game. I wanted to see how far I could take the idea of a proper emulated machine inside Godot — and it grew into a project of its own.

Repository (MIT license): GitHub - uxerror/NConsole · GitHub

I’m happy to hear feedback, ideas, and suggestions, especially from people who have worked with real 8-bit hardware. A tile and sprite editor is next on my list!

5 Likes

Dude…

That thing is DISGUSTING :face_vomiting:

Good job

1 Like

Idk how you’ve optimized it to work but ig magic is magic, good job!

1 Like

Proper byte code is pretty fast! Especially if it’s tied to per-frame execution like this project is! I’ve been writing a game utilizing in-game programming through a RISC-V assembler and emulator without performance worry. GDExtension helps too I’m sure, but I’m mostly using it to keep my types and bits in order.

2 Likes

I wonder how much more effective it would be if you put everything into exe file made from assembly or C, probably ton but still it’s awesome that it’s not that bad of a performance

Emulating the game console would probably be faster without Godot’s overhead, there are plenty of smaller pixel-buffer renderers than Godot. Otherwise it’s already a GDExtension written in C++ so it’s not going to get much faster looking just at the console performance.

1 Like

Thank you! Honestly, there’s no real magic here: @gertkeno is right. The console is deliberately designed to be very small. It runs at 1.79 MHz, while the C++ core executes around 550 million CPU cycles per second on my machine. So the console uses roughly 0.3% of a single CPU core.
Emulating 80 frames of Snake takes about 0.5 ms, and mixing one second of audio across four channels takes around 2 ms. An assembly-written executable might save fractions of a millisecond out of the 16.7 ms available per frame. And in the 3D demo, rendering the floor on the GPU costs far more than the console itself.
The real resource constraints apply within the console itself: the game is allocated 29,829 cycles per frame — not a single cycle more.
I really enjoy writing software for such a constrained system. For example, in my next project, the Raycaster (which is already in the repository), I had to precompute tables for trigonometry, distances, and wall heights to avoid wasting precious cycles on calculations during gameplay. I also had to find ways to replace multiplication and division with table lookups, store coordinates and distances in fixed-point format, and pre-generate graphical tiles for combinations of neighboring rays. Even fish-eye correction had to be accounted for during the preprocessing stage.
These are exactly the kinds of constraints that make development interesting: instead of simply throwing more processing power at the problem, you have to find ways to solve it within a strictly defined resource budget.

Sounds great, is it public anywhere? I’d like to take a look at this.