Show HN:我们的太空游戏内置了可运行 Linux 的 RISC-V 模拟器
Show HN: Our space game has a built-in RISC-V emulator that runs Linux

原始链接: https://againstallodds.games/blog/2026/10/03/our-risc-v-emulator-pasriscv/

PasRISCV 是一个开源的、基于 Object Pascal 的 RISC-V 模拟器,为 SEEDS 中完全仿真的 Linux 计算机提供支持。它采用 zlib 许可,实现了一套完整的虚拟 64 位 RISC-V 系统,包括 RV64GC/RVA23、SMP、中断、存储、网络,以及虚拟机监控器、向量和密码学扩展。其混合解释器与追踪 JIT 在 x86-64 主机上可支持实际执行的大约 99% 的指令,并可选启用软件 FPU 模式,以实现严格的 IEEE 754 行为。 SEEDS 通过 OpenSBI 和 U-Boot 启动定制的 Alpine Linux 镜像。磁盘镜像可以使用 VirtIO Block、基于 PCIe 的 NVMe、VirtIO-9P 或 VirtIO-FS。图形系统使用配备自定义 MMIO 的高性能 SimpleFB 帧缓冲器,也支持 VirtIO GPU、VirGL、Bochs VBE 和 Cirrus Logic。音频支持 CMI8738、FM801、Intel HDA 和 VirtIO Sound,并包含 OPL 与 PCM 合成。 游戏和来宾系统通过 vsock 通信,使用快速二进制序列化、优先级消息以及请求—响应交互。模拟器还提供 IPv4/IPv6 NAT、内置调试器与反汇编器,以及 GDB 服务器支持。不过,为确保安全性和可复现性,游戏中的出站网络仍被禁用。

一家获得 demoscene 社区支持的小型独立工作室正在开发 **SEEDS – Echoes Beneath the Sands**,这是一款以太空生存和星球生态改造为主题的游戏,使用 Object Pascal 编写。其突出的技术特点是 **PasRISCV**:一款开源的 64 位 RISC-V 模拟器,直接嵌入游戏之中。 PasRISCV 可模拟现代虚拟机,支持 RV64GC、多 hart、RVA23.1 特性、向量扩展和虚拟机监控器。它能够通过 OpenSBI 或 U-Boot 启动 Linux,目前使用的是定制的 Alpine 3.23 环境。该模拟器将解释执行与 x86-64 跟踪 JIT 相结合,并支持 VirtIO/NVMe 存储、帧缓冲及其他图形适配器、多种音频设备、IPv4/IPv6 网络、调试功能和 GDB 服务器。 在虚拟 Linux 系统中,玩家可以使用 Ruby、Python、Rust、C、C++ 或 Go 等语言编写原生 RISC-V 程序。该工作室还开发了 PasVulkan 引擎、物理引擎和 POCA 脚本语言。后续计划包括自动化系统、可入侵的游戏内电脑、玩家创作的游戏,以及 DOOM 等经典软件。 该游戏目前仍在积极开发中,尚未进入抢先体验阶段。PasRISCV、PasVulkan 和 POCA 均已在 GitHub 上开源;PasRISCV 采用宽松的 zlib 许可证。
相关文章

原文

Our RISC-V emulator PasRISCV

You may already know that our game SEEDS includes a fully emulated Linux system, which runs our in-game tools for the player. For example, if they are accessing the planetary overview and stats through the program selector on the computer in the homebase, these apps are native Linux programs. Even if you’re playing the game on a Windows machine, these ELF binaries are executed on this emulated RISC-V 64-bit system running the Alpine Linux distribution.

I want to take the opportunity to let you peek behind the curtains and tell you a bit about our emulator. It is powered by our in-house PasRISCV project, which is programmed in Object Pascal and accessible to everyone as free open-source software (FOSS). You’re invited to check out its sources and maybe even make use of it. PasRISCV and its frontend companion pasriscvemu are licensed under the permissive zlib license.

