HNHacker News
TopNewBestAskShowJobs

vblanco

1,173 karma · joined December 17, 2020

Game engine programmer, self taught. I love cpp and making fast code.
submissionscomments
vblanco··on Show HN: Claude Code skills that build complete Godot games
There is not much need for this. I already use claude code with godot to build serious projects, and you only need to point the bot at godot + sourcecode folder, and use C#, then it works like a charm.

Nice set of prompts and skills tho, im grabbing them for personal use.

vblanco··on Like digging 'your own grave': The translators grappling with losing work to AI
Commercial translator services lately are the worst they have ever been. You cant validate that they aren't directly sending your excel with the translation lines into a LLM with no tweaking/checking.

For a indie videogame i work on, we tried a couple translation agencies, and they gave terrible output. At the end, we built our own LLM based agentic translation, with lots of customization for our specific project like building a prompt based on where the menu/string is at, shared glossary, and other features. Testing this against the agencies, it was better because we could customize it for the needs of our specific game.

Even then, at the end of the day, we went with freelancers for some of the languages as we couldn't really validate the AI output on those languages.The freelancers took a month to do the translation vs the 2-3 days we ourselves took for the languages we knew and we could monitor the AI output. But they did a nice job, much better than the agencies.

I feel that what AI really completely kills is those translation services. Its not hard at all to build or customize your own AI system, so if the agency is going to charge you considerable money for AI output, just do it yourself and get a better result. Meanwhile those freelancers are still in demand as they can actually check the project and understand it for a nice translation, unlike the mechanical agencies where you send them the excel and they send it to who knows what or an AI without you being able to check.

I will likely be opensourcing this customizable AI translation system for my project soon.

vblanco··on No Graphics API
There is no implementation of it but this is how i see it, at least comparing with how things with fully extensioned vulkan work, which uses a few similar mechanics.

Per-drawcall cost goes to nanosecond scale. Assuming you do drawcalls of course, this makes bindless and indirect rendering a bit easier so you could drop CPU cost to near-0 in a renderer.

It would also highly mitigate shader compiler hitches due to having a split pipeline instead of a monolythic one.

The simplification on barriers could improve performance a significant amount because currently, most engines that deal with Vulkan and DX12 need to keep track of individual texture layouts and transitions, and this completely removes such a thing.

vblanco··on No Graphics API
This is not really directly about resizable BAR. you could do mostly the same api without it. Resizable bar simplifies it a little bit because you skip manual transfer operations, but its not completely required as you can write things to a cpu-writeable buffer and then begin your frame with a transfer command.

Bindless textures never needed any kind of resizable BAR, you have been able to use them since early 2010s on opengl through an extension. Buffer pointers also have never needed it.

vblanco··on No Graphics API
This is a fantastic article that demonstrates how many parts of vulkan and DX12 are no longer needed.

I hope the IHVs have a look at it because current DX12 seems semi abandoned, with it not supporting buffer pointers even when every gpu made on the last 10 (or more!) years can do pointers just fine, and while Vulkan doesnt do a 2.0 release that cleans things, so it carries a lot of baggage, and specially, tons of drivers that dont implement the extensions that really improve things.

If this api existed, you could emulate openGL on top of this faster than current opengl to vulkan layers, and something like SDL3 gpu would get a 3x/4x boost too.

vblanco··on Converting a large mathematical software package written in C++ to C++20 modules
Because you now need to go through virtual calls on functions that dont really need to be virtual, which means the possible cache miss from loading the virtual function from vtable, and then the impossibility of them being inlined. For example they have a ITexture interface with a function like virtual GetSize(). If it wasnt all through virtuals, that size would just be a vec2 in the class and then its a simple load that gets inlined.
vblanco··on Converting a large mathematical software package written in C++ to C++20 modules
The modern cryengine compiles very fast. Their trick is that they have architected everything to go through interfaces that are on very thin headers, and thus their headers end very light and they dont compile the class properties over and over. But its a shame we need to do tricks like this for compile speed as they harm runtime performance.
vblanco··on Rust to C compiler – 95.9% test pass rate, odd platforms
Game consoles generally only offer clang as a possibility for compiler. If you can compile rust to C, then you can finally use rust for videogames that need to run everywhere.
vblanco··on Expressive Vector Engine – SIMD in C++
Yeah thts the fun of it, you create your kernel/function so that the simd level is a template parameter, and then you can use simple branching like:

if(supports<avx512>){ myAlgo<avx512>(); } else{ myAlgo<avx>(); }

Ive also used it for benchmarking to see if my code scales to different simd widths well and its a huge help

