godot icon indicating copy to clipboard operation
godot copied to clipboard

Add "Game" editor for better runtime debugging

Open YeldhamDev opened this issue 1 year ago • 101 comments

Implements several aspects of https://github.com/godotengine/godot-proposals/issues/7213.

https://github.com/user-attachments/assets/8a7d4e0c-b624-4660-bf83-0e9495117d01

Features Implemented

  • Selection of 2D/3D nodes at runtime ~when the game is suspended (see below)~, this includes anything that has collisions or some sort of visual representation. When a node is selected, a selection box will appear around it and it will be opened in the inspector.
  • Suspend mode. This is a middle ground between in-game pausing and the editor's break feature. When this mode is enabled, it allows node selection, and frame skipping.
  • Next frame. This allows the game to run one frame at the time when the it's suspended.
    • Production edit: This closes https://github.com/godotengine/godot-proposals/issues/3105.
  • 2D/3D camera override. The camera manipulation can come from within the game, or the 2D and 3D editors.

Things Missing

  • Window embedding. This requires low-level OS-specific code, that's above my league.

Limitations

  • For now, selection only works in the root window. This is not a hard limitation, and selection in subwindows could be implemented as well.
  • No editor theming for the selection boxes and popup list, as well as no shortcut redefinition for camera controls, since we can't access those values at runtime. A possible workaround would be to pass those settings via the debugger.

Compatibility Break

  • A minor one is unavoidable to add this new editor to the feature profile.

Sponsored By: 🐺 Lone Wolf Technology / 🍀 W4 Games.

YeldhamDev avatar Sep 20 '24 22:09 YeldhamDev

This is excellent!

One small detail I think would be neat is to freeze the time parameter in shaders while the game is suspended, so that the effects don't continue animating and the 'next frame' button allows for shader debugging

JoNax97 avatar Sep 21 '24 12:09 JoNax97

@JoNax97 Done!

YeldhamDev avatar Sep 21 '24 14:09 YeldhamDev

Finally, this is incredible work and I'm really excited to see this merged! Thank you so much! A few questions:

  1. I can't tell from the video but does the click selection also work to highlight the tree item in the "remote" tab? I see it selects the remote note in the inspector which is great but it would also be cool to quickly navigate a complex hierarchy by selecting stuff, which would quickly unfold the parent items. I believe I've seen a plugin do this recently.
  2. Would it possible to separate the "suspend" mode from the click selection so that users can click on things while the game is not paused? Like maybe with a separate toggle to activate a selection mode instead of being tied to suspend? I think this was something mentioned in the original proposal with the "selection mode", and being able to click on (and eventually edit I presume) nodes while the game is running could save a lot of time for realtime tech demos (like cloth physics demos as an example) that would otherwise have to implement their own selection tools. I'm also imagining a debug camera being the next step here and that might fit better in a selection mode rather than suspend mode because you could take a look at something more closely while its in motion/changing instead of having to unpause and repause and find that exact spot again.
  3. Finally, and this may be a big ask, but is there potential for users to extend the functionality of these new runtime tools with custom code? For example, if there was never a PR for changing camera in pause mode, a user might want to code their own camera system that hooks into the new suspend code. But since I noticed that the can_process method now checks for suspend status, no user code can be run while the game is paused. This makes sense as a quick way to halt scripts but it would be neat to allow some way to customize how the tools work, though I'm not exactly sure how. On that note, it would also be great to get a signal for suspend and unsuspend to coincide with the notifications, that way at least user code can run when the mode starts and stops :)

I don't think all of that necessarily needs to go in this PR but just curious about the future of this feature. Regardless, I really appreciate what you have so far!

RobProductions avatar Sep 21 '24 23:09 RobProductions

@RobProductions

  1. Yes! And clicking an item in the remote tree also highlights the node in the game as well.
  2. Internally we settled to make selection only available when suspended, as the inputs of clicking around would clash with in-game code.
  3. This sort of stuff would need to have its own proposal opened for discussion, as this is beyond the scope of this PR.

YeldhamDev avatar Sep 22 '24 00:09 YeldhamDev

Great work!

I'm curious how this would behave for an XR project.. would it be possible to disable the Game tab for an XR project but keep the functionality shown in the video? cc @BastiaanOlij

Also I'm curious if this would work with the Android editor. Have you tested this PR with the Android editor?

m4gr3d avatar Sep 22 '24 04:09 m4gr3d

YESS!! FUCKING THANK YOU

