Andre Weissflog, a game and tools programmer, writes about C, WebAssembly, emulators, and handle-based memory design.
HN links it for the handles post, WASM debugging guides that a commenter found amazing, and his browser-based 6502 emulator projects.
Games are supposed to be fun for humans, and computers don't care. So why worry about players cheating at games when you can make the card dealer or the game itself cheat, with the goal of everyone having the most fun (or regret)? Stay true to the rules of the game, just not probability!
I've been playing the brilliant card game Fluxx -- Andrew Looney's chaos engine where the rules themselves are cards that change mid-game. Draw N, Play N, and the win condition all mutate constantly.
The game can change its mind about the rules, so what if the dealer themself is intelligent and vengeful?
I've been exploring this with what I call the 'Cosmic Dealer' -- an omniscient dealer that knows the entire game state and can choose cards for dramatic effect instead of randomly. It can choose randomly too of course, but where's the fun in that?
The dealer knows:
- Every card in the deck
- Every card in every hand
- The goal, the rules, the keepers
- The narrative arc, the character relationships
- What would be FUNNY, DRAMATIC, IRONIC, or DEVASTATING
The Cosmic Dealer has 11 modes: Random (fair pre-determined shuffle), Dramatic (maximum narrative impact), Karma (universe remembers your deeds), Ironic (you get exactly what you don't need), Comedy (implausible coincidences), Dynamic (reads the room and shifts modes), FAFO (Fuck Around Find Out), Chaos Incarnate (THE DEALER HAS GONE MAD), Prescient (works backward from predetermined outcome), Tutorial (invisible teaching curriculum),…
> Once you step away from automated formal verification, which is very rare to begin with, the programmer is always responsible for maintaining some nonzero number of program invariants.
Of course! It's nice to have all the help with that you can get.
> In my years of experience with Go, the manual work to close file handles when you are done is not particularly burdensome or difficult, and I have seen very few errors slip into production related to resource management which would have been solved by RAII.
Go has a GC which greatly reduces the number of things to manage, but the discussion is about Zig. In Go, if you add, let's say, a string to a class, you don't have to do anything, it will just work because of the GC. In Zig, if you add a string to a class and it didn't already have a close method for some other reason, you now have to update all the users. Essentially its unreasonably burdensome to switch from not managing a resource to managing a resource unless there are few users.
> That’s what I mean when I write “a class that manages a resource with RAII”. Just on a personal note—it can be damn frustrating writing a comment on HN sometimes, because somebody will always find a way to misinterpret it completely.
This wasn't some kind of pedantic point-scoring. In something like C++/Rust every single class that so much as contains a string manages a resource with RAII, but only a tiny number of them actually require you to write any cleanup code. In a language…
> C++ references do not help you with use-after-free, accidental concurrent modification or container/iterator invalidation.
Maybe I didn't express this clearly enough, but I don't use C++ pointers or references to store something that is more than just temporary, I usually go for indices instead. You should read the "Handles are the better pointers" article (https://floooh.github.io/2018/06/17/handles-vs-pointers.html) to understand a bit more of what I'm saying.
> with C++ still lacking concepts it's really no match.
I thought C++ already had concepts in C++20? (Though I honestly haven't got that much use for it, and I still use C++17 since I want to wait a bit until compiler implementations get mature).
> Rust's tooling blows C++ out of the water.
Agree with Rust's toolings being more polished than its C++ counterparts. I like that Rust has Cargo and also its own build.rs which you can code your custom build scripts in the same language. I also agree that Rust modules are much better than C++ headers (although modules are in C++20, I feel it's already a bit too late when so much existing code hasn't been written for it) The last time I looked at IDE support with Rust it wasn't that great, but that was quite some years ago so things might have changed a lot.
Not GP, but I think the ossification of WebGL has little to do with security concerns and a lot to do with the fact that the GL model is a poor fit to the direction hardware has taken over the past couple of decades. Realistically, any successor is going to be benchmarked to within an inch of its life too, so the same worry would apply.
The shape of that successor is still very vague, but it'll probably be closer to the Vulkan/Metal/DX12 generation. Various interested parties have been putting together exploratory proposals (see e.g. Mozilla's Obsidian), and Khronos appears to be accepting that "Vulkan everywhere" ain't going to happen and working on a "3D portability" initiative that's pretty much lowest-common-denominator. That would almost certainly have a web binding if it pans out.
Disclaimer: I don't work in this area, I just follow it out of morbid curiosity.
A few links:
https://www.khronos.org/api/3dportability/
http://floooh.github.io/2016/08/13/webgl-next.html
https://www.phoronix.com/scan.php?page=news_item&px=Mozilla-Obsidian-Graphics-API
Orthodox style argument aside, this project uses a build system written by the same author called fips[0]. I've tried it myself, and it's an absolute joy to use. A few simple commands will get you up and running on any supported platform, and it does an excellent job of telling you what went wrong if there's a failure. It also has a system for compiling the same shaders to multiple platform targets.
Oryol's demos[1] are impressive as well. Especially the ones that showcase emulation and various integrations of immediate-mode GUI frameworks.
The entire project is underrated in my opinion. With web assembly slowly coming alive, there's a distinct lack of small, multi-platform engines designed with the web in mind. I only wish Oryol's ecosystem was larger, it could be a realistic alternative to Three.js perhaps—if it isn't already.
Keep up the good work floeofwoe. :)
[0] https://github.com/floooh/fips
[1] https://floooh.github.io/oryol/
The point is that you can get some safety guarantees. Nowhere near the degree of guarantees available in safer languages, but still better than the status quo.
Edit: one example of a pattern, whose name I can't remember, was to switch from returning pointers to data structures, to returning pointer offsets as handles. Using these handles you can then track more information about validity and handle "null pointers" more sensibly rather than it introducing undefined behaviour. In superscalar processors the offset calculation basically costs nothing, but the additional safety can be considerable. I believe I read about this pattern in game engines, let me know if you know the name of it!
Edit 2: I think this is it:
https://floooh.github.io/2018/06/17/handles-vs-pointers.html