vblanco··on Expressive Vector Engine – SIMD in C++
Interesting library, but i see it falls back into what happens to almost all SIMD libraries, which is that they hardcode the vector target completely and you cant mix/match feature levels within a build. The documentation recommends writing your kernels into DLLs and dynamic-loading them which is a huge mess https://jfalcou.github.io/eve/multiarch.html

Meanwhile xsimd (https://github.com/xtensor-stack/xsimd) has the feature level as a template parameter on its vector objects, which lets you branch at runtime between simd levels as you wish. I find its a far better way of doing things if you actually want to ship the simd code to users.

vblanco··on Retrofitting spatial safety to lines of C++
Game developers have been doing this since forever, its one of their main reasons to avoid the STL.

EASTL has this as a feature by default, and unreal engine container library has the boundchecks enabled on most games. The performance cost of those boundchecks in practice is well worth the reduction of bugs even on performance sensitive code.

vblanco··on Tracy: A real time, nanosecond resolution frame profiler
it does, but i dont use it much due to it being too slow and heavy on memory on my ryzen 5950x (32 threads) on windows. a couple seconds of tracing goes into tens of gigabytes of ram.
vblanco··on Tracy: A real time, nanosecond resolution frame profiler
A truly incredible profiler for the great price of free. There is nothing coming at this level of features and performance even on paid software. Tracy could cost thousands of dollars a year and would still be the best profiler.

Tracy requires you to add macros to your codebase to log functions/scopes, so its not an automatic sampling profiler like superluminal, verysleepy, VS profiler, or others. Each of those macros has around 50 nanoseconds of overhead, so you can liberally use them in the millions. On the UI, it has a stats window that will record average, deviation, min/max of those profiler zones, which can be used to profile functions at the level of single nanoseconds.

Its the main thing i use for all my profiling and optimization work. I combine it with superluminal (sampling profiler) to get a high level overview of the program, then i put tracy zones on the important places to get the detailed information.

vblanco··on Trying out C++20's modules with Clang and Make
Yes, but template code is all on headers, so it gets parsed every single time its included on some compile unit. With modules this only happens once so its a huge speed upgrade in pretty much all cases.
vblanco··on Trying out C++20's modules with Clang and Make
They are not slower than headers. Ive been looking into it because modular STL is such a big win. On my little toy project i have .cpp files compiling in 0.05 seconds while doing import std.

Downside is that at the moment you cant mix normal header STL with module STL in the same project (msvc), so its for cleanroom small projects only. I expect the second you can reliably use that almost everyone will switch overnight just from how fast of a speed boost it gives on the STL vs even precompiled headers.

vblanco··on Focus: A simple and fast text editor written in Jai
https://pastebin.com/VPypiitk This is a very small experiment i did to learn the metaprogramming features. its an ECS library using the same model as entt (https://github.com/skypjack/entt). In 200 lines or so it does the equivalent of a few thousand lines of template heavy Cpp while compiling instantly and generating good debug code.

Some walkthrough:

Line 8 declares a SparseSet type as a fairly typical template. its just a struct with arrays of type T inside. Next lines implement getters/setters for this data structure. Note how std::vector style dynamic array is just a part of the lang, with the [..] syntax to declare a dynamically sized array.

Line 46 Base_Registry things get interesting. This is a struct that holds a bunch of SparseSet of different types, and providers getters/setters for them by type. It uses code generation to do this. The initial #insert at the start of the class injects codegen that creates structure members from the type list the struct gets on its declaration. Note also how type-lists are a native structure in the lang, no need for variadics.

Line 99 i decide to do variadic style tail templates anyway for fun. I implement a function that takes a typelist and returns the tail, and the struct is created through recursion as one would do in cpp. Getters and setters for the View struct are also implemented through recursion

Line 143 has the for expansion. This is how you overload the for loop functionality to create custom iterators.

The rest of the code is just some basic test code that runs the thing.

Last line does #import basic to essentially do #import stl type thing. Jai doesnt care about the order of any declarations, so having the includes at the bottom is fairly common.

vblanco··on Focus: A simple and fast text editor written in Jai
Cpp goes nowhere to this level. Jai templates execute normal code (any code) at compile time, so there is no need for sfinae tricks or others, you just write code that directly deals with types.

You can do things like having structs remove or add members by just putting the member behind an if branch. You can also fully inspect any type and iterate members through reflection. There is a macro system that lets you manipulate and insert "code" objects, the iterator system works this way. you create a for loop operator overload where the for loop code is sent to the function as a parameter.

It also lets you convert a string (calculated compile time) into code. Either by adding it into the macro system, or just inserting it somewhere.

Some of the experiments ive done were implementing a full marc-sweep GC by generating reflection code that would implement the GC sweep logic, having a database system where it directly converts structs into table rows and codegens all the code relating to queries, automatic inspection of game objects by having a templated "inspect<T>" type thing where it exposes the object into imgui or debug log output, fully automatic json serialization for everything, and an ECS engine where it directly codegens the optimal gather code and prepares the object model storage from whatever loops you use in the code.

All of those werent real projects, just experiments to play around with it, but they were done in just a few dozens/hundreds lines of code each. While in theory you could do those in Cpp, it would need serious levels of template abominations to write it. In jai you write your compile time templates as normal jai. And it all compiles quickly with optimal codegen (its not bloating your PDB like a million type definitions would do in cpp template metaprogramming).

The big downside of the language is that its still a closed private beta, so tooling leaves much to be desired. There is a syntax color system, but things like correct IDE autocomplete or a native debugger arent there. I use remedybg to debug things and vscode as text editor for it. Its also on relatively early stages even if its been a thing for years, so some of the features are still in flux between updates.

vblanco··on Focus: A simple and fast text editor written in Jai
Jai has a few unique features that are quite interesting. You can think of it as C with extremelly powerful metaprogramming, compile-time codegen and reflection, and strong template systems, plus a few extra niceties like native bump allocator support or things like easily creating custom iterators. There is nothing quite like it.
vblanco··on “Sadly, I Think Godot Is a Scam. I'm Not Sure I Can Do This.”
I once had a possible series of PRs that would increase performance of godot renderer, fixing considerable bottlenecks on scene rendering on CPU. Reduz didn't like the changes and it went into the "will be fixed for 4.0" deflect. To this day most of those performance fixes arent there and 4.0 is slower than the prototype i had. My interaction was very much not positive.

Even then, i believe that godot leadership is doing a great job. Its almost comparable to the amazing process Blender has. This post looks to me like a ridiculous statement. Reduz and other godot leads get constant pestering from hundreds of people daily, Godot even has thousands of issues on the github repo for bug reports.

The godot project and W4 spend their money wisely. I know some freelance developers who got hired for doing some project features. Someone like reduz just does not need to scam anyone, because if he wanted money he could likely work for other companies as a low level Cpp engineer and get more money than what he pays himself with the w4 funding. That w4 funding is being used to make godot into a "real" game engine, with console support which is needed for the engine to be taken seriously by commercial projects and not just small indies or restricted projects. Setting up a physical office and a place to have all those console development kits costs money, and hiring developers experienced in those platforms is not cheap.

In the way i see it, the godot project often develops features in a "marketing" fashion. This clashes quite directly with people using it for serious projects. Unity engine has a very similar issue. We get things like development effort being spent on fancy dynamic global illumination while completely rejecting the classic static light maps (needed for lower end), and even basic features like level-of-detail or occlusion culling which are considered a must-have that every engine has. I think this is what makes the poster cyberreality in the linked forum so angry. Its one of the big faults of the engine, but its not that bad as a development idea. Those fancy big features attract a lot of users, who can then provide feedback and bug reports, PR their fixes to the engine, and of course, funding and hype. The main team makes sure that the architecture of the engine is good, with some fancy big features, and the bugfixing and more niche/professional features are left to community that can PR it. Github is filled with "better" engines from a technical standpoint with a total of 1 user.

vblanco··on The Year of the Vulkan Book
Vkguide deals with the basics, starting from scratch. The book above can be a great read after one completes vkguide, as it shows how to implement some advanced features. I helped review the book and think they should have been more clear that its a book for the people who already know graphics to a high level and want a refresher/info on some new state of the art techniques.
vblanco··on “Clean” code, horrible performance
its custom made mirrored tshirt, he is writing on one of those lightboards and then mirroring.
vblanco··on Godot for AA/AAA game development – What's missing?
I wrote extensively about that as part of my vulkan guide. https://vkguide.dev/docs/gpudriven . The TLDR of it is that you have the cpu upload scene information to the GPU, and then the GPU performs culling and batching by itself in a series of compute shaders. In most games the scene is 99% static, so you can upload the scene at the beggining and never touch it again. this decreases CPU-GPU traffic by orders of magnitude, and if used right, gives you 10x or more performance improvements. Unreal 5 Nanite tech is based on this concept.
vblanco··on Charge – Blender Open Movie
Important detail to comment on this movie. Its rendered using the EEVEE renderer, which is kind of a "game" realtime renderer. Its not using pathtracing on a massive machine to calculate the final image.
vblanco··on Mesh Shading for Vulkan
Nanite in consoles already uses mesh shaders. On PC it emulates them through some trickery but having it using real mesh shaders would be only a small change in code.
vblanco··on Mesh Shading for Vulkan
I believe mesh shaders are the future of the geometry pipeline for graphics, specially given that both of the new consoles have an implementation for them. Freeing the mesh pipeline from the legacy of opengl and similar stuff is going to allow a lot of new techniques and implementations.

Mesh shaders in a way are a new version of what the Playstation 2 did back in the day, where you had a vector processor that would output triangle lists to be rasterized. Its flexible mesh pipelined allowed very interesting techniques, like the multi-layer meshes for fur in shadow of the collosus, or multiple types of smooth LOD interpolation seen in other games. With them, now we can emit geometry from a programming model that is more or less normal compute shaders. Each threadgroup will output a small mesh directly into the rasterizer units of the GPU, so the flexibility is quite great.

Game developers are running into the limits of the current vertex shader model, as you can see with trickery like doing mesh processing in compute shaders and writing the final indices into a big linked list through parallel compaction and similar. With the mesh shaders, all that becomes both more optimal and simpler to write. Techniques like Nanite become a fair bit faster using mesh shaders than emulating them by writing indices into memory, as it avoids that whole memory and syncronization round trip. Completely removing the disliked geometry shaders is also a great feature.

Its great to finally have a crossplatform implementation of Mesh Shaders, but i think the implementation leaves a bit to be desired given it seems to be a direct translated vulkan version of the DX12 implementation. Im not sure how its going to scale to hardware other than the 2 big desktop vendors. The biggest issue with the mesh shaders here is that the cache sizes or recomended amounts vary depending on the GPU. To take the most advantage of mesh shaders and get great speed out of them, there are some fast-path counts for triangles,vertices, and shader memory usages. Those vary by the vendor, so im not sure how are developers going to deal with that correctly other than having multiple versions of the shader by vendor.

vblanco··on Design patterns let you apply existing solutions to your code
I believe thinking of design patterns as something you "use" is one of the biggest mistakes being marketed to new programmers. A lot of them are niche use or only really exist to cover lack of features in languages, such as the Singleton pattern that has no real use in Cpp because you can just put a global pointer instead. It makes people think more about the code than about the problem they are trying to solve to begin with and often ends with a lot more code than is needed to solve the problem for no real good reason. Ive seen a lot of young programmers being mislead considerably by articles like this, including myself.

I see design patterns books and articles as more of a bestiary than a toolkit. Their purpose is not to be a repository of prebuilt solutions (because patterns dont solve anything by themselves). Their main purpose is to give names to a good amount of very common code patterns so you can communicate about it with other programmers.

vblanco··on How we built an auto-scalable Minecraft server for 1000+ players
WoW used to run update only twice a second, which gives a lot of time for logic. The WoW game logic is very simple, as the players cant really affect the world other than the enemies they are fighting at that moment. Also, the players are spread around the world and that limits the N^2 problem of players sending data to other players. Events like Gates of Anquiraj made servers break due to clumping too many players in one location. The game also used to do a lot of logic on the clients, for example collision checks would only run in clients, allowing easy flight-hacks. The server really only broadcasts player positions to other players, and manages the combat logic which is basically turn based.

In private servers using code you can look at (Mangos) they manage to run 4000+ players on a single gaming-spec machine without much trouble. Its more of a design problem compared to something like minecraft where the simulation is much more detailed. In some research projects for wow private servers people have reached 20.000 simulated players in a given machine.

vblanco··on A Macro View of Nanite
Parts of this pipeline have been used since 2015. You can see most of the techniques explained in here https://www.advances.realtimerendering.com/s2015/aaltonenhaa... . What nanite does is to continue the development of this by combining it with Visibility Buffers (decouples rasterization from materials) and adds incredibly fancy LOD system and rasterization for small triangles.
vblanco··on Multithreading for Game Engines
Burst and Job system forces the user to follow good patterns for the multithreading, and makes sure that the user isnt writing to the same thread-unsafe structure from 2 jobs. In that regard its similar to what Rust does. It really is great to have all that checking, as if it passes the checks, it probably will work great. Keeping all the read/write dependencies beetweeen tasks in Cpp is very hard.
vblanco··on Multithreading for Game Engines
Good catch, i was unaware that loading textures off threads in opengl was possible, given that ive never seen it used even on commercial engines. Ill update the article to reflect that.
← PreviousPage 2 of 2