fastfetch on the in-game computer in SEEDS: Alpine Linux riscv64 running on PasRISCV
fastfetch on the emulated computer inside our game:
Alpine Linux riscv64 running on PasRISCV
oh, and spot the typo…

Emulation

First, there are two ways we could have done this: emulating only the userspace, or emulating a complete virtual machine. For PasRISCV we chose the latter and emulate a machine including display and storage devices, interrupts, everything down to the last thing, so that for the running kernel it appears as a complete hardware system, even though it’s virtual.

The emulated machine uses the 64-bit RISC-V instruction set architecture (ISA), which, in contrast to most proprietary architectures – like x86 and ARM – is an open standard and completely open and free to use under a permissive license. That means if you’re building a new hardware device based on it, you don’t have to pay any royalties for using the RISC-V ISA itself.

On the technical side, the system provides SMP/MultiHART, RV64GC, and RVA23 support, including the Hypervisor and Vector extensions, together with additional scalar and vector cryptography extensions. Nevertheless, listing and explaining all emulated features is beyond the scope of this introduction, so to get a full overview of the emulation head over to the PasRISCV repository.

CPU and FPU

To emulate the CPU, the emulator uses a hybrid approach: an interpreter combined with a tracing JIT compiler. As of now, the JIT is limited to x86-64 hosts, but about 99% of the instructions we encounter are supported by it.

Floating-point operations, for example, can be handled directly by the host FPU. For cases where stricter behaviour is required, PasRISCV offers an optional mode that combines software floating point with the interpreter. This exists because IEEE 754-2008 specifies some behaviour that can’t be reproduced exactly using the x86 floating-point hardware.

btop on the in-game computer
btop running on the emulated computer

Linux

If you start a new game or load a saved game in SEEDS, the emulator in the background is already booting the system. A normal Linux kernel can be booted in two ways: directly through OpenSBI or through U-Boot. For a direct OpenSBI to kernel boot, all required modules and, more importantly, the disk images currently need to reside in the initramfs. Therefore, we use the more traditional OpenSBI to U-Boot chain, which then loads and executes the kernel. This allows us to have a normal disk image which holds the system.

These images can be attached to the guest system either as VirtIO Block devices or as emulated NVMe hardware over PCIe. Disks can operate normally in read-write mode, but they can also be attached read-only. This is especially useful for our game as we can have a root partition that gets replaced by game updates. In addition, we keep a separate user partition for the player’s own data, like the high score tables of the mini-games, until we have a proper mechanism to hold that state in the game state itself.

Host directories can also be made available inside the guest through VirtIO-9P or VirtIO-FS. This is particularly convenient during development because we can compile tools directly on the host and then access them immediately from inside the emulated machine. Otherwise, we’d have to inject the binaries directly into memory, or use a separate exchange mechanism, or even worse, reboot the emulator on every little change.

Our game uses a slightly modified version of the lean and excellent Alpine Linux v3.23.6 system, which some of us also love to run on our servers, together with our custom kernel build. However, a recent stock Alpine image also runs without problems.

Graphics

For graphics, our virtual game screens currently access their displayed pixels using the emulator framebuffer device. More specifically, we use SimpleFB backed by a custom MMIO display buffer.

PasRISCV provides several other virtual graphics adapters as well. One option is VirtIO GPU, which supports EDID and 2D functionality, along with experimental 3D/VirGL capabilities. Through its PCI emulation, it also provides devices supported by drivers such as Bochs VBE and Cirrus Logic. We even managed to run an X server with the Motif Window Manager in the VM, but it’s a bit too slow to be really usable on most machines.

For our game, however, the simple framebuffer display is quite useful, as it’s fast enough and lets us process its output with custom shaders running in the game. This way we add additional retro effects such as scanlines, phosphor glow, and similar – I’m tempted to say beautiful, but that of course is in the eye of the player – visual degradations of the 80s and 90s.

