A custom editor for live coding games uses a multi-process architecture where the editor, game modules, and inspector modules each run in separate processes while sharing a common memory-mapped state, enabling real-time state manipulation, debugging, and iteration without restarting the application.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Live coding games in a custom editor // Andrey Varlamov (Handmade Network Expo 2026)
Added:A few years ago, I watched Handmade Hero for the first time and I've been enamored with that style of development ever since. To me, the most interesting thing about it is how direct it is and how many things it demystifies for you.
Uh for example, being able to write game code with nothing in your way, uh no engine, no framework imposing its design on you, no upfront architecture that you have to follow and kind of subscribe to.
And another thing that's really interesting to me and that'll be the theme of my demo for today uh is how it deals with game state and the fact that it's all laid out flat in a block of memory and it's easy to reason about, you can dump it to disk, reload it, revert to it and stuff like that.
So, this got me thinking, wouldn't it be nice to have a development environment that is tailored to that style and not just that, but one that takes full advantage of these principles and uh opens up new affinities and interconnections in different parts of the development process.
And just to give you some examples of my line of thought, let's take Emacs. It is known to not just be a text editor, but a whole engine for running Elisp.
Uh and Elisp is not just a language for extending Emacs, but it is its whole user interface.
Um another example is TempleOS.
Uh HolyC in this context is not just behind-the-scenes language that uh the user is never meant to see, but it's again, its primary user interface. And what's interesting about HolyC is that it's uh compiled. So, anything you run, including what you type into the uh shell as a command, gets compiled just in time, uh loaded and executed without any virtualization.
So, my idea is to combine these two inspirations and uh come up with a text editor that uses a natively compiled language as its primary interface.
Or at least that was kind of the original idea, but from there it's kind of a direction which I'm exploring, so uh there is kind of different ways in which I'm approaching that.
Uh so, I've been toying with these ideas and making a few prototypes. Uh last year I made a version that uh what it did is basically ran user modules, and this is just a screenshot just to kind of give this idea that um you have the editor and then user module uh runs as part of it in the same process. So, it's not just an editor, but also a platform layer for uh running user modules. And you could have multiple ones and stuff like that.
And another thing about it was that uh you could have a kind of script that is still just C code in this case and uh it gets dynamically loaded and that function gets run and applied to uh the state of the editor and whatever uh user module there is. And what's interesting about this version is that the editor itself was just a module that is run by uh the same platform layer. So, you could apply the same logic to it and you could apply scripts to its own state.
But, there was a major issue with this design and that's the fact that it was all part of the same process, so a bad code uh of or sorry, a bad line of user code could crash everything including the editor.
Uh so, that's kind of what stopped me in this version, but this time around I've been making a proof of concept where everything is uh actually kept in its own process. All of the user modules are their own processes and the editor is its own process as well.
Uh so, let me just jump into demonstrating it. That's what I'm going to focus on today.
Uh so, this is the editor, kind of the visual part, and the text editing is not really the focus for today. It's pretty bare-bones, but what I want to show is how I'm dealing with um kind of with with shared state. So, what I have here is uh two modules, one of which is kind of a game and another one is an inspector for the game. The game itself, if I start it, uh it's just this kind of example. I just have a bunch of entities on the screen here and um one of them is the player you can move around and pick up items. You can pick them up and you can drop them.
But, another module is the inspector. And the inspector has in real time, it's accessing the same state as the game and uh you can see everything being updated in here.
And um for example, in this game itself, you can press G to drop an item, but the same function gets is kind of attached to this GUI element of this button, so uh you can drop it here.
Uh and then to get a little bit deeper into how this works, I'm going to demonstrate this uh scratch running functionality. And I just call it that kind of from the Emacs scratch buffer, but I'm not sure if it's the best name for it, but for now it uh stuck.
So, I'm going to make a new scratch buffer, which is just this template for a function where I can write some code and then it immediately gets executed on the game.
So, for this demonstration, I'm going to start with uh these little lines. So, basically, the first two lines, what they're doing is um is kind of this concept of a state arena where the idea is that the state of the game is kind of singular and you can always refer to it uh uh without having to specify the arena.
So, and I kind of bake it into the type of the state PTR. And so, what you do every frame, or in this case, every time this function is run, is you give whatever uh memory block that that this one should use. And then I'm attaching this memory block to the state arena. And uh all it's doing is kind of setting the base address uh according or in relation to which these relative pointers are uh you know, that they're offset off that base. So, every pointer inside the state is uh actually uh relative to that offset.
Uh and so, in this example, what I'm going to show is just simply changing the ground tile. So, I'm going to run it and apply it to this module. So, right away, we see how it just swaps the little data that lives in that state of kind of the tile coordinate of that sprite in the atlas.
Another example uh here, we're going to take uh our state, go into the entity store, and get the actual entity of the player, and then swap its uh sprite.
Oops.
So, here you can see the player's uh sprite change. And because again, these uh states of these two uh modules are linked, we see that in real time.
Another example of uh functionality is uh you can call all of these kind of shared uh game library functions.
For the lack of a better term.
So, for example, here I'm going to run this and uh this function runs here where I'm actually dropping the first item that the player is carrying.
So, here for example, you can uh as you are tweaking your game, you can make changes to its state uh live in this kind of uh script-like fashion.
Another example is uh spawning a new entity. So, you can see now under the player there's this amulet entity.
Uh and it's kind of a completely new one that is specified in the script.
Uh and another thing is that because it's uh actually memory-mapped to file, if I close everything and then I uh let's say open the inspector first, all of this is still there and I can actually run this without even game being uh running and then go back to the game and see uh this difference here.
And uh because we have the editor as kind of the central point of all of this uh interconnecting, we can actually use it for like resetting that uh memory state and now the game is in its original state. And so, the idea here is that the editor can kind of help you deal with these memory blocks outside of your programs. And uh you can see how there's a line here where the editor is basically like the platform, but this time the platform is actually across uh different processes.
And you don't even care about that uh anymore.
I mean, you don't even care about uh kind of the process itself, that boundary.
So, now I'm going to show the code that goes into these two modules just to show that there's nothing that crazy going on here.
Uh so, basically here there is these uh hook functions that are getting called by the platform layer, which the editor is telling uh you know, it's creating a new process, starting the platform layer, and telling it to run this uh as a dynamic library.
And what we have in here is in the update, we again do this kind of attaching thing.
And if we see that it's a fresh block of memory, we will initialize everything in here. So, we create the player, we add our items, and stuff like that.
And uh then we're doing the usual frame stuff. We're changing or checking our inputs.
Uh here you can see this is where an item gets picked up, item gets dropped, stuff like that. And I'm using raylib to draw this just for simplicity.
Uh and then the inspector itself actually looks pretty similar.
Uh it's just another module accessing the same state. And uh most of this code here is just the GUI logic, but as far as the actual game logic goes, it's accessing these functions again. And so, let me show you kind of the state itself.
It's a pretty simple. Most of it is just this entity store where um you know, with a bunch of helper functions to kind of get our entities and stuff like that. Um And here you can see this is that state PTR. So, everything that lives in this state struct should use the state PTR if it's kind of a dynamic memory access.
Um But what you can see here is that I'm actually using a vector for the return of this function, and I feel like uh I found that like usually if I obsess too much with making everything perfect right away, I just get stuck in the actual work. So, sometimes you just want to be lazy and you don't care about uh like let's say here I'm just returning this uh function in a convenient way. So, I don't have to worry about like how do I organize this data just for this function and stuff like this. I can just throw a vector in here. So, that's just to demonstrate that this doesn't limit necessarily what you use and you can kind of incrementally opt in to any of these features.
Um but of course the limitation being that if you use this in the main state, then you won't be able to deal with this across the process boundary.
And uh in the RPG.cpp itself, uh I'm just implementing all these functions, nothing too crazy.
But, what's interesting here is I have the static variable of the tile set and this is something that doesn't actually make sense across different processes because it's usually an OpenGL handle or something like that. So, I actually want to deal with this on the per process basis and that's what this init function is for. That's for loading everything that uh the runtime of the process uh needs. So, for example, both in the both in both inspector module and the game module, I call this load tile set function which kind of sets it here and then you can refer to your tile by its coordinate.
And uh obviously you can extend this more into some kind of asset management system that, you know, streams this and does this on the fly and uh stuff like that.
So, uh Yeah, so I mentioned everything I wanted to go over in the demo itself, but I wanted to also touch upon a few topics just to kind of talk about them. So, one thing is I think the elephant in the room is synchronization. And the thing about that is interestingly enough, this is actually not in any way synchronized. And in this simple case, it still runs better than I expected.
But I actually have the solution or at least an idea for it of how I'm going to resolve it later.
And that's actually going back to how it was in the single process version. So, I'm going to run every update of each module in series, not in parallel. So, only one module gets to update the state at a time. This way, the user doesn't have to worry about synchronization right away. They can do it in the simple way.
And only then if you know, it gets more complicated for them, they can actually start synchronize again in a in a smarter way.
And uh another thing is for kind of the direction of the editor itself, my idea is again to make it a module that runs on the platform layer. And so, and to move all of its state into a kind of similar structure.
And what this will allow to do is again applying the scratch buffer idea to the editor itself and to its state. So, you can write a script, not even kind of as an extension that you install, but literally you just paste some code that will just apply some changes to the editor. And I think it opens up a few interesting opportunities in terms of using it as a kind of maybe build tool, scripting tool. And all of this is right in your editor.
Um Also, it's interesting to make this work with meta programming, although that's kind of for way later, but I'm imagining a kind of functionality of being able to just hover on a variable and seeing a user-defined widget that will show like a graph of how the variable is changing frame over frame.
Uh and it leads me to this interesting idea that is pretty abstract, but I just wanted to mention it. But it's kind of uh modular development. So, if you're working on a kind of subsystem in your game, what if you had a different representation just to deal with that subsystem? So, for example, uh if you have some kind of RPG with combat and it's using dice mechanics to actually calculate damages and stuff like that, what do you what if you had a separate game, {quote} {unquote}, a separate application that will represent fighting in a kind of uh like the way that is logical to the fighting, right? So, like uh event by event and not in this uh structure as it has to be for the actual player of the game.
So, that's kind of some thoughts of where I want to take it, but um I think it's interesting because uh what you can do, and my idea here is to not even provide the user with any uh direct tools, but a kind of infrastructure where they can make these tools themselves. So, they could use any library or maybe later on I start providing certain facilities and infrastructure, uh and all of this because it can operate in this way and it has that center of the editor. Uh There there is actually like a place where to put it that is singular.
So, uh that concludes my presentation.
So, I'm open to any questions.
>> [applause] [applause] >> Test, test. Um all right, raise your hand if you have any questions.
I I noticed that when Well, you said when people write scripts for the editor, they're written in C and they run in their own process.
And you did that because if the script crashes, it'll bring down the whole editor unless you put it in a different process cuz that's like the only thing that OS gives you to really address that. Uh have you ever considered compiling the scripts to like bytecode and running them in a virtual machine?
Or like are there any downsides to giving each one its own process?
>> Uh well, regarding the virtual machine, I mean it's another kind of point of failure, another thing to develop, another complexity. So, as much as possible, I want to avoid that. And since the computer is already kind of a machine that runs code, why would you want this level of indirection, right?
But I mean you could have it, but again, you would have to develop it, right?
>> Next question.
Um I'm curious if you have plans for when like you want to ship the game and you don't need all of the other processes there. Is there any uh tooling or infrastructure around you know, now I don't want to be writing out to an external file. I just want to keep everything in memory cuz there won't be multiple processes.
>> Yeah, you would just have to replace the platform layer and just provide uh memory in a different way that is not mapped to file, that is not shared. And uh you can actually do that at any point in development process because the actual code is all isolated from the platform in its own DLL.
>> Another question.
>> All right, I think that concludes that.
Let everybody give Andre a big round of applause.
>> Thank you all.
>> [applause]
Related Videos

