minetest / minetest

Luanti (formerly Minetest) is an open source voxel game-creation platform with easy modding and game creation
https://www.minetest.net/
Other
10.85k stars 2.04k forks source link

Help modders deal with object invalidation properly #14687

Open appgurueu opened 6 months ago

appgurueu commented 6 months ago

Object lifetime is managed by the engine. This means that the "rug can be pulled" from under a modder; an entity can become invalid from one server step to the next. Modders need to be careful to check this.

Getters will just return some kind of "invalid" value - sometimes even a valid value - while setters will just be no-ops. I believe this probably masks logic bugs.

I think the engine could help them here.

First and foremost, our docs should draw attention to the issue to make sure it isn't overlooked. This is relatively simple to do.

However, I don't think we should stop there. My suggestion:

Ultimately, what we're doing here is implementing "optionals at home", where the default behavior is error-throwing unwrapping (which makes sense for our purposes).

Thoughts?

cx384 commented 6 months ago

Would it be possible to handle this via the Lua garbage collector? Similar to Weak Tables in Lua, just make it nil when it does no longer exist.

appgurueu commented 6 months ago

Would it be possible to handle this via the Lua garbage collector? Similar to Weak Tables in Lua, just make it nil when it does no longer exist.

Unfortunately I don't think that's possible without modifying Lua. With weak tables, you effectively mark the parent, telling Lua that children can still be garbage-collected (if there are no remaining "strong" references to them).

I'm not aware of any mechanism that would allow you to mark a userdatum (or a table for that matter) itself as collectable. (I also searched the reference manual and couldn't find anything that would be helpful here.)

(And even if such a mechanism existed, we couldn't rely on the GC actually collecting the userdatum in a timely manner, and for the remaining duration of its life, it would still be invalid.)

appgurueu commented 4 months ago

The only thing remaining here is whether to deprecate getters / setters on invalid objects. We probably don't want to deprecate getters since it is too much work for anyone involved, and they return nothing consistently. Setters may be deprecated in-code eventually, the docs already don't endorse this.