Recent submissions

Comment · 3 years ago
Sorry to self-promote, but, Angeldust (https://angeldu.st) is a single, persistent, real-time voxel world going for about eight years now. Can handle 300+K players on a single server due to massive parallelism. Unfortunately we don't get those player numbers right now, but hopefully in the future!
Comment · 5 years ago
Angeldust, my 'fast and efficient' video game was on the HN front page for days in 2019: https://news.ycombinator.com/item?id=21858226

I now present the first, native, optimized build for all Raspberry Pi models that you can help test. It's fast, efficient and beautiful. You can play this forever, without DRM or limitations.

Thanks to amazing feedback from HN, I've added great features to the game over time, available on all operating systems:

– control remapping – pasting text (from password managers too!) – energy saving – quest rewards – additional languages (10 in total)

I'm livestreaming as I submit this post; feel free to hop by with questions and comments. It was awesome last time we did this! Here are the links:

YouTube: https://www.youtube.com/watch?v=KFhxfYA98gw Twitch: https://www.twitch.tv/AngeldustLive

Have fun playing! I'll be here after the livestream to answer your replies.

Comment · 6 years ago
I didn't really use many external resources during development, most of the time I'm just "winging it" and acting towards a goal that I have in my mind. Coming up with a naive solution first, then trying to optimize it a bit in my head, then writing the code for it.

Angeldust's physics are relatively straightforward since it's based on a voxel grid. All game world intersections are approximated using axis-aligned bounding boxes (AABBs). I wrote the physics engine myself from scratch to reduce the number of game world data lookups, because that's pretty much the hot path in the code.

In the YouTube video from my earlier comment you can see that initially I started out with just game world boundary clipping and simple plane physics on the checkerboard. As I expanded my game world model, the physics engine grew along. So my advice would be (again) to start simple and grow from there. You'll do fine!

Comment · 6 years ago
Comment · 6 years ago
Go for it! If you already have OpenGL experience—doesn't matter what level—you "only" have to add a bit of basic 3D world math and input handling. I found SDL (http://libsdl.org) to be a very good core framework to build upon regarding input handling.

For the 3D world, start with a checkerboard pattern or so. In fact, this is almost exactly what I did to start Angeldust. I once showed off some early game prototypes on my stream, take a look at this one for example: https://www.youtube.com/watch?v=qMs8YpkSrg0&t=3289

If you keep watching that stream you'll see other in-progress versions so you can see how my product evolved.

Comment · 6 years ago
It's ridiculously hard to come up with an answer to this seemingly simple question. I've tracked my time usage pretty meticulously by version number, but for most features I had to develop the server-side, client-side, website and network simulator code simultaneously. Developing this (or any) game I think isn't a process where you build the server first, then build the simulator and then build the client. It's building v0.0 for all parts, then v0.1 for all parts and onwards where all parts gain features in lockstep.

For Angeldust I've done dozens of updates, each and every single one building upon the existing base. Looking back it's amazing to see that the product evolved in an almost linear fashion from v0.0 all the way to the current version without ever having to drop or redo features. But because the product evolved as a whole I can not really distill a time estimate for only the "client side engine".

I mean: would you consider testing the client side engine part of client side engine development? For testing you need a working server. For which you "need" a working network simulator. It's dependencies all the way down.

And how about translation work for in-engine strings, updating shared libraries and frameworks, issue tracking, writing the asset conversion toolchain (which needs assets, which need integration). It's very hard to come up with any solid number. Maybe if you can severely limit your question's scope I can come up with an educated guess.

Comment · 6 years ago
Comment · 6 years ago
Comment · 6 years ago
Angeldust has practically zero level of detail (LoD) and has no occlusion culling. "Almost zero LoD" means that geometry is always rendered at full resolution, but subtle vertex-shaded effects like the waving of grass are not applied for distant geometry. So you will see grass everywhere, but it won't wave when it's "unnoticeably" far away. Other than that I just push millions of mostly buffered triangles and vertices each frame at high view distance without a hitch. Turns out computers are pretty fast these days.

Note that I'm working on a newer render engine that actually uses more GPU shading capabilities and this engine runs even smoother than the current one, since it balances the workload a lot better between CPU and GPU.

As for data structures: both client- and server-side it's pretty much a simple std::map<coordinate, chunk*>. Its O(log(n)) lookup is adequate and I don't want or need to do complicated things to ensure decent performance. On top of the map I do spatially-aware caching to prevent say 99% of actual map lookups which turns the majority of lookups into O(1) which seems pretty much optimal.

As for keeping data: the server is authoritative in everything. The server keeps the data. You can take any device, install Angeldust and sign in with your credentials and you'll find yourself back in the same world, same friends, same progress, same everything that you had on another device.

Same with game state: the server tells the client everything. The client is basically just a dumb graphical terminal application that renders 3D visuals instead of VT100 text.

Comment · 6 years ago
I think your first question is actually supposed to be: what if a single (not two) entity is modified from multiple chunks?

All external effects that can happen to an entity are written to an atomic integer that tracks healing points, damage points and effects like poison and stunning. Angeldust currently runs on CPUs supporting atomic integers everywhere, so this doesn't have to fall back to mutexes. On platforms/compilers without atomic integers I have a software-fallback that uses mutexes for this, but currently it's not used anywhere.

Most world state is compiled into flat byte arrays each tick to save processing time, since many clients can be in the same area at once. The server bundles these world state byte arrays for chunks near a client together and sends them over the network. The client interpolates from these updates. What you see on screen lags behind subtly to make sure animations are smooth. I think this happens in most online games since you don't really want to extrapolate.

Angeldust's game pace and mechanics are designed so that the interpolation doesn't affect your aiming accuracy or game experience too much.

Comment · 6 years ago
I considered it, then dropped it. The Google Play Store definitely has a mechanism of adding more data/bundles to your application, but (when I investigated this) you'd need to drag in Google-provided libraries and tie your app to the Google Play Store. I dislike lock-in and do my best to be able to independently develop and distribute my product. So expansion files/bundles didn't look interesting.

To compensate, the Itch.io Android APK is actually pretty much identical to the Google Play Store version, but it just includes all 3D assets too.

Comment · 6 years ago
Really getting into the nitty-gritty here. If an entity migrates to an inactive chunk, I keep the entity "on hold" and add a "chunk set mutation" to the active chunk set so that the set is expanded in the next tick. The processing thread for this newly added chunk sees that no data exists yet and synchronizes the state from the backend during the subsequent tick. On this tick the entity gets added to the new chunk write state and disappears quietly from the old chunk in the next tick since it isn't "on hold" or copied anymore.

As for the processing per tick: the entire active chunk set gets semi-randomly processed by threads. You'd be absolutely right that the order of operations isn't always deterministic. An entity not being processed for a tick doesn't happen since the old chunk will still process entities that are "on hold", but only perform a subset of operations. Double-processing does occur and this is sometimes visible while playing with a chat message being duplicated. This happens pretty rarely and I took care to make sure occasional double-processing doesn't interfere with gameplay mechanics.

As for synchronization: yes, each tick all processing threads join together and the server performs minor central processing and scheduling. Then the next tick begins and all threads are started again.

Comment · 6 years ago
Comment · 6 years ago
Pick your poison; I also have a Twitch channel:

https://www.twitch.tv/AngeldustLive

I'm not a social media user and I currently don't keep a public blog. There are many interesting aspects of Angeldust to talk about and I have many war stories from this and previous projects that would make for an interesting read or listen.

Just this evening I talked on my livestream about my rough introduction to SIGPIPE randomly killing my server processes. I can understand that a YouTube or Twitch livestream isn't the most convenient format for hearing these stories, but it's currently my most warm and entertaining way to share them.

Streaming is a highlight in my life, while writing out stories feels like work. Very faintly I'm crystallizing a plan to share knowledge in a written way, but for now I think the livestream is going to be my preferred way for requesting and telling stories.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton