Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Script interpreter time-jumping.

Name: Anonymous 2011-11-25 16:25

I'm writing a "game"-engine for visual novels in python and have the following problem:

My engine includes a script-interpreter for a language without 'if' and 'for' statements. I save the interpreter-state for each line in a cache, so I can jump to a line without executing the whole file up to that point. When the sourcecode changes, the engine sets the cached interpreter-states for the involved lines to None. The engine rebuilds outdated states by going downwards from each None and filling newly calculated states into the cache until the calculated state matches the one that is already in the cache (before overwriting it), because it's safe to assume that all further states are not affected by the change. Example:
1 {}                       a=0
2 {"a": 0}                 b=3
3 {"a": 0, "b": 3}         #comment
4 {"a": 0, "b": 3}         a=1
5 {"a": 1, "b": 3}         c=7
6 {"a": 1, "b": 3, "c": 7} #comment
If line 1 is changed to "a=1" the engine rebuilds lines 1-5. Because at line 5 the calculated state and the cached one are the same. Now there is a problem with that approach. When I have a 5000 line file and I change a variable at the top, the changes propagates through the whole file and the engine starts lagging. A solution I'm considering is using something like {"a": [0]} instead of {"a": 0} and using references to the same 1-element-list from all states wherein the variable in question isn't changed. In the example that "a=0" is changed to "a=1" this would lead to all 0s from 1-4 to be 1s afterwards when actually only one number was changed. The rebuild stops at 2 already because the calculated and cached state match. This is definetly a speed-up, but only works with assignments. If line 3 had something like a=a+10 the rebuild-cursor would never reach the line 3 because the references across states break the assumption mentioned earlier. At least when not used correctly. I can't even make special treatment for this kind of instructions because commands can be user-defined too. A different approach would be to store the data like cache[var][linenr] instead of cache[linenr][var]. I haven't thought about that much yet. Also, I can only support simple types yet, like ints. I need to find a way to have (recursively) versioned python-objects.

It's quite difficult to put all this into words. There is still more, but I don't even know if /prog/ is able to help me so I won't bother to type it down (yet)

Name: Anonymous 2011-11-27 10:34

>>29
First of all, thank you for this serious answer.

About point 1: The scripts-segments *are* linear, but they can be arranged by a higher-level code (in python). (States are not transferred across scenes)

About point 2: The expected user-group has no idea of proper programming and is likely to actually try something similar. I used a profiler and it turned out that the determination of ident-level used 0.5secs per 10000 lines. That's because I haven't separated parsing and execution yet. And I'll store the result of parsing as a lambda. (for performance)

I don't completely understand what you mean by 3. What I precompute are the states at each point in time. They aren't alternatives.

Ad 4. I'm only using 'diff' when reloading the file from disk (and in that case performance doesn't matter). Normally I get insert and delete events from gtk with line-numbers.

I think that the lisp-code you posted is what i'm doing already. Yours is just easier to read and understand. (I need to learn Lisp already)

And the language has to be a custom one, because it's much easier to type:
Karin happy: "Oh, how are you?"
than:
karin.face = "happy"
karin.say("\"Oh, how are you?\"")

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List