The World of Warcraft Server emulator TrinityCore has a hot reload system for its Scripting (Boss AI, Spells etc.).
AFAIK when it's enabled, those modules are compiled into their own shared library and when you make a change to one of the script .cpp files, it triggers a compilation and then unloads and reloads the shared library (I think the process is more complicated than that so it doesn't crash for scripts that are currently active and different operating systems behaving differently).
Made developing those scripts much, much more comfortable when it was introduce. You no longer needed to manually compile, stop and start the server, wait for all the database stuff to be loaded, switch to the client, log back in, wait and then retry on every single tiny change.
To me, it was like magic.
Today, I wonder why they didn't just use a proper scripting language.
This is how RunUO/ServeUO was designed as well. I'm pretty sure it's a common design practice that came from muds. The server is only responsible for network and communications - everything is then orchestrated through plugins/scripts/systems that can be compiled and reloaded while the server is running. The more modern way is now to separate your "server" from your "modules" in distributed-systems architecture (just deploy the new module to the farm) but the idea still permeates.
Still, RunUO was C# and like java, recompiling and loading is trivial. Doing it in C/C++ land is heroic.
At least for java, you can spin out a new class loader which intercepts all class loading tasks and basically shim the dynamic module from the permanent runtime platform very trivially. For unloading, you'll likely need conventions on how to shut it down cleanly to not leave a ton of garbage around. Want a new version? Spin up a new class loader, rinse and repeat. If you need stateful between versions, you clearly need to mindfully build a facade for that outside of the dynamic parts. This is all not hard, but not introductory either. That said, I basically wrote similar DLL loaders in my first year writing c so many decades ago, so shrugs.
Class loading from a DLL is one thing, persisting the state and reloading that state on-top is another. In Java, you can use the class loader to load new instances of a class, but it's up to you to transfer state before giving that class over to your program again. In C# it's a similar story with System.Runtime.CompilerServices. The trivial bits are the fact that you can use reflection to do this rather easily in both Java and C#. In C++ isn't not as simple. The struct/data signature may change, you need a temporary storage vessel (old object?) to copy to the new class object. While it's still "digital plumbing", it's not that easy to do and then hot-reload the whole stack.
Made developing those scripts much, much more comfortable when it was introduce. You no longer needed to manually compile, stop and start the server, wait for all the database stuff to be loaded, switch to the client, log back in, wait and then retry on every single tiny change. To me, it was like magic.
Today, I wonder why they didn't just use a proper scripting language.