A deranged attempt at a Python 3-like bytecode interpreter in C# with green threading and state serialization.
I am working on a game in my free time, or rather I keep winding up working on the tools for a game in my free time because I such at concentrating. I got caught up when it came to NPC scripting and general game rule scripting. I am using Unity, and I can write C# just fine, but:
Looking at my options:
So somehow this seemed like the smart--I mean "least dumb" idea.
If this was single-threaded and you decided to sleep in your script, you'd hang everything. So what happens instead is that a sleep statement will just block that one script's particular context, take it out of scheduling, and other stuff can run. This includes, well, the main game loop. Very important!
You could try to multithread this but every time that script's context wants to touch anything it doesn't own--including a lot of the interpreter's own runtime stuff--it's going to risk blowing something up that another script is trying to touch at the same time. Each thread also devours about a megabyte just for the right to exist.
This is my own self-deprecation at work. Calling the project "this is a bad use of time but I'm doing it for personal reasons so nyaaaah" is too long, so I have named it after an organ in a snake's butt. What's funny is that other people have also called their own projects "Cloaca!" I can change it but if somebody complains to me that they're the one entitled to name their project after a snake's butt then I'm just sorry for you. I'll rename it to Blue Steel or Magnum.
I started with IEnumerables but that implementation turned feral and had to be put out of its misery behind the tool shed. Cloaca now uses async-await like all the grown-ups expect in this era. I was afraid I'd have to make my own synchronization context, but I'm able to trap all the relevant awaiters using a specific custom awaiter. A scheduler traps these and moves on to the next queued script.
I have considered some other strategies:
I have started embedding it into my personal Unity projects both as scripts I schedule and a scripting console. These are simple little commands right now. However, it has at least proven basic async-await scheduling works within Unity, and that I can interoperate between my interpreter's base types and .NET/Unity types. For basic commands, it's actually working really well. I have a lot of triggers kicking off Cloaca scripts now. It probably leaks memory like crazy.
I do have the basics in Python:
Then add on top of this a scheduler that can gleefully leap between scripts as they get blocked on awaitables.
We can flip this around and I can list things I have not done at all:
There's a document listing current levels of support for things and a todo document that maps TODO items.
Uhh I haven't really pushed on this yet. My intention ultimately is to be able to save a script's context using a serializer, and be able to deserialize and resume it later. This would assume everything in that context can be serialized. However, you know some stuff can't and there would have to be some means of resolving those for it to be robust at all. So I haven't really hammered on it yet.
My game serializer is another ridiculous thing. When I described it to somebody, they said, "Well, that's kind of how Skyrim does it so it's not unheard of." I then realized I had done a bad thing.
Here is a manual but this isn't a widely used project so the documentation has not been battered by multiple people trying it.
A good start is to look at Form1_Load in Form1.cs in the CloacaGuiDemo project. It shows setting up a basic runtime, adding your own embeddable stuff to it, scheduling independent scripts, and interacting with the REPL. A method of sleeping without pausing the thread is included there.
This is still a personal project in its youth so I don't really expect much attention. I will gladly accept pull requests, but you will probably have to explain what trauma caused you to want to contribute in the first place. You can open an issue if you want to ask about general vision and whatnot. If you actually found an issue and filed it, then I will be very amused that you spent the effort to have said so.
This project is available under the Python Software Foundation License.