godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Identify instance windows when using launching multiple instances #3357

Open Duroxxigar opened 2 years ago

Duroxxigar commented 2 years ago

Related to https://github.com/godotengine/godot-proposals/issues/522.

Describe the project you are working on

A networked game in pre-alpha 4.0

Describe the problem or limitation you are having in your project

When using the new feature to launch multiple instances (pic 1), it is very easy to lose track of which instance belongs to which debug session (pic 2).

instances

debug

Describe the feature / enhancement and how it helps to overcome the problem or limitation

In the instance window title bar, display the debug session number, something like, Session - 2. This will help prevent this situation altogether.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Read above

If this enhancement will not be used often, can it be worked around with a few lines of script?

Will be used all the time for games that are testing with multiple instances.

Is there a reason why this should be core and not an add-on in the asset library?

It's a core editor feature now.

chrisb123 commented 2 years ago

This will be handy property to expose, currently all the instances are created and stacked on top of each other with the exact same name, there is no way to determine or label which is which session and I have to manually arrange the windows every time they are started

Calinou commented 2 years ago

The technical implementation of this feature likely involves adding a --window-title-prefix command line argument that can be set to add a prefix to the project's window title. This prefix also be prepended to any run-time window title changes performed by the project.

This argument could be made available in debug builds only as to not bloat release export templates.

chrisb123 commented 2 years ago

I worked out how to do this in gdscript with a network game I was working on. I found what it did and was not a good solution

opatut commented 2 years ago

The technical implementation of this feature likely involves adding a --window-title-prefix command line argument that can be set to add a prefix to the project's window title.

I would appreciate it if this would double as a way to identify the different sessions from script, e.g. --session-index -> Engine.get_session_index() or something along those lines, so I can automatically make one session a server and the other the client on startup in my debug entrypoint scene, such that I end up in a working game without interaction, for even faster testing.

Eoin-ONeill-Yokai commented 2 years ago

@opatut @Calinou I recently had to make my own modification to the engine to account for something like this and found this proposal when searching for any existing requests. I would like to know how users here feel before attempting an upstream.

I've basically created an instance identifier variable (for instance, --instance-count 1~4) which will be added to the command line arguments only when there are multiple instances available.

So by opatut's recommendation, I could make an Engine.get_session_index() option, which would default to 1 when there's no flag accessible. Right now, I'm actually use it for my initialization of server / client for debugging. For my server client check, I'm simply looking at all the input args for --instance-count and then grab the next variable. If it's 1, I run the server. If it's 2 or more, I run the client instance.

With that in mind, users could configure whatever behavior they need from this (including modifying window title states, or overlaying detailed information unique to each instance as an overlay in game) while also having other uses for it such as testing server client interactions.

Basically, I have the code ready already to mostly upstream, but would like to clean it up if the main team is interested. Should I create a WIP merge request?

chrisb123 commented 2 years ago

exposing the session ID with something like Engine.get_session_index() would be ideal, no need for more

kdada commented 1 year ago

Multiple instanses may connect to debug server in arbitrary order.

I have another implementation for this proposal: Add misc capture group to RemoteDebugger and add misc:set-session-id to set the session id.

Mimerme commented 1 year ago

I think adding a feature to seperate the two console instances as well would be helpful as its currently difficult to differentiate between the two while print debugging

kuyarruyyy commented 10 months ago

I was scrolling through the docs for a solution and I came across DisplayServer.window_get_attached_instance_id() here and it looked promising. So, I put it in a label, run 2 instances of the project, and got different values between the instances.

Is this what we are looking for? If not, can someone enlighten me on what it actually does and how is it different from what we are trying to achieve?

Edit: After some tinkering, no, this wasn't a solution. There were moments where the same values were displayed in the label for both instances. If someone can enlighten me about this particular method, I will deeply appreciate it.

quimnuss commented 8 months ago

Meanwhile, I found OS.get_process_id() which at least lets me distinguish between windows. As a quick and fallible workaround this missing info I'm just doing modulo 2 to choose player 0 or 1 which works most of the time.

There's probably a way to leverage this more robustly.

KonstantinosPetrakis commented 5 months ago

One way to handle this is the following (by storing an incremental value to a file):

func get_incremental_number():
    var save_path = "user://incremental.tres"

    var store_value = func(val): 
        var file = FileAccess.open(save_path, FileAccess.WRITE)
        file.store_64(val)
        file.flush()
        file.close()

    var read_value = func():
        if FileAccess.file_exists(save_path):
            await get_tree().create_timer(.5).timeout # Wait for val to be saved
            var file = FileAccess.open(save_path, FileAccess.READ)
            var value = file.get_64()
            file.close()
            return value
        return 0 

    var value = await read_value.call()
    store_value.call(value + 1)
    return value

func _ready():
    if await get_incremental_number() % 2 == 0:
        _on_lobby_host_game(Globals.SERVER_PORT)
    else:
        _on_lobby_connect_game("localhost", Globals.SERVER_PORT)

It's not the brightest way, but it's used for debugging purposes anyway.

ctrlraul commented 4 months ago

Here's a way to give an index/id to the instances running using Godot 4.3:

  1. Under the Debug menu, select "Customize Run Instances..." image

  2. Set a command line argument with the index for each instance: image

  3. Implement the code to obtain the value - I'm using C# but the GDScript equivalent shouldn't be too dissimilar:

    
    public readonly int InstanceIndex = GetInstanceIndex();

private static int GetInstanceIndex() { const string pattern = @"instance-index=(\d+)";

Regex regex = new Regex(pattern);

foreach (string arg in OS.GetCmdlineArgs())
{
    Match match = regex.Match(arg);

    if (match.Success)
        return int.Parse(match.Groups[1].Value);
}

return -1;

}


I settled for a regex pattern match, but you can always use a command line arguments parsing library for it.

NOTE: Which instance will have each index isn't deterministic.

I hope that's useful to anyone else. 🙂
JodliDev commented 2 months ago

@ctrlraul Sorry. How is it that you have an option "Customize Run Instances"? I am running the latest Godot 4.2.2 and I dont have anything like that. What am I doing wrong? Please teach me your magic :D

grafik

D4r3NPo commented 2 months ago

@JodliDev It's a new feature of the 4.3 : Capture d’écran 2024-06-24 à 17 49 49

JodliDev commented 2 months ago

Oh. Well, I should have figured that out myself. Thank you very much! :)

recon472 commented 3 weeks ago

is it possible to set these new settings in 4.3 through gdscript? I'd like to add buttons to my editor which would change the settings in this customize run instances window