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.