rayzorite avatar Sep 22 '24 06:09 rayzorite

Hell yeah!

Kathenae avatar Sep 22 '24 07:09 Kathenae

3. Finally, and this may be a big ask, but is there potential for users to extend the functionality of these new runtime tools with custom code? For example, if there was never a PR for changing camera in pause mode, a user might want to code their own camera system that hooks into the new suspend code. But since I noticed that the can_process method now checks for suspend status, no user code can be run while the game is paused.

@RobProductions I haven't checked the code yet, but like this PR is doing, you can have your own code evaluated outside of process (even during debug breaks), by registering a capture in EngineDebugger and implementing a EditorDebuggerPlugin to communicate with it.

Faless avatar Sep 22 '24 09:09 Faless

yay, amazing work !!! 🥳

adevinwild avatar Sep 22 '24 10:09 adevinwild

Nice work, I would like to see more controls for the interacted objects (in Unity you can move, rotate, scale in this mode?), maybe some new buttons needs to be introduced for this.

Chaosus avatar Sep 22 '24 14:09 Chaosus

  • [x] Sometimes the suspend button is stuck disabled:

https://github.com/user-attachments/assets/535347b0-31c3-4f05-8bb2-2f823041558a

This happens after running the project a couple of times and requires restarting editor to fix.

EDIT: Seems to happen when you F8 to close the game. Looking at the implementation, maybe session counter is broken.

EDIT2: Yep, F8 closes the session twice and makes the counter go negative permanently.

  • [x] The selection popup appears at wrong position. Seems to be relative to "Game" position.

https://github.com/user-attachments/assets/c1f7ac6e-7009-4c27-a81f-878c460ea9d4

  • [ ] It would be useful to have in-game shortcut for next frame. Clicking a button isn't always convenient.

KoBeWi avatar Sep 22 '24 15:09 KoBeWi

This is similar to what Unity has right? (not used Unity)

What supposes in practice? I mean, i know that it allows to select and pass frame by frame but aside in practice, what this allows that before wasn't possible?

azur-wolve avatar Sep 22 '24 18:09 azur-wolve

I mean, what this allows to do that before wasn't possible

See the description:

  • Selection of 2D/3D nodes at runtime when the game is suspended (see below), this includes anything that has collisions or some sort of visual representation. When a node is selected, a selection box will appear around it and it will be opened in the inspector.
  • Suspend mode. This is a middle ground between in-game pausing and the editor's break feature. When this mode is enabled, it allows node selection, and frame skipping.
  • Next frame. This allows the game to run one frame at the time when the it's suspended.

What do you mean? How is that not functionality? What are you asking? This is exactly what it allows that wasn't, are you asking what it is for? Or?

AThousandShips avatar Sep 22 '24 18:09 AThousandShips

This is similar to what Unity has right? (not used Unity)

What supposes in practice? I mean, what this allows to do that before wasn't possible

This is completely different from the functionality in Unity. The game still runs in a separate process, and game errors will not affect the editor. However, the theoretical final effect may be very similar to Unity, provided that functions such as window embedding and camera overlay are implemented.

scgm0 avatar Sep 22 '24 18:09 scgm0

I went over the implementation and left some comments; overall it's probably ok. The feature works fine, why is this still a draft?

Though I find the UX a bit awkward. I assume even when embedding is implemented, the current separate window mode will still be available. And if you have separate window, the Game tab is mostly redundant; it's only used for its tiny toolbar. I foresee lots of switching between Game and Script tabs during debugging. Feels like there should be a way to move the toolbar out of Game tab. I don't have concrete idea though.

KoBeWi avatar Sep 22 '24 19:09 KoBeWi

@KoBeWi Bugs fixed!

The feature works fine, why is this still a draft?

Well, without the embedding, the editor just has a big blank square in the middle of it for no reason, which makes me consider the current state unfinished. I can mark it as ready if the rest of the maintainers want to merge it as is, however.

Though I find the UX a bit awkward.

I just followed through the proposal's idea. I'm open to suggestion on how to improve the overall UX.

It would be useful to have in-game shortcut for next frame. Clicking a button isn't always convenient.

Sure! Any suggestions?

@Chaosus

Nice work, I would like to see more controls for the interacted objects (in Unity you can move, rotate, scale in this mode?), maybe some new buttons needs to be introduced for this.

Out of scope for the current PR. But a proposal can be opened about more things to be added!

YeldhamDev avatar Sep 22 '24 22:09 YeldhamDev

Thank you. Wonderful job!