Space Prowler title screen on the computer in the homebase
Space Prowler running inside SEEDS

Audio

The emulator of course also supports audio. We emulate retro sound cards, such as the CMI8738 and FM801, with PCM, OPL2, and OPL3 available on both. Intel HDA and VirtIO sound are supported as well. OPL and OPN are closely related Yamaha FM synthesis families that influenced the sound of the mid and late 80s and early 90s of various consoles and PCs.

Even professional synthesizers such as the Yamaha DX7 were powered by related FM synthesis chips. Newer cards featured PCM playback, often retaining FM synthesis only as a legacy feature, until later cards left it out completely. PCM allowed the playback of samples and quickly – and imho sadly – largely displaced the distinctive OPL chiptune sound. Back then, most people were fascinated by the more realistic-sounding music that used samples, instead of sound chips. So more and more games used the new sample-based sound.

Nowadays, the sound of OPL has a relatively large fan base in retro circles that love computer music. Various websites and archives provide easy access to the vast libraries of 80s and 90s chiptune music. Fitting our somewhat retro-80s theme, our little proof-of-concept space game running on the computer in SEEDS is called Space Prowler. It features a charming retro pixel style and has a dedicated chiptune as its title theme, which combines both OPL3 synthesis and PCM sound samples for the drums.

I actually wrote a small editor named chOPLin to compose this music. This so-called tracker runs entirely in a normal Linux console; it even works from within the game using the computer’s 80×50-character, 640×400-pixel framebuffer console, albeit creating music in that way is a bit cumbersome. I plan to release the tracker as free and open-source software once I have some spare time, as I still have to polish it and make it more user-friendly.

Integration

The link between the emulated machine and the surrounding game uses Linux Virtual Sockets (vsock) for its communication. Moreover, we use a small binary serialization format. Conceptually, it’s somewhat like a binary version of JSON, highly optimized for fast (de-)serialization. Data can flow in both directions, much like with a normal network protocol. We also have a small priority queue and message-reference system, so we can handle urgent, prioritized messages as well as request-and-response exchanges.

For example, imagine that the in-game computer is displaying the planetary sphere. The client program that sits inside the virtual computer can request updated information about things such as terrain information or the locations of animals, and receive this data from the game running the virtual machine.

We also have most of the wiring ready for players to be able to program, reshape, and populate the whole planet through automation. As it’s a normal Linux system, you’ll be able to use Ruby, Python, or even Rust, C, C++, and Go to change and automate your world.

That said, it’s not our primary concept for the game at the moment, as there’s just as much satisfaction in building things by hand and manually shaping the planet into something beautiful.

Running a certain game...
PasRISCV running a certain game…
Spaceship interior showing the ship's computer
Spaceship interior

Networking

The emulator also has real networking through its own Slirp-like userspace NAT implementation. It doesn’t rely on an external library for this, and it supports both IPv4 and IPv6.

As a result, the emulated Linux system has normal network access. For example, we can run Alpine’s package manager apk update and apk install to install packages directly from inside the virtual machine. Our own tools are also installed as signed Alpine packages.

However, networking is disabled in the game for the foreseeable future: the VM cannot make any outbound connections at all, mainly for security, isolation, and reproducibility.

Debugging

PasRISCV also contains its own custom disassembler and debugger. In addition, it can act as a GDB server. Although it currently is only partially implemented, this means you can use your preferred debugging tools with it, as long as they support GDB’s remote debugging protocol.

Coda

We hope you gained some insight into how SEEDS and PasRISCV function together to provide a fully usable, in-game Linux system to run our (and maybe in the near future your own) programs to create an immersive experience when taking on Naxiah’s journey in space.

And I don’t think I need to mention that Linux is a first-class platform for playing our game.
Fun fact: two-thirds of the creative and development team use Linux as their main OS. ;)

Alex | #emulation, #risc-v, #linux, #gamedev

Permalink |
联系我们 contact @ memedata.com