▲ William Eklund
William Eklund

I'm William Eklund, a systems and game developer in Sweden working in C# and .NET: backend, cloud, networking, performance and game engines.

My largest project is Krut, a 3D game engine I build solo. Two games run on it so far, one of them an online racing game with a dedicated server and a backend. Below is what the engine does today, the games and backend built on it, and where it's going next.

C# / .NET 10 · ASP.NET Core · PostgreSQL · Docker · Direct3D 12 or Vulkan · Native AOT · ~82k LOC

What the work shows

skills, with where to find them below

The engine

Krut.Engine · closed source

A sunlit stone courtyard rendered in Krut: a pergola casting striped shadows on cobblestones, three metal spheres on plinths, glowing light strips and a cloudy sky
A courtyard showcase rendered in Krut with PBR materials, parallax occlusion mapping, reflection probes, SSAO, screen-space reflections and a prototype HDRI sky.

Every system (rendering, physics, audio, networking, navigation and asset loading) is a separate part that only knows about the others when it has to. A game includes the engine as a git submodule, inherits from a shared Core loop and overrides the parts it wants to change. Builds are Native AOT, so players don't need .NET installed, and every subsystem has xUnit tests that must pass before anything ships.

Most of Krut is written by hand, by me. I use libraries for a few low-level pieces, listed further down, but the systems built on top of them are my own code.

The target is a modern, optimized game engine built on the old-school BSP workflow (like Quake, GoldSrc and the Source engine), with modern features like PBR, real-time lighting and a Forward+ renderer.

Libraries: SDL, Jitter2 (physics engine), Recast & Detour (navmesh generation and pathfinding), LiteNetLib (networking), FMOD Core (sound playback and mixing), NVorbis (Ogg decoding), AssimpNetter (model import), ImGui.NET (debug UI), xUnit (tests).

Krut.Netcode

open source library · GitHub · MIT

An authoritative-server netcode library for .NET built on LiteNetLib, extracted from Krut.Racing. It handles the low-level synchronization and prediction primitives needed to keep multiplayer games responsive and fair over noisy, high-latency internet connections.

The library is decoupled from any specific engine or physics model: games define their own messages, snapshots and simulation step, while Krut.Netcode manages the wire protocol, clock synchronization, client prediction rollbacks, entity interpolation and simulated network degradation.

Games on Krut

Commute

single-player FPS · Krut.Engine 1.8 tech demo · play the demo on itch.io

Fighting through the subway station level.

Commute is a 10-minute vertical slice and tech demo for Krut.Engine 1.8, testing the engine in a real game, and it borrows a lot from Source engine games. The demo is one level, Subway Station: from the ticket hall down to the platform, through the tunnels and out into the depot. It's built in TrenchBroom with a custom texture set and lit by Krut's own GI lightmapper. Along the way there are button puzzles, live wires and explosive barrels.

There are three kinds of enemies: melee, ranged, and bombers that beep faster as they get closer. They path on the navmesh, stay away from live electricity, and don't all rush you when they can't see you. They only throw a grenade when they have a clear line.

Krut.Racing (working title)

online multiplayer racing · in development

Gameplay from the current build.

A spec racer: every car performs exactly the same. You can change how your car looks and sounds, but not how it drives. The server enforces this, because clients never touch vehicle parameters.

The car physics is my own vehicle sim, written for this game: a kinematic simcade model with a friction ellipse, weight transfer, anti-roll, suspension, downforce, drafting and FWD, RWD or AWD drivetrains. It runs on a fixed step, so the same code runs headless on a dedicated server per race, and clients only send their inputs. The netcode is built to keep racing smooth at pings of 150-200 ms (see Krut.Netcode).

Krut.Racing backend

accounts, results, economy and server orchestration · built, being connected

The game server is authoritative for the race, and the backend is authoritative for everything that outlives it. Clients never report their own results: when a race ends, the dedicated server builds the result from its own state, signs it with HMAC-SHA256 and hands it to the backend, which verifies the signature before anything is stored or paid out.

What's next

after 2.0.0 · in progress

Krut 2.0.0 was released on 2026-10-26 with a new GPU layer and Forward+ rendering.

Contact

You can reach me by email at williameklund2@gmail.com, or find me on LinkedIn and GitHub.