mrussogit avatar Sep 22 '24 22:09 mrussogit

@mrussogit Please don't bump without contributing significant new information. Use the 👍 reaction button on the first post instead.

timothyqiu avatar Sep 23 '24 00:09 timothyqiu

Some notes:

  • Generally it seems to work, but we do need the embedding for this to be useful. I think it can be implemented in another pr to get things going, it just needs to be ready on release to avoid confused users. Simplest option I can think of is just keeping the game window on top, set to borderless and dynamically change position to fill the editor panel. I saw somebody showing presumably this kind of tool in reddit a few days ago (here).

  • In-game shortcuts should be defined in project's input map, so that they can be changed per project if needed. However, they should work also when editor is active instead of game for coherent experience. My suggestion: debug_pause = shift + esc debug_next_frame = shift + f1 debug_select_2d = shift + f2 (could interfere with batch rename, any better suggestions?) debug_select_3d = shift + f3

  • Show list on click has a few bugs

    • When you select an option, a new list is opened. list bug It works if you click, drag and release at the correct option. Which is arguably more ergonomic, but is different to editor's behavior.
    • If the mouse moves into the menu (even on border) it closes when releasing mouse. (this also can be seen in screencap above)
    • When doing a selection from the list, the object under mouse gets briefly selected before the list item gets selected (when using alt+RMB).

And here's some less important things we can address at later time:

  • Some things for better integrating scene tree:

    • Automatic changing to remote scene when running game, or at least when selecting any node would be appreciated.
    • Selecting a node in game doesn't cause scene tree to scroll to show selection.
  • A big "run" button in the otherwise empty panel might be better for ux. Or maybe run automatically when changing to game mode or vice versa?

  • I would consider placing the mode after assetlib, if not for anything else then for shortcut to be ctrl + f5 as run game f5 and open game mode are conceptually close (also if opening game tab runs the game automatically, it feels appropriate) 😁

  • Camera override is disabled when switching to Game mode, limiting it's usefulness greatly. However, in the long run, camera override should be not needed and instead allow controlling the camera freely when paused would be preferred.

  • Something akin to @tool scripts could be added (@debug perhaps) for enabling users to run scripts even when game is paused by the editor.

  • Does the next frame show next process or physics frame? Should there be distincion between the two for debugging different code?

  • Once embedding is implemented and if it's implemented as I understood from the proposal (via some Vulkan voodoo), I think it could be possible for the editor to draw overlays on top of the game? This could be used for theming the menu (since editor draws it instead of game) and also for transformation and camera gizmos. Disclaimer: I may have misunderstood what reduz was proposing.

aXu-AP avatar Sep 23 '24 06:09 aXu-AP

Simplest option I can think of is just keeping the game window on top, set to borderless and dynamically change position to fill the editor panel. I saw somebody showing presumably this kind of tool in reddit a few days ago (here).

Major appeal of this feature for me would be recording or screen capturing the editor window (for example on Discord) and not having to switch between which window I'm capturing every time I run the project, this wouldn't work with this approach.

Another thing that has to be considered is what should happen if the game tries changing resolution, full screen mode or one of the window parameters.

On a related note another useful feature I'd like to see when window embedding is implemented is aspect ratio controls, with options like fitting the area, using the project resolution, choosing from presets or letting the user manually type in a ratio.

ettiSurreal avatar Sep 23 '24 10:09 ettiSurreal

Well, without the embedding, the editor just has a big blank square in the middle of it for no reason, which makes me consider the current state unfinished.

Do you plan to implement it now though? It can be done iteratively, with the current PR as the first step. Unless follow-ups would require some major rewrites.

Though I bet users will be disappointed if it makes it into next release in this state. Maybe we can make it disabled/hidden by default or something.

Sure! Any suggestions?

It could be something similar to debugger_stop_shortcut in Window, but for frame step. If the game is not suspended, it would suspend it. If it's suspended, the shortcut would call next_frame().


In-game shortcuts should be defined in project's input map, so that they can be changed per project if needed.

That would mean keeping editor-only shortcuts in project settings. I don't think it's really necessary, the functional buttons (F1-F12) are rarely used in games, so they can be used for shortcuts.

Automatic changing to remote scene when running game

There is already editor setting for that.

Something akin to @tool scripts could be added (@debug perhaps) for enabling users to run scripts even when game is paused by the editor.

Might be unnecessary once we get REPL.

KoBeWi avatar Sep 23 '24 10:09 KoBeWi

