Dereferencing/dealloc/garbage collecting an object declared in source?

Is there any way to get rid of an object declared in source in TADS3? I’m specifically worried about adv3, but I don’t think that’s relevant for the question (someone correct me if I’m mistaken here).

Basically I’ve been experimenting with different ways to declare certain kinds of things whose “normal” syntax I find clunky or unintuitive (like Doors), mostly by declaring a template object in source which is then automagically converted (during preinit) into the “real” in-game objects. Ideally I’d like these declarations to be able to clean up after themselves (by dereferencing themselves in non-debug builds).

2 Likes

I’m not aware of any way to disappear declared objects…
Can you create your doors with a preinit construct routine and then convert them, or does that defeat the purpose?

1 Like

Yeah, in that case that’s the solution I’ve been using: having the door template class be a subclass of Door, so the declared object becomes one half of the door pair.

In other cases I don’t think that approach will work (at least not directly). For example, I’ve got an NPC memory library I’m working on where individual memory objects may or may not be directly re-usable in this way (because some of them are “base” memories and others will be modifications/deltas to other memories, and so several objects can end up being consolidated into a single object).

There’s also some procgen map stuff where I think I’d like the ability to basically scrap and re-initialize any Room instance, for example.

Another approach is to do a sort of roll-you-own garbage collection by implementing a singleton to keep track of instances that aren’t being used in the current game configuration, and then re-using them by manually zeroing out their properties and then re-initializing them with new ones. But roll-your-own garbage collection is one of those “this way madness lies” sorta things.

2 Likes

I don’t see how. Objects declared in source are stored statically in the image file. You could nil out all the properties, but the base object declaration will always remain.

Since classes are just another form of object in TADS, it’s like asking if you can deallocate or free a class.

Keep in mind the undo stack can defeat some of your effort. I don’t believe preinit data is on the stack, but init-time data will be.

One possibility: Have your template classes / preinit code all located in a single compilation unit / file, and list it last in the Makefile.t3m. If the stars align, the compiler will put them all in the same code page(s) and toward the end of the image file, and only swap them in during initialization. If they’re not referenced again during runtime, the page(s) will fall out of core early on and not be paged in again.

EDIT: Also, there are many other types of pages in an image file, so they might not locate toward the absolute end of the image. The idea is to keep the pages with said code out of core, so compiling them together may still achieve the desired effect.

Obviously, this is relying on a lot of side-effects and what-ifs. On the plus side, the TADS compiler is not a moving target these days.

2 Likes

Neither I…

but I wonder if jbg is taking in account eventual memory/CPU HP issues in constrained environment (cell phones, perhaps ?) because AFAICT desktop and laptop computers today has much more than enough resources to handle large/computing-intensive .t3 story files (the largest one in my if/bin/tads3 remains, since 2008, macrocosm.t3, perhaps back then some memory and/or resource issues was possible, but today ?

I think, and I’m a fan of highly optimised code, that perhaps is an optimisation not worth the heavy, and potentially compiler version dependant, as Jim Nelson discreetly noted, effort.

Best regards from Italy,
dott. Piergiorgio.

2 Likes

@jbg, have you done testing and found that the performance is measurably decreased by these static objects remaining in memory?

1 Like

I’m not worried about the performance or capabilities of modern hardware per se. I’m worried about the T3 VM. It gets wobbly and starts exhibiting (as far as I know) undocumented behavior(s) when you hit a couple thousand objects.

1 Like

Hm… Prince Quisborne has 16,500 objects (at startup) and I haven’t noticed anything wobbly from it, per se…

1 Like

If you’re not doing anything too unusual, I think the hard-ish limit is 65k objects (that is, internally objects have 16 bit IDs). The limit is much lower for objects in a single location—you’ll get an exception if you try to place more than ~13k objects in the same scope (I frequently but not exclusively get a limit of 13100 objects in testing, lower if the objects aren’t all instances of the same class)…but you’ll get a runtime error if the player tried to enter a room with fewer than that (I’m not sure what the exact limit is).

Performance craters with dynamic object creation at smaller object counts.

If you’re writing a “well-behaved” game you’ll almost certainly never run into any of these issues. But I’m writing a game with a bunch of implementation idiosyncrasies. So I’m much more cautious about just writing off stuff as something I’ll never have to worry about, because I don’t want to hit a wall on down the road.

3 Likes

This is why I tend to ask weird questions here, lol. I’ll be following this thread closely, as I’ve also wondered about this.

1 Like