unevenprankster 2025/09/04 12:34 |
I'm beginning to integrate FixScript into my game engine as a replacement for Lua but upon coming across the fixscript_reload function I've been curious as to how it's used in practice. I want to support being able to edit the game scripting as it runs to add or change things, as well as refuse reloading if an error is found so the user can address it and then proceed as normal.
One of my big inspirations has been this video (https://www.youtube.com/watch?v=72y2EC5fkcE) from Tomorrow Corporation about their game engine that can do seamless reloading as well as time-travel debugging and snapshots. I haven't managed to wrap my head around those last 2 features but I hope to at least build a simple debugger in the future for watching variables and breakpoints. As for my current thoughts about the language, the way FixScript handles loading is a little more complicated thanks to requiring passing a callback but overall much more flexible, I've also noticed this in the design of the C API which ultimately makes it way simpler to create and register new functions compared to in Lua. Every time I read more of the implementation and the docs I'm just stunned by how flexible and yet straightforward it all is, all while being so tiny. I hope to later take advantage of the loading callback when I'm implementing a filesystem abstraction (think PhysFS) so that it can seamlessly load from the main filesystem or a game package, the latter specially great for supporting modding. |
jezek2 2025/09/05 03:23 |
That video is pretty cool. Maybe even too fancy :D
I think the time-travel can be implemented as some form of snapshots of the state at regular intervals and then ability to just run up to given point from that. Similar how video codecs work. That way you can implement the breakpoints etc. by simply stopping execution on the condition. This can be achieved by inserting of throwing of an exception (typically some form of special value is used such as a function reference or perhaps a native handle). Another alternative is to directly adjust the bytecode interpreter implementation and insert debugging stuff here. It should be pretty straightforward to adjust (as long as you don't require JIT, but for scripting purposes it's not that important I think). You can see the hot-reloading and a simple "IDE" in action in CellSplit, an opensource clone of Agar.io that I've created: https://www.cellsplit.org/bots The editor inserts a bit of delay when reloading the code so the user is not getting errors during active editing, but nothing prevents to reload it at every keystroke like in the video. And yeah, all the aspects of the language design and implementation managed to fit together, it surprised me as well. The simplicity is quite contagious to everything else which I really like. Why overcomplicate stuff when it doesn't need to be. |