I don't think it's really necessary, the functional buttons (F1-F12) are rarely used in games, so they can be used for shortcuts.

The function keys are used quite commonly in PC games as default keybinds.

Though I bet users will be disappointed if it makes it into next release in this state. Maybe we can make it disabled/hidden by default or something.

As a user, though, I do second this suggestion.

pineapplemachine avatar Sep 23 '24 12:09 pineapplemachine

That would mean keeping editor-only shortcuts in project settings. I don't think it's really necessary, the functional buttons (F1-F12) are rarely used in games, so they can be used for shortcuts.

I tend to use f1-f12 for various debug functions though. Minecraft is one popular example which also packs a lot of functionality to those keys. Some genres like MMORPG and RTS also tend to use function keys. But I think shift+esc which I proposed is quite safe for pausing. Other shortcuts aren't needed when game is running.

Automatic changing to remote scene when running game There is already editor setting for that.

Oh, I see, it's disabled by default (due to performance concerns?). Maybe it could open anyway upon pausing or selecting a node?

Might be unnecessary once we get https://github.com/godotengine/godot/pull/60134.

I was thinking more like creating tool scripts to help with debugging. But on second tought, they might be possible as editor plugins. In any case, it's more like food for thought, not really relevant for this pr.

aXu-AP avatar Sep 23 '24 13:09 aXu-AP

@aXu-AP Fixed most of the popup-related bugs. The one about releasing the mouse inside the popup closing it seems like a bug with embedded PopupMenus in general, as it can be reproduced with other menus as well.

YeldhamDev avatar Sep 23 '24 14:09 YeldhamDev

Hi @YeldhamDev , thanks for answering my questions above! I pulled down your code to check it out and there's a few things I wanted to mention. First off, when running the 3D platformer demo I noticed the game was crashing when I spammed mouse clicks while in suspend mode, here's a video demonstrating that:

https://github.com/user-attachments/assets/91b8e06a-d36b-4d01-9fda-d52c9ecf1196

With more experimentation I think I narrowed it down to when you click the number text above the player in this scene, so I suspect there's some sort of null error in the new selection code regarding text objects(?)

Next, regarding question 2. I had above, I did some tinkering with the selection mode and managed to split it out so it could work even without the game being suspended. I called this "Edit Mode" and created a new button for it in the top toolbar to test it out. With these changes in place, you can activate "Edit Mode" where inputs are stopped from reaching the game and the click selection works whether the game is suspended or not:

https://github.com/user-attachments/assets/1235c020-028b-4113-b475-9007489e3962

Could something like this work to solve the "clash between inputs" you mentioned earlier? If you'd like to see my changes, here is the branch and here is the relevant commit :)

A few notes though, the code is not polished since it acts more as a proof of concept - the edit mode button doesn't reset, extra functionality is hooked into the suspend variables instead of being more explicit, and I had to update the bounding box on input event rather than every frame because it was easier, but that stuff is easily remedied in a proper PR. I'm pretty interested in this subject mainly because the tool becomes a lot more useful when it works while the game is running 😄 thanks!

RobProductions avatar Sep 24 '24 02:09 RobProductions

That's really a nice work!! I expect lot of users will find these features very useful.

Is there anyone working on the embedding part? I have some experience with embedding another process window into an application, I'll be glad to give it a try if nobody is already working on it.

Hilderin avatar Sep 24 '24 02:09 Hilderin

@YeldhamDev this is great!

I wanted to quickly check; this looks like it will be an officially supported, superset of the hacky prototype I worked on here: https://github.com/bbbscarter/GodotRuntimeDebugTools

Is that the intention? If so, that's fantastic, and I will happily deprecate my hack when it lands!

bbbscarter avatar Sep 24 '24 13:09 bbbscarter

Is there anyone working on the embedding part? I have some experience with embedding another process window into an application, I'll be glad to give it a try if nobody is already working on it.

Please go ahead, this would be awesome!

akien-mga avatar Sep 24 '24 14:09 akien-mga

This addon does the embedding: https://fabimakesgames.itch.io/embedgame

Maybe you can get some ideas from it

cesarizu avatar Sep 24 '24 16:09 cesarizu

This addon does the embedding: https://fabimakesgames.itch.io/embedgame

Maybe you can get some ideas from it

The reddit post of the addon was brought up earlier, it essentially "fakes" the embedding by putting a borderless window over the relevant area, which while fine for an addon, I believe should not be the way this is implemented into the editor.

ettiSurreal avatar Sep 24 '24 17:09 ettiSurreal