Rust ECS with dynamic loading/uploading of 'modules' (systems + components)?

I have 0 experience with dynamically loaded Rust code.

Is there a way, without restarting a running Rust ECS system, to dynamically load/unload 'modules' ?

Here, a 'module' is defined as Component + System.

This only needs to work on Linux.

You can pick your favorite ECS. I'm curious if this has been done at all before.


This crate has part of what you ask and an example using Bevy.
I'm not sure if you can add new components without restarting and you can't change the signature of systems.

I don't think this is something that can be safely done. Unloading is unsound if the main process happens to still hold some pointer to the module, for example &'static strs, other references to statics, function pointers and trait object vtables. Not to mention that the module could start some thread... Since all of this is inherently global, it's pretty much impossible to control and thus guarantee safety from a library point of view, but it must be a responsability of who writes the module.

I know very little about Java and even less about Minecraft, but in my limited understanding, Java Minecraft servers can dynamically load/unload modules.

In your opinion, is (1) I'm misunderstanding something or (2) the java runtime has some feature that makes this possible (that the Rust runtime lacks).


AFAIK you can try doing this on the JVM, and it will be memory safe, but it won't be guaranteed to be unloaded, and this can cause weird errors.

There's no explicit way to unload modules on the JVM except garbage collecting the ClassLoader which loaded them. However this requires that no object from that module is still alive, since they hold a reference to the ClassLoader and thus prevent the module from unloading as well. This is what makes it memory safe on the JVM, meanwhile Rust has no integrated garbage collector that can track everything, and lifetimes don't apply to stuff like function pointers, so this is impossible to track.

Moreover you might have notices that this means you can't force some module to be unloaded by the JVM, you can only pretend it was unloaded (if the library is well behaved with respect to that and your code doesn't incorrectly keep references to it). If your or the module mess up something then you can get weird errors, like for example ClassCastException that claim a class can't be casted to itself (due to one being from the module that should have been unloaded and one from the new one). In fact there were people arguing you should not use /reload on Bukkit/Spigot servers, and that should be removed.

1 Like