I’ve seen multiple games where if you open another window of the game when you already have one open, it gives you a message saying you can’t have multiple open, and then that second one closes. How do I achieve this? Or in short: How do I detect if there are multiple windows of my game open?
There are multiple games that I’ve made that would benefit from having this implemented. So thanks in advanced!
Every project gets its own per-user persistent storage that scripts can acces using user://-prefixed URLs.
Notice how i said “every project”, not “every instance”. Never tried it myself, but i think two instances of the same project will share the same user:// base directory.
Knowing this, you can keep a resource at user://instances.tres and have the game load it at startup.
class GameInstances extends Resource:
@export var instances: Array[GameInstanceEntry]
pass
class GameInstanceEntry extends Resource:
@export var pid: int
@export var name: String
func _init(new_pid, new_name):
pid = new_pid
name = new_name
pass
pass
Then at game start you make some script check for entries on that resource:
var game_instances = load("user://instances.tres")
if (not game_instances.is_empty()):
# there is already an instance running
# bunch of cross-window multiplayer code...
pass
else:
# there are no other instances running.
# single-player init...
pass
game_instances.append(GameInstanceEntry.new(OS.get_process_id(), "MY GAME 3: RELOADED RETURNS PLUS ULTRA TURBO"))
# you can order players by instance spawn order
set_player_id(game_instances.length())
game
Based on the posts text, I think OP isn’t looking for a local multiplayer game, and instead, wants to make sure only a single instance of their game runs.
In that case, your code has a flaw which the answer I gave above fixes:
If your game crashes, the residual file will still exist, and at that point, your game can no longer function until your player manually removes the file.
If pid file is used, you could check if the process with given pid still exists, but I guess that would require executing OS specific stuff with OS.execute.
Another way would be creating TCP server. Something like this:
var server: TCPServer
func _ready() -> void:
server = TCPServer.new()
var ok = server.listen(12345, "127.0.0.1")
if ok != OK:
prints("probably already running another instance")
But this isn’t problem free either. You need to pick a port number than nobody else uses. Unfortunately the port number is only a 16 bit integer, so it is pretty much guaranteed that someone has something else already running on that port.
I could include crash handling and live instance introspection but then a bunch of other stuff would have be be cascaded into the example and the small suggestion would turn into a 400-line cross-instance bus.