Panzerschrek
Panzerschrek on Hacker News
Is it memory safe? Or is it yet another "better C"?
Recently I did something similar (or even more labor-intensive). I recreated an existing game from scratch by manually rewriting its code without even thinking about LLM/"AI" tools usage. (see my submissions).
But I agree, that using an "AI" tool may be a serious temptation and thus way less new porting projects will be done with such care.
> there is something more important than license: community
Is there such thing as "community" at all? As I know, the majority of open-source projects are developed by a single person, where others only contribute bug reports (in best case). It's not a community, if there is such imbalance in contribution and power.
Only a handful of projects (a small percentage) has actual community with many members doing meaningful contribution. But they are most notable ones, so that one may think, that all open-source projects function like this.
I do this in another way:
for( size_t i_plus_one = count; i_plus_one > 0; --i_plus_one )
{
const size_t i= i_plus_one - 1;
// actual loop code
}
It's in my opinion better than using i-- as condition, since I generally avoid using results of -- and ++, because doing so is bug-prone.
> How do we find the association values? We sort the characters by how many keys they touch. We then take them one at a time and try 0, 1, 2, … until we find a value that does not cause a collision.
This sounds too easy to be true. As I understand, that's the core of the whole approach - to find a table filled with some magic values giving perfect hashing. And it shouldn't be that simple, since search space is huge (a table with 256-values each with 8 bits size at least).
Nice approach.
I hope some time compilers will eventually learn to detect code containing a bunch of if-else with string comparison and replace it with perfect hashing.
> Memory is a handful of data stacks that the compiler assigns statically
I doubt this can work well in all cases. Sooner or later one needs proper heap.
I don't know what Unreal Tournament did use internally, it's hard to investigate, since there is no (official) source code release for it. But I do know, that brush-based (additive) approach isn't strictly necessary for creating maps for Quake/Quake II/Quake III, it's technically possible to write a map compiler taking maps in some subtractive format. The reason why it's not done (or at least not common) is because it's not a trivial task and because existing infrastructure adds some friction.
Trenchbroom is very good, but I still think, it's not the best possible map editor. It uses brush-based approach, which isn't the right way of designing maps for games in closed spaces (like Quake). Creating each room requires creating at least 6 brushes for its walls/floor/ceiling, which is way to much for such stuff. On the other hand Unreal Editor (for first Unreal and Unreal Tournament) supports creating rooms directly (as subtractive brushes), when two room primitive touch each other, they are automatically connected.
I see little to no benefits of introducing such "traits" into a language having duck-typing in templates. It may sometimes improve code readability (slightly), but with more boilerplate code for traits handling in exchange. And the result machine code will be identical to code with no traits at all (with only duck-typing).
C++ is a good example of this. It had duck-typing in templates for decades. Then some sort of trait-like mechanism named concepts has been introduced. The only benefit of them seems to be slightly better error messages if someone misuses a template class/function.
Does it have automatic error handling, so that if one command fails, the whole script fails too? Last time I tried it, I needed to write
if ($LastExitCode -ne 0)
after each command.
Typical C approach.
In C++ this should be done with std::variant instead. It has the exact same binary layout, but is type-safe (compared to union usage).
Does std::polymorphic require passed types to be copyable?
My app doesn't require sandboxing. And vulnerabilities aren't important, since it's not intended to work with untrusted data and/or use network.
I once tried packaging my application using Flatpack. But I saw no benefits of using it. I can as well just link all my dependencies statically (which I eventually ended using).
> Turn your Database class into a state machine with an uninitialized and a connected state. Then have a Database.connect()
It's a bad advice. It's preferred instead to have a connect function returning a database instance in a successful case or an error otherwise.
All this seems for me to be overcomplicated. Naturally parsing is just a function, which may call subfunctions, sometimes recursively. Sometimes it can do it in a loop - in order to parse sequences.
I have written many parsers in such a way and I didn't even require such terms as "parser combinators".
Software renderer of Quake II has no colored lighting. It's OpenGL-only feature. Half-Life and Unreal do this better, they support colored lighting in their software mode.
> Games worth trying
I can add more:
Unreal (and Unreal Tournament), Thief, Quake II (a slight improvement over Quake), Half-Life (a great improvement over Quake), Shadow Warrior,
Any modern port of Doom supporting software rendering, Heretic, Hexen, Descent, System Shock, Homeworld.
> Imagine that you had a streaming world game where as the player ran around the world, old level geometry would deallocate, and new level geometry would allocate and stream in from disk.
In such case stack-like allocator isn't the best strategy. One can use some sort of cyclic allocator instead. As I know Quake did this for surfaces cache.
> Once again, these allocators work fine in multithreaded environments
How? As I understand, for such double-headed allocator to be multithreaded one needs to update two counters atomically, which is tricky.
> There's no separate database server. You open the database file through SQLite's C API.
> Every request spawns a fresh process.
How does it work when multiple concurrent requests are possible? Does SQLite allow simultaneous write access from multiple processes?
> A news site doesn't need to do audio processing on my machine and read back the buffer? It doesn't need to use webgl to render triangles to an offscreen buffer?
We should go further. A web-site with mostly static content should not use user-side scripting (Javascript) at all, it's unnecessary for it. It should be required only in rare cases where a site is basically an application and require manually turning it on each time such application is opened.
The ability to hold a reference to a container and its member seems to be interesting. But I don't think it adds significant value in practice (behind some synthesized examples) and doesn't worth to increase language complexity language compared for a more coarse reference analysis (variable-based).
> the compiler remembers where a reference points to
> So we spent months sharpening the explanation and figuring out its benefits, and wrote a post 8 on it last year, hoping other languages would pick it up.
My language (see my submissions) has this feature since many years. In its current form it exists roughly since year 2020, but some under-the-hood changes and slight improvements have been done since.