I built a Game Boy emulator in F#

· web hardware design · Source ↗

TLDR

  • Engineer built Fame Boy, a working Game Boy emulator in F# with sound, running on both desktop and web after hundreds of hours.

Key Takeaways

  • Architecture separates emulator core from frontends via two arrays (framebuffer, audiobuffer) and two functions, enabling desktop and web targets.
  • F# discriminated unions reduced 512 raw opcodes to 58 typed instructions; separate From/To types enforce hardware-legal states at compile time.
  • Mutability was adopted pragmatically: copying 16+ kB of memory per CPU cycle was too costly, unlike the pure CHIP-8 predecessor Fip-8.
  • A 16-line Flags module using inline pure functions replaced a DU-based setFlags array approach and improved emulator FPS by ~10%.
  • AI was used only for generating CPU test cases from specs, keeping implementation learning intact while catching bugs in existing instructions.

Hacker News Comment Review

  • Commenters broadly praised the F# type modeling, with specific technical feedback that struct discriminated unions ([<Struct>]) could further reduce allocations in Instructions.fs.
  • F#’s performance ceiling for interpreter-style workloads came up as a known tradeoff; the author’s pragmatic shift to mutability is consistent with community experience.
  • A thread of sentiment emerged around F# being permanently overshadowed by C# in the .NET ecosystem, limiting library ergonomics for idiomatic F# use.

Notable Comments

  • @debugnik: Flags registers typed as byte make the &&& 0xFFuy mask in setters redundant; suggests [<Struct>] DUs to cut allocations.
  • @redrobein: F# library ecosystem is largely C# handmedowns with no F#-specific docs, limiting idiomatic development.

Original | Discuss on HN