Server Framework module hot reloading?

Maybe I’m missing something obvious here, but I find it kind of odd that we have to build, then compose up the Nakama server for testing/building code.

These related issues seem to indicate that others have this issue:

I’m just wondering if this is a feature I’m unaware of, and if so how do I enable it? If not, is it in the works? How does this work with the docker setup?

This doesn’t exist in Nakama natively but something you can enable with additional tools on your local development.

The reason why this isn’t something baked in to Nakama is that this is exceptionally hard to get right as the runtime code carries state (e.g. for Authoritative Matches). Additionally, in a multi-node setup, we’d then need to implement capability negotiation between different versions of the custom code.

Essentially, there really isn’t a practical ‘need’ to have this baked in to Nakama for production purposes and only is needed for local development which can be achieved much easier with some tools that watch your local disk file changes and recompile+restart Nakama.

1 Like

the feature is needed for local development, so you wouldn’t need this for multi-node setup. recompiling and restarting sometimes takes a very long time - for example using docker to recompile go modules for nakama took me more than 1 minute on every change. on top of that going to the console after restarting requires you to login again.

@mofirouz I appreciate your perspective and understand the technical challenges related to implementing hot-reloading in Nakama. As a platform tailored for developers using Lau, Go, and TS/JS, it’s surprising that hot-reloading isn’t readily available, especially considering the convenience it brings to server-side code development.

The majority of modern application, web, and game development environments consider hot-reloading an essential feature. It significantly enhances productivity by facilitating rapid iterations and testing, making it highly desirable for server-side game code development.

Colyseus, for instance, offers hot-reloading for single nodes: Dev Mode - Colyseus Multiplayer Framework. They manage state effectively and can restore room sessions during reloads in dev mode.

It’s important to emphasize that the objective of hot-reloading isn’t to support production functionality but to streamline local software development. Its potential to ease the development process is invaluable, especially in the context of server-side multiplayer games.

The need to recompile the Docker container with every minor change is burdensome and arguably disrupts the smooth development experience.

Given Nakama’s potential and strong capabilities, it’s disappointing that the lack of this feature may hinder its appeal for developers.

1 Like

Thanks for the follow up.

I don’t really like the “dev mode” feature - because from our experience, developers don’t really pay attention to the warning labels and expect the same behaviour in production which won’t be the case as discussed.

Personally when I develop with Nakama, I don’t need to recompile the entirety of the Docker image - with Lua/JS it will require a simple reboot of the container (just like Nakama reboot) if you’ve mounted the folder containing your code onto the container.

Maybe we just need a guide on how to achieve this in the documentation as first step and if that’s not enough, then we can look at what other steps we can take to make the Developer Experience better.

@mofirouz If i may,
In the past i really did also thought i would need hot reloading of modules as development was conducated by all of developers on single machine as all of data was there. And yeah reloading of the container it is fast usually but logging to the machine, uploading code, and then restarting took a while, especially if you had to test logic from clients.

Then we tried to do development with local setup. Each dev would had on its pc/mac setuped dev environment and worked on it, and this works great as long you don’t have to test multiplayer features, as if you need to run multiple clients and you dont have enough strong pc/mac to support that + docker , you are screwd.

So obviously this step is easy slowable by upgrading each dev pc/mac to have better specs, but it still didn’t solve for us the need of constant uploading/replacing/restarting/client starting/testing.

Solution i found by creating a test environment through editor.
Since we are using Lua as our runtime, we are using ZeroBrane editor. I managed to make ZeroBrane to support nakama, so intellisense and some of the features i got it working. The problem was how to access database, and well nakama features.
I have a made a testing/mocking lib in lua so we can execute in editor code and check does logic work.
I tried to make as much as i could testing/mocking lib to act how nakam would act and to return correct data when functions were called.
To mock database, we actually don’t fully mock it, but usually export from our dev machines a database in csv format, so lua can parse it, and let code run normally. And this gives all of our devs ability to execute code in editor/ live debugg it/catch outputs and then finally when logic is verified to put it in docker and test it in client.

Hi @mofirouz, I’ve been able to integrate the template Nakama project with docker compose, and set up a TypeScript compiler in watch mode. The setup uses nodemon to detect file changes and restart the container accordingly. I’ve found it to be a quite effective workaround, and it certainly improves the development experience, allowing me to get started on my project.

Is there a possibility for me to contribute to the existing documentation? I’d be interested in creating a tutorial that outlines this process, so that other developers could more easily set up a similar environment.

One question that I have is regarding the shared volumes in docker which are automatically updated without needing to restart the entire container. This brings up the possibility of having Nakama just watch the data folder and, upon detecting changes, only reload the specific modules that have been updated. Could you shed some light on if this is a possibility?

is there any solution for Go modules? i notice no problems with JS modules - but Go modules for some reason take a really long time to build on every change if going through docker.

Thanks @T0RR1N

Is there a possibility for me to contribute to the existing documentation? I’d be interested in creating a tutorial that outlines this process, so that other developers could more easily set up a similar environment.

We’ll be looking at how best to separate the content with the actual site layout so we could open-source the content in the future. At this moment, the best way to contribute to the documentation is to send us a Markdown formatted content that you’d like to have on the website and we can incorporate the doc with the official documentation.

One question that I have is regarding the shared volumes in docker which are automatically updated without needing to restart the entire container. This brings up the possibility of having Nakama just watch the data folder and, upon detecting changes, only reload the specific modules that have been updated. Could you shed some light on if this is a possibility?

That’s not possible sadly; due to the way the entire JS/Lua VM need to reconstruct the dependency tree, we cannot part-reload the graph into the system; the entire JS VM needs to be reconstructed based on all files not just a subset that has changed.

1 Like

For this, @dragonlobster I’d suggest that you take a look at your local Docker resource allocation and increase it; Go build tooling is quite cpu/memory hungry which may result in slower compilation process. Enabling many cores to the Docker VM can help with this.

The hot reload doesn’t need to be fancy. And in today’s ecosystem it is table stakes to have a good Developer Experience which includes a tight rebuild loop during local development.

All that is needed is for the server to completely restart when a change is detected in the modules directory (AppInstance pattern.) And an appropriate way to opt-in to the functionality in development environments. Launch flag, config option, etc.

Currently developers have to implement this functionality themselves at the wrong layer. Either at the OS layer by building a watcher system on top of the nakama base image. Or in their orchestration layer via docker compose watch, --build <svc>, etc.

This is time spent implementing missing functionality and not building a game.