Single Game Instancing

What do you use in order to guarantee that only one instance of your game is running?

  • I see programs like Gnome-Mahjong and Firefox Browser both have the ability to intercept the launch of another instance of their programs. In the case of Gnome-Mahjong it even re-shuffles the current game, just as further proof that the program itself was made aware of the relaunch.

I’m curious if there is a cross-platform solution.

OK. This obviously is not a new problem, a quick search brings up a half dozen solutions.
The one that appears most cross-platform seems to be called “Port Squatting”.

I’m getting pulled away from the computer, I’ll edit this post if I get a chance to make some example code. It looks like SDL_Net can be used here.

“Port Squatting” is extremely simple, here’s some sample code:

#include <SDL3/SDL.h>
#include <SDL3_net/SDL_net.h>

bool isFirstInstance()
{
	// I chose this port number at random
	// There's a slight possibility that this port is used by another program,
	// I don't know if there's a guaranteed resolution to this though.
	NET_Server * server = NET_CreateServer(NULL, 58147);
	if(server)
	{
		return true;
	}
	return false;
}

int main()
{
	SDL_Init(SDL_INIT_VIDEO);
	NET_Init();
	SDL_Window * window = SDL_CreateWindow("Not First", 400, 400, SDL_WINDOW_RESIZABLE);
	SDL_Renderer * renderer = SDL_CreateRenderer(window, 0);
	SDL_SetRenderVSync(renderer, 1);

	SDL_Color bgColor = {200, 200, 120, 255};
	SDL_Color firstColor = {255, 100, 100, 255};

	if(isFirstInstance())
	{
		bgColor = firstColor;
		SDL_SetWindowTitle(window, "First");
	}

	bool run = true;
	while(run)
	{
		SDL_Event ev;
		while(SDL_PollEvent(&ev))
		{
			switch(ev.type)
			{
				case SDL_EVENT_QUIT:
					run = false;
					break;
			}

		}
		SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, bgColor.a);
		SDL_RenderClear(renderer);
		SDL_RenderPresent(renderer);
	}
	NET_Quit();

	SDL_Quit();
}
  • I chose to not have the extra window close, but rather be aware that it is not the only instance in play. (Title and background color changed as evidence)
  • I expected it to be more difficult which is why I created the wrapper function “isFirstInstance()”, but this function is just an annoyance if you want to further develop a server-client relation between the windows.

Why it works:
Only one server is allowed to be open per port, so any subsequent program that tries to open a server on that port is guaranteed that NET_CreateServer() will fail and return NULL.
This is considered a reliable method because the port is automatically closed when the program exits (even if the program crashes to exit)

Edit:
I suppose the issue I bring up in the comments could be solved by completing the client-server handshake, and confirming that the server is an instance of your program. If it is not, then have a couple of follow-up ports to attempt.