Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Splitting editor and runtime scripts. #12837

Closed
ghost opened this issue Nov 11, 2017 · 12 comments
Closed

Splitting editor and runtime scripts. #12837

ghost opened this issue Nov 11, 2017 · 12 comments

Comments

@ghost
Copy link

ghost commented Nov 11, 2017

Just a feature suggestion. X)

I use tool script quite a lot in my projects, and it is one of the big highlights for me. However, there are situations where a lot of extra work is needed to prevent code from colliding. Walling off code that is editor only versus code for run time only.

For some scripts this is exactly fine, because almost all the same code is used. Though quite often in other situations the code gets littered with extra branches, and the logic of the tool takes almost entirely different turns. It can get very bloated and difficult to organize, especially when they have different start up behaviors.

I was thinking it would be a nice added option if nodes could optionally have a resource slot for Editor Only Script. Something that specifically only executes in the editor, and can be discarded when a project is exported.

Note: Leaving the old way intact though, because there would be some trade off between code duplication and branch complexity.

@Zylann
Copy link
Contributor

Zylann commented Nov 11, 2017

Last time I thought about this I thought it could be done with #ifdef macros, although they only get rid of execution bloat, not maintainance. On the other hand you could use a child editor-only node (or a mere script) and put tool functionality in it, I used to do that in my game for debugging in order to keep code separate (leaving only one if in my main gameplay script)

@ghost
Copy link
Author

ghost commented Nov 11, 2017

@Zylann I like that idea. Thanks for sharing it.

@SirPigeonz
Copy link
Contributor

SirPigeonz commented Nov 12, 2017

I had idea of EditorOnlyNode, that would be stripped when doing Export.
Mare idea never consulted it with anybody.

@ghost
Copy link
Author

ghost commented Nov 12, 2017

@n-pigeon That also sounds interesting. Especially for addon custom nodes that act as editor only helper nodes.

@Zylann
Copy link
Contributor

Zylann commented Nov 12, 2017

See #12453

@bojidar-bg
Copy link
Contributor

Related to #8735. Copy-pasting my proposal here:

element.gd:

tool "element_tool.gd"
# This script isn't tool by itself, but is replaced by the other in-editor
extends Node2D

export(int, "Fire", "Water", "Ice") var element_type = 0

func get_damage():
  return ConfigAutoload.elements[type].damage

element_tool.gd:

tool # Might be unnesesary, discuss
extends "element.gd"
# extends is not required, but better if you do this so you would get all the exported vars

# Discuss: do we really need to extend the other script for that?
# We might handle it like placeholder scripts, exporting/autocompleting the same, but
# having different in-editor logic.

export(bool) var debug = true setget set_debug

func _ready():
  set_debug(debug)

func _draw():
  if debug:
    pass # Draw circles, whatever..

# Needed since we don't have a cool way to observe property changes yet
func set_debug(new_debug):
  debug = new_debug
  update()

@Zylann
Copy link
Contributor

Zylann commented Nov 14, 2017

Would this work with C# and GDNative?

@bojidar-bg
Copy link
Contributor

bojidar-bg commented Nov 14, 2017

Well, it would work as long as there is some way to specify the target tool script. So, attributes in C#, and some additional registration function in GDNative. Examples:

// c#
namespace X {
    [Godot.Tool(typeof(ElementTool))]
    class Element { /* ... */ }

    class ElementTool : Element { /* ... */ }
}
// C++
NATIVESCRIPT_INIT() {
	register_class<Element, ElementTool>(); // Not sure if it would be here. This is just an example.
	register_class<ElementTool>();
}

Likely, it would be done internally as Ref<Script> Script::get_tool_mode_script() {}, with the current implementation being equivalent to Ref<Script> GDScript::get_tool_mode_script() {return this;}.

@Zylann
Copy link
Contributor

Zylann commented Nov 14, 2017

Also it must be taken into account that we may want to not include such editor stuff when exporting ;)

@ghost
Copy link
Author

ghost commented Nov 14, 2017

As an aside, one of the unhappy things I keep bumping into with tool script (and why splitting would be handy), is that they will not allow you to reference Autoload Singletons. Even if it isn't being called directly by tool code, it will flag it when it parses.

This doesn't compile:

tool
extends Node2D

func _ready(): 
	if(not get_tree().is_editor_hint()):
		Utils.my_utility_function(123)

@bojidar-bg
Copy link
Contributor

@avencherus That's a bug, #4236

@ghost
Copy link
Author

ghost commented Sep 21, 2018

Closing this. Appears a different and more robust feature/direction is being considered going forward.

As an aside, one of the unhappy things I keep bumping into with tool script (and why splitting would be handy), is that they will not allow you to reference Autoload Singletons.

This was very thankfully resolved: #18545

@ghost ghost closed this as completed Sep 21, 2018
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants