4 ms·
Tangential, but let's say I want to build a multiplayer game, where players (untrusted users) are allowed to run arbitrary code in some kind of a VM. I've so fa
by rollcat 2y ago
Tangential, but let's say I want to build a multiplayer game, where players (untrusted users) are allowed to run arbitrary code in some kind of a VM. I've so far established that:
- The VM has to be built in a safe and performant language (like Rust, Go, or - if careful - modern C++), and available as a library to integrate with the rest of the game. However I don't trust myself to write safe C/C++ (the game is being prototyped in LÖVE/Lua).
- Each VM instance needs a tight execution/instruction budget, to avoid stalling the server's main update loop; e.g. a timer/virtual "hardware interrupt", or simply counting cycles, or even something modelled after eBPF. The total number of VM instances running in a single game would also need to be limited somehow (e.g. making a key component scarce and/or non-renewable, or dividing the total instruction budget across all VMs, or requiring a player to be present in a nearby world chunk).
Use cases are something like redstone in Minecraft: curious and technically-inclined players could build contraptions, like auto-farming crops, pranks/traps, defences, fancy gates/moats, etc. Not the core of the gameplay, but rather one aspect of it, for the curious to explore, learn, have fun with.
There are many off-the-shelf VMs that do RISC-V or similar ISAs, and I'm considering picking one of those, but wondering if a RISC instruction set isn't too low-level for such a thing. On the other hand, it would be nice if the knowledge would be directly transferrable to the real world.
Anyone tried to build something similar and can share their experience?
- whytevuhuni 2y agoAren't you describing the ideal scenario for WASM here? Some runtimes like wasmtime have a concept of fuel [1], which can limit the execution time. One of the Rust-based Lua VMs, piccolo [2], was also made specifically with the ability to be interrupted in the middle of anything, by being stackless. [1] https://docs.wasmtime.dev/api/wasmtime/struct.Store.html#method.set_fuel https://docs.wasmtime.dev/api/wasmtime/struct.Store.html#met... [2] https://news.ycombinator.com/item?id=40239029 https://news.ycombinator.com/item?id=40239029 (see "Fuel" on its article)
- rollcat 2y agoActually Piccolo sounds like the ideal solution here, if I were to stick to LÖVE/Lua. It could be weird/confusing to have completely different VMs for the in-game contraptions vs the game engine itself (LuaJIT), but I think the narrow gap could attract players to become modders/contributors. Thanks for the suggestion!
- Scarjit 2y agoI would go with lua for the players. You can easily sandbox it, by not compiling in the dangerous functions. Using debug.sethook you can limit execution by count (https://www.lua.org/pil/23.2.html https://www.lua.org/pil/23.2.html). And finally you can bring your own alloc for lua. There are also decades of articles on how lua works with C and C++, and you can find examples for Rust and others too.
- fwsgonzo 2y agoThat's what libriscv excels at. It's the ideal solution for exactly that https://libriscv.no/docs/intro/ https://libriscv.no/docs/intro/
- xyzzy123 2y agoI'm not an implementor but this particular set of requirements has been explored pretty extensively by blockchain developers wanting smart contract execution environments. See e.g: https://www.nervos.org/knowledge-base/comparing_blockchain_virtual_machines https://www.nervos.org/knowledge-base/comparing_blockchain_v...
- andrewstuart 2y agoRun headless chrome and execute each script on a web page.
- rollcat 2y agoI understand you mean it as a joke, but unironically, it's among the most widely deployed sandboxes in the world, which actually would make it a worthy contender if not for the resource requirements, complexity, and the upgrade treadmill.
- goodpoint 2y ago> if not for the resource requirements, complexity, and the upgrade treadmill. this is what makes it a joke
- andrewstuart 2y agoBut if you need something that is genuinely secure and actually works, you'll find it's not actually that complex and the upgrade treadmill does not exist - on linux it is up to you if you upgrade headless chrome though obviously a good idea from a security perspective.
- andrewstuart 2y agoQEMU microvm microvm’ virtual platform (microvm) microvm is a machine type inspired by Firecracker and constructed after its machine model. It’s a minimalist machine type without PCI nor ACPI support, designed for short-lived guests. microvm also establishes a baseline for benchmarking and optimizing both QEMU and guest operating systems, since it is optimized for both boot time and footprint. https://www.qemu.org/docs/master/system/i386/microvm.html https://www.qemu.org/docs/master/system/i386/microvm.html
- deleted 2y ago[deleted]
- xnorswap 2y agoYou probably don't need what you're thinking of a "VM instance" to run a VM, and for games you may well be better off building your own VM, although that depends how far down "arbitrary code" you go. There are a few Zach-like games which achieve this kind of thing. The scope of the VMs they build are different, the VMs in Shenzen I/O are quite different to that of TIS-100. Likewise non-zach zach-like games like "Turing Complete" also let you build through VMs. These aren't the kind of VMs you might expect, they're not full x86/x64 emulators, they're very simple virtual machines that have can handle a small abstracted instruction set. If you restrict the VM to executing a limited number of instructions/cycles, then you don't need it to be super performant in terms of clock cycles. More important is to define the memory limits of your VM. This is a key constraint that will keep processing feasible but also keeps understanding to be manageable for the player. If I recall correctly, TIS-100 has 1 general register and 1 accumulator register in each general cell. I don't remember now if there are also special memory cells, but if there are, I suspect the total amount of memory is of the order 64 bytes or so. Other similar VM games have more memory support, but typically top out at 16KB. What's the actual gameplay loop you'd like to achieve? Defining that will help define and shape the constraints you put on players.
- rollcat 2y ago> You probably don't need what you're thinking of a "VM instance" to run a VM, and for games you may well be better off building your own VM [...]. Indeed. I want something less awkward than redstone; I'm also considering something like fCPU[1] or eBPF (no jumping back = no loops = super easy to keep an upper bound on execution budget). [1]: https://mods.factorio.com/mod/fcpu https://mods.factorio.com/mod/fcpu But one of my side goals is to attract players who might be interested in contributing to the core game, so I also like whytevuhuni's suggestion[2] to embed a Lua interpreter. That's a faraway stretch goal (I still have very little in terms of prototyping), but I'd like to keep my options in mind. [2]: https://news.ycombinator.com/item?id=42493118 https://news.ycombinator.com/item?id=42493118 > What's the actual gameplay loop you'd like to achieve? Defining that will help define and shape the constraints you put on players. The general direction is something like Minecraft (with some Factorio / Oxygen Not Included thrown in), with focus on exploration, self-expression, collaboration, and a kind of lore/storytelling (that's deeply personal, like GRIS but still in a generative sandbox). For example, people have made pixel art in Minecraft by meticulously placing blocks, one by one, on a huge area, and then creating an in-game map of it all[3]. I'd like my game to feature a pixel art editor instead. Same goes for in-game coding/automation: I want to reduce the friction from an idea to seeing it in-game. [3]: https://minecraft.wiki/w/Map https://minecraft.wiki/w/Map Thank you for all the suggestions!