Mara's Avatar

Mara

@maraneshi

Sometimes works on game engines. She/Her. More tired than you could ever imagine. πŸ³οΈβ€βš§οΈπŸ³οΈβ€πŸŒˆ @Maraneshi@mastodon.gamedev.place https://x.com/Maraneshi

143
Followers
382
Following
54
Posts
19.10.2024
Joined
Posts Following

Latest posts by Mara @maraneshi

It's not a good game, but nobody can say they didn't at least try to make something cool. A memorable game one way or another. I'm still massively impressed by their cutscene and camera direction, it's so dynamic and high effort even if over the top and goofy sometimes.

09.02.2026 04:07 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Screenshot of the graphics debugging tool RenderDoc showing the scene from the video above. You can see a large particle quad with two textures being applied to it, one is the shadow from the fan above, the other is a generic ball of smoke.

Screenshot of the graphics debugging tool RenderDoc showing the scene from the video above. You can see a large particle quad with two textures being applied to it, one is the shadow from the fan above, the other is a generic ball of smoke.

More particles mimicking volumetric lighting through a ceiling window. One may notice the shape of the "shadow" on the particles doesn't particularly fit the scene here, it's a shared texture with the scene from the next screenshot, presumably to save memory.

More particles mimicking volumetric lighting through a ceiling window. One may notice the shape of the "shadow" on the particles doesn't particularly fit the scene here, it's a shared texture with the scene from the next screenshot, presumably to save memory.

More fake volumetric lighting through a window on the side of a structure.

More fake volumetric lighting through a window on the side of a structure.

Search lights illuminating the "air" in front of them by emitting particles that are then shadowed by a projected texture to form a perfect cone shape matching the spot light. The overlapping particles plus the light's flare sprite create a nice bloom effect.

Search lights illuminating the "air" in front of them by emitting particles that are then shadowed by a projected texture to form a perfect cone shape matching the spot light. The overlapping particles plus the light's flare sprite create a nice bloom effect.

Here's a RenderDoc shot with the projected shadow/light and a generic smoke particle, plus some more examples. The last one smoothly "trims" the particles into a perfect cone shape matching the spot light cone. Also works surprisingly well as a bloom effect, there's no post processing here.

06.02.2026 06:11 πŸ‘ 24 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Video thumbnail

A while ago I was surprised to find some obscure game from 2003 (Chaser) to have *really* great fake volumetric lighting by using static textures projected onto particles. Projectors weren't entirely new, but I don't remember *any* sort of lighting on particles being common back then.

06.02.2026 06:11 πŸ‘ 54 πŸ” 1 πŸ’¬ 2 πŸ“Œ 1

Also to the original point: LLMs would help exactly nothing with any of this. A lot of it is not documented and it would be impossible for a machine to infer this much context and connections just from code. Even if I wasn't already against using it, it would be practically useless for this codebase

28.11.2025 21:34 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Also we have a spy class that can disguise itself as any other character in the game by effectively changing its soldier preset but then undoing some of the changes, which is a super awesome mechanic but you can imagine how this is yet another nightmare stacked on top.
TLDR: Games were a mistake.

28.11.2025 21:11 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

So then people go and add hacks to individual scripts on the soldier itself to re-check on creation which zones they are currently inside, which then crashes because it's calling back into other scripts which weren't created yet so it needs a timer, etc...

28.11.2025 21:11 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Different soldiers can also have different gameplay scripts attached, some of them quite complex, so scripts need to be recreated from scratch on change. Unfortunately that means if you're in a zone that attaches a script to you when you enter, that script is detached when you change characters.

28.11.2025 21:11 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Any time you add functionality to the soldier class you need to make sure it's initialized correctly both on the initial creation of the object and on respawn/character change. We once had a bug where if you died or changed characters you could no longer damage yourself with your own explosions.

28.11.2025 21:11 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

However you can also buy different types of soldier presets during gameplay, so it does need to reinitialize quite a lot more stuff. This also means in many places you cannot distinguish in code whether a player respawned after a death or bought a new character class.

28.11.2025 21:11 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

This reminds me of fun things in W3D: The "soldier" objects owned by players are never destroyed until disconnect, which for example means that you can't respawn until the death animation has fully played out since respawning is teleporting your existing soldier that is currently in "death" state.

28.11.2025 21:11 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Yeah I'm not sure, but maybe it can't automatically find i in A because it could also be dependent on T or something. The fun part is where if you also have a global variable named i and you don't qualify A::i then it will increment that global instead, except if you are in MSVC permissive mode.

25.11.2025 17:47 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Preview
Two-phase name lookup support comes to MSVC - C++ Team Blog η‚ΉθΏ™ι‡Œηœ‹δΈ­ζ–‡η‰ˆ This post written by Tanveer Gani, Stephan T. Lavavej, Andrew Marino, Gabriel Dos Reis, and Andrew Pardoe β€œTwo-phase name lookup” is an informal term that refers to a set of rules governing th...

There's a long explanation of this behavior and what kind of issues you can encounter with it here: devblogs.microsoft.com/cppblog/two-...

