Removing Methods from Preinit

Okay, so it’s not a big deal now but it’s gonna be a big deal later.

I enjoy byte packing and speed optimization. It’s fun and satisfying, so that’s the actual goal here; practicality value is kinda arbitrary here.

I have a separate program written in JavaScript for Node.js (I know, hold on) because it can crunch numbers a lot faster than TADS can, so I have this separate program generating a large set of values as TADS 3 Vector declaration code, which I drop into the game code as a method that runs during execute() on a PreinitObject.

However…while this is 32kB of cache memory, would this also be saved to the game file in the form of instructions, because the method that caches the Vector is being saved as characters to the game file as well?

So I tried using setMethod(prop, method) to assign an empty method to what creates the cache. Then I run t3RunGC(). The idea is the old method with all the values saved as assignment instructions should get tossed to garbage collection before the preinit cache is done being written.

I compared the sizes of the files (outside of debug mode), and the difference is only a few bytes, which are probably the addition of the the setMethod instruction, and the garbage collection call.

So…is there a way to keep methods from making it into the game file, after preinit is done? Right now this would only save me at least 32kB, but I have other data that I plan to also build in an external program, which will probably be a lot larger in size.

In a world where AAA games are GB in size, this is all meaningless, but it matters to my personal design goals, and also: it’s still fun.

Should I try to compile a version that lacks this cache entirely (method with declaration and all), and see what the size difference is? If it’s only 32-40kB of a difference, then maybe these methods are not becoming game instructions in the final file? If it’s a difference of 72kB or more, then that’s probably both the cache and the declaration method instructions.

While I know how a lot works, this is specifically an area of uncertainty.

EDIT: Wait a moment, is it possible to pack any kind of file into the final game file, similar to multimedia resources? I’d include the cache as a file and skip the declaration method, but only if it’s possible to make it part of the game file. I’m always kinda wary of having to include multiple files alongside something I plan to distribute; it’s much simpler to just have the one game file.

2 Likes

Yes, you can. To access the file, use File.openTextResource() or File.openRawResource(). (Note that I’ve not used these before, so there may be some caveats.)

3 Likes

Ah, excellent!! I remember seeing these in the docs, but I guess I assumed it was for an external file, lol. I read up on packaging a few months after that, so I probably failed to make the connection. I’ll try implementing this and see what the size difference is!

Thanks again!

1 Like

Okay, well… if anyone was curious to know the answer to this: The difference appears to be 10.4kB.

Anyway…I’m gonna try the file-based cache, now that I’m back on the computer.

1 Like

Okay, with some help from @ArdiMaster, I have realized that I can generate the data into a file of any size I want, and then read that file using the standard File.openRawFile() method, and dump the converted contents into my variables during preinit.

Here are the results!

(A) With declaration method and Vector caching during preinit:
        1,658,900 bytes
(B) WITHOUT declaration method and Vector REMOVED:
        1,648,258 bytes
(C) Data loaded from file, and dumped into Vector during preinit:
        1,654,777 bytes

A-B difference: 10,642    bytes
A-C difference:  4,123    bytes
A : B ratio:         2.58 X

Alright!

It seems that the declaration instructions did count for approximately the size of the original data!
Also: A did include an attempt to set an empty method to the declaration!

EDIT: Also, if anyone has been curious, adding a garbage collection call (t3RunGC()) does absolutely nothing for the preinit stage, so it seems that garbage collection gets a pass before preinit is done as part of the normal process. (This was my assumption, but now it’s been tested.)

1 Like

Concur with the objective, I’m one whose back in 1980s fight with 8-bit .ASM until I reduce the code enough to free a 128 or 256 byte block from the floppy (and still look at my work modulo 4096 (the size of a block in my filesystem)… )

Best regards from Italy,
dott. Piergiorgio.

3 Likes