Notice: If the game stops working after an update, it might be a savegame incompatibility. Remove your savegame folder and try again before posting about it.
Registration has an extra hurdle now: There have been advertisement bots, so I added a security keyword to registration. Deal with it.
  0 users browsing Suggestion Box. | 1 bot  
Main » Suggestion Box » Internalizing the JS engine
Poll
Four files or only two?
Internalize them
 1
Don't
 0
1 user has voted so far
Pages: 1
Posted on 03-18-13, 10:44 am
<i>Prophet of Celestia</i><br>Baka on the streets, senpai in the sheets

Posts: 197/344
Since: 06-08-12

Last post: 1669 days
Last view: 1209 days
At this moment, Noxico requires four files to start up:
• Noxico.exe, the main program
• Noxico.mix, the game data
• Jint.dll, the javascript interpreter
• Antlr3.Runtime.dll, which Jint uses for parsing

Sound support adds a few more:
&bull fmodex(64).dll (or libfmodex(64).so)
&bull Music.mix, technically optional
&bull Sound.mix, also technically optional

Now, I can't do this with FMOD, cos that's a regular library file, but I can and have internalized Jint and Antlr into the source code for a copy of Noxico. The end result is a single Noxico.exe that is the size of the regular one plus the two libraries, in one. Now you only need to account for two files to run:
• Noxico.exe, the main program
• Noxico.mix, the game data

Build times are still reasonable.

I think one of the effects would be less confusion like with Eccles.

This also fixes a potential performance problem in that Antlr uses the 2.0 runtime. Jint and Noxico use .Net 4.0. Internalizing them means that all parts use the same runtime.

The downside: if a new version of Jint is released, you can't just drop in a new copy of Jint.dll. (Antlr3 is outdated -- there's already an Antlr4 but Jint uses 3... for now.)

I don't just program Noxico...
Posted on 03-18-13, 04:37 pm

 

Posts: 81/105
Since: 12-06-12

Last post: 3999 days
Last view: 3981 days
Is there any way that internalizing them could reduce performance at all? Because if not, then I think having them all in one file is definitely the way to go.

Also, in that respect, I think it might be a good time to try running a profiler on Noxico and see if we can't get rid of a few performance bottlenecks. I've noticed that any time there's more than 30 or so scripts running per tick, it causes the game to slow down quite a bit. It's possible (and fairly likely) that some of the code I've been adding has been less efficient than it should be and it'd be nice to see where the program is spending most of its time.

Lead writer on Noxico (and sometimes programmer or designer) <br>
Posted on 03-18-13, 07:18 pm (revision 3)
<i>Prophet of Celestia</i><br>Baka on the streets, senpai in the sheets

Posts: 199/344
Since: 06-08-12

Last post: 1669 days
Last view: 1209 days
Performance is pretty much the same either way, except for the whole "no need to run .Net 2.0" part.

The main reason I can imagine too many scripts bogging down the game is that they all build, set up, and use their own Jint instances, every time RunScript is invoked, as opposed to ApplyMissions which builds one single Jint and uses it for each mission file in order. A similar problem occurs for each script block in scenes, but that's less noticable.

Having a single Jint for all BoardChars could be... problematic, in that aside from changing the identity globals (<code>this</code>, <code>thisEntity</code>) and the optional extra parameter (which can have any name on the JS side), other variables will leak across all BoardChars. On the other hand, nothing went wrong for ApplyMissions so far.

So what we could do to safely increase performance is to give each BoardChar its own Jint instance, preset once on initialization to have the correct <code>this</code> and <code>thisEntity</code> variables, along with all the types and methods, and only set the extra parameter when invoking RunScript. Because RunScript does a lot of stuff.

Edit: and replace all the Console.WriteLine() calls with a debug-only method in Program:
[System.Diagnostics.Conditional("DEBUG")]
static void WriteLine(string format, params object[] arg)
{
        Console.WriteLine(format, arg);
}
That might take a reasonable bite.

Update: BoardChar already have their own Jints, but RunScript still resets them every time. It's trivial to make them reset only the first time RunScript is invoked for a specific BoardChar, though...

I don't just program Noxico...
Posted on 03-19-13, 03:59 pm
<i>Prophet of Celestia</i><br>Baka on the streets, senpai in the sheets

Posts: 200/344
Since: 06-08-12

Last post: 1669 days
Last view: 1209 days
I've added a stopwatch to Game.Update, triggered every time it updates in Walkaround mode. In total I've timed 516 frames, in which the active/visible board is updated, along with its neighbors, and inactive boards are checked and flushed (there are none in this case). This includes copious timeskipping to see if there's any spikes when Jint is used. The impact is neglible compared to HD access.

../updateTime.txt

At frame #36, the neighbors were first accessed and needed loading, causing a spike of 3138177 ticks, or 1.20 seconds. The average time per frame is 46355 ticks, or .0046355 seconds.

Note that the Jint scripts were triggered near the end, but the largest spikes that weren't neighbor-loading occur much earlier.

I don't just program Noxico...
Posted on 03-19-13, 07:04 pm (revision 1)

 

Posts: 83/105
Since: 12-06-12

Last post: 3999 days
Last view: 3981 days
Hmm, interesting. It's good to know that Jint isn't the culprit, but I wonder then if there's anything we can do to either eliminate or redistribute some of those larger spikes? Maybe try initializing certain variables on load rather than first update?

Lead writer on Noxico (and sometimes programmer or designer) <br>
Posted on 03-19-13, 07:10 pm (revision 1)
<i>Prophet of Celestia</i><br>Baka on the streets, senpai in the sheets

Posts: 201/344
Since: 06-08-12

Last post: 1669 days
Last view: 1209 days
Or if we're feeling particularly adventurous, multi-threaded board load requests!

Edit: or the more sensible and easier to implement variant of the above, a loading flag.

Every tick, the active board updates it neighbors. That means about eight other boards are requested from GetBoard(), which loads each of them if they're not already there. These GetBoard() requests are repeated for every tick -- the second time 'round, things are fast because the neighbors are already loaded. But loading all eight of them slows down the game! Instead, have GetBoard() set a flag when loading a board from disk, and only load if that flag is cleared. At the end of the tick, Game.Update() clears the flag again.

Now, only one neighbor is loaded for every tick, processing input between them instead of loading eight boards between inputs. In theory.

I don't just program Noxico...
Pages: 1
Main » Suggestion Box » Internalizing the JS engine