DEX
Posted 4 days ago
Three months ago I decided to start following a hunch.
A little backstory: way back in the days before WebAssembly, Emscripten (the most popular C++ to WASM compiler) used to be this wacky fork of LLVM, which, instead of translating C++ into bytecode, was capable of printing out… pure JavaScript???

Anyone who’s ever used JavaScript immediately knows how wtf bonkers that sounds, but Emscripten wasn’t really about the “why,” it was about the “how,” and they proved it could be done. It didn’t really matter how fast/slow the module was, the cool thing was that all of a sudden you could have DOOM running in your browser despite the fact that it was a completely sandboxed web environment.

Long story short, Emscripten has somewhat moved on since then (though the pure JavaScript support lives on through WASM2JS I believe) but the core principles remain the same: whatever you’re actually allowed to do with the hardware, do it, and emulate everything else (libc, filesystem, fibers, etc). Which is awesome, because again, the end result is completely sandboxed. You can do whatever the hell you want with memory because your “memory” is really just a massive JavaScript byte array with the stack at the beginning and the heap taking up the rest.

About a year ago I came to the realization that “hey, C# is actually LESS restrictive than JavaScript in many ways, even if it’s whitelisted out the ass… if they could do it for the web, why can’t we do it for s&box?”
And then I remembered that compiler development is a major-league pain in the ass and filed that idea away.

After all C++/CLI kinda exists, which isn’t whitelist friendly but it’s similar enough that if someone wanted to touch the assembly up, they could port a C++ app to s&box with a little elbow grease. Way easier than actually transpiling. I made a proof of concept of this ages ago which was an editor tool to patch the C++/CLI assembly in with your C# assembly, and it did generally pass ILVerify. But you were limited to the “pure” mode, which meant no pointers, and you had to use .NET types. But at least it passed ILVerify without complaints.

Then Facepunch removed ILVerify and switched to just… compiling code on the fly. Well shit, writing your game in boring goody-two-shoes C# is now mandatory. Bye-bye assemblies.

But like, I adore C#, but I’ve also grown to kind of fucking hate it at the same time because of all the restrictions placed on you by the whitelist. Chiefly, it’s damn near impossible to use any external C# libraries without needing to rewrite atleast some of the code to get rid of stackallocs etc. Plus, you have to include them in your codebase, and s&box’s compile steps are really rigid so you can’t just modify the csproj to add an external folder, or add build steps to do any kind of code transformers etc. And look, don’t get me wrong, this is probably the perfect ecosystem to be developing from-scratch fun little games in. But it’s a little restrictive for the kind of world shattering shit-your-pants on the spot “how the fuck is this possible” type of project. You know the ones I mean. Like DOOM running in a web browser.