TOP 15 Data compression Interview Questions and Answers 2019 Part-2 | Data compression | Wisdom jobs
wisdomjobs
281 views•2019-06-28

CTS 158: 802.11w Management Frame Protection
ClearToSend
4K views•2019-02-04

NDSS 2019 Send Hardest Problems My Way: Probabilistic Path Prioritization for Hybrid Fuzzing
NDSSSymposium
496 views•2019-04-02

How realistic is Cities: Skylines?
CityBeautiful
159K views•2019-02-14

GUIs & TUIs: Choosing a User Interface for Your Python Project | Real Python Podcast
realpython
2K views•2025-04-04

The OSI Model - Explained by Example
hnasr
225K views•2019-05-12

Cloud Computing - Introduction
elithecomputerguy
98K views•2019-10-07

From Traveler's Dilemma to Dynamic Routing | Demystifying Networking
IITBombayJuly
5K views•2019-08-04
Trending

WOW! Judge TURNS THE TABLES on Trump in His OWN $10B LAWSUIT!!!
MeidasTouch
197K views•2026-07-23

Playstation NO DISC/NO BUY Fight Is Over...
DavidJaffeGames
4K views•2026-07-23

Steam and Xbox Just Dropped The Hammer On PlayStation
OhNoItsAlexx
9K views•2026-07-23

Americans Confused in Australia for 17 Minutes Straight
IWrocker
17K views•2026-07-23