25.11.2025 17:24 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

MSVC still defaults to permissive/non-standard mode, where templates are only checked/compiled when instantiated. If you add /permissive- to the command line it will also complain, because then templates are syntax checked at the point of definition, which is the indended standard behavior.

25.11.2025 17:22 πŸ‘ 1 πŸ” 1 πŸ’¬ 1 πŸ“Œ 0

Killing or knocking out or avoiding enemies was a true choice in DX, but in DXHR everything *must* be wholly systemized and every action within that system *must* have an immediate reward, making you think about that instead of the action itself. Same with pretty much every other mechanic.

09.11.2025 23:18 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

You *can* make good games that way and I certainly enjoy systems-oriented games, but I miss a more world/goal oriented design in some ways. IIRC the original Deus Ex mostly gave you rewards for meeting goals, not the individual actions that lead to them, so you actually felt free in your choices.

09.11.2025 23:18 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

I'm not a designer but I've been thinking this a lot lately, where especially newer games are entirely action/system oriented in their rewards and the overall design and how it turns everything into an instant-gratification numbers game and reduces the world to pretty set-dressing over those systems

09.11.2025 23:18 πŸ‘ 2 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Screenshot from Deus Ex Remastered, showing pitch black walls right next to overly bright lighting.

Screenshot from Deus Ex Remastered, showing pitch black walls right next to overly bright lighting.

What is lighting? Also the original lipsync was bugged so we slapped slow interpolation on it and made it look like a bad cartoon animated for another language instead.

25.09.2025 00:03 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Unity documents that it does apply the factors even for min/max, but it can't actually do that since no graphics API supports that (I checked OpenGL, Vulkan and D3D). What's likely happening is that not specifying blend factors in Unity means blending is *disabled entirely*.

21.08.2025 22:10 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Since not all possible byte values even *make sense* for UTF-8 (unlike UTF-16), as in they are not even code units at all, there's no way to make a "messed up" encoding like WTF-16/8 out of this and you either have to actually support arbitrary byte sequences or assume UTF-8 and hope for the best.

29.07.2025 17:07 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

they can still fit the general idea because all code units [0x0000, 0xFFFF] *can* be used in a legal encoding.

On Linux, the situation is hopeless because technically file names have no encoding whatsoever (may depend on file system), only the byte values for ASCII nul and slash are illegal.

29.07.2025 17:07 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Windows filenames are mostly arbitrary bytes and thus WTF-16 can have those "surrogates" as individual values instead of pairs. This can then still be encoded in an extended form of UTF-8. So even though we have arbitrary bytes and some of them are not legal code *points*,

29.07.2025 17:07 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Summary as far as I understand:
In UTF-16, all 16-bit values from 0x0000 to 0xFFFF are used and legal, but [0xD800, 0xDC00) and [0xDC00, 0xE000) are supposed to come as pairs to encode larger code points using the lower bits in each value (two 16-bit "code units" to make one "code point").

29.07.2025 17:07 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
The WTF-8 encoding

Yes. Basically, OSes like treating file names as just bags of bytes, so you can create filenames that are not valid UTF sequences. This has been dubbed the Wobbly Transformation Format (WTF). It's usually used with regard to Windows, but I believe Linux has the same issue
simonsapin.github.io/wtf-8/

29.07.2025 16:23 πŸ‘ 1 πŸ” 2 πŸ’¬ 1 πŸ“Œ 0

Make sure to also learn about WTF-16!

29.07.2025 16:09 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Ugh, scratch that, I was blind. Both compilers insert the prefetch loop at the end, which makes a lot of sense because the "else" case is universal and only refers to the second "if", so it will always execute even if the first if condition is true when you don't chain them with "else if" correctly.

29.07.2025 14:00 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Both. Unfortunately it seems the problem is quite a lot more mysterious because I'm getting the exact same codegen for the measured section on MSVC, but the perf difference is consistently measurable. On Clang there is at least a slight difference in how the loop is unrolled (MSVC doesn't unroll).

29.07.2025 13:53 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Also, I propose the "pipeline" mode optimization should be called "loop unrolling but I went too far".

29.07.2025 12:46 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

My initial instinct was that the pointers should be pre-sorted, but of course that only helps if there is some actual data locality, so I had to reduce the test set to <32kB to get any actual benefits. The sorting would have to take place whenever the pointers get modified, not when you query them.

29.07.2025 12:45 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

In another case of "benchmarks are hard", the "original" becomes a bit faster (~15% for me) if you change "if (Mode == kPipeline)" to "else if". Since Mode is a template parameter anyways, upgrading to "if constexpr" should absolutely ensure no weird side effects on code gen from the branch.

29.07.2025 12:41 πŸ‘ 2 πŸ” 0 πŸ’¬ 2 πŸ“Œ 0

There may be some edge cases where you can do horrible things in 11 (e.g. OOB access on a local array, unaligned access, wrong resource type) and of course you never know what the driver does under the hood (it could try to optimize your resource bindings to something not possible in the API).

26.02.2025 16:58 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0