Skip to content

Latest commit

 

History

History
214 lines (171 loc) · 10.7 KB

DOC.md

File metadata and controls

214 lines (171 loc) · 10.7 KB

func-godot-lightpass documentation

This is a simple plugin, and for the most part all you need to do is press the "export all exportable nodes" button on an FGL* node. However, there are some cases where you may wonder what to expect, or get warnings when you do something incorrectly. Those are explained here. Also, it is possible to set up your own nodes to be exported by FuncGodotLightpass. That API is documented after the more common usecase scenarios.

Expected workflow

FuncGodotLightpass was designed with a certain level creation workflow in mind.

  1. Greybox and texture the level in TrenchBroom
  2. Import the level into Godot, and place lights there, adjusting color and brightness and range in the editor view
  3. Export the placed lights back into TrenchBroom map file
  4. Optionally repeat this process on the same .map file, greyboxing a new area of the level and then lighting it, until they level is complete.
  5. Touch-up the map file from either TrenchBroom or Godot at any point afterwards

Notice that its not expected for you to edit the lights from TrenchBroom. Although you can, the point is that you should be able to group, rotate, or move the lights while editing the level to keep things aligned. Changing the color or intensity of lights from TrenchBroom is not going to be as easy as from Godot. The light entity definitions are made simply to save values from Godot into the .map file, not to be edited from TrenchBroom.

Adding exportable nodes

To place a node, select your FuncGodotMap, right click, and select "Add Child Node." Alternatively, select it and then press Ctrl + A on your keyboard. Then type the name of a FuncGodotLightpass node, and hit enter. After, you may use Ctrl + D to duplicate these nodes. Try to keep them as direct children of the map node, as it will lead to the most predictable results.

The available nodes for placement using FuncGodotLightpass are as follows:

  • FGLOmniLight
  • FGLSpotLight
  • FGLDirectionalLight
  • FGLDecal
  • FGLWorldEnvironment
  • FGLAudioPlayer

Each of these has an in-editor button at the top of its inspector window labelled "Export all Exportable Nodes." Clicking this button will search the scene tree for all of the nodes under the same FuncGodotMap as the one which the user pressed the button on. It will write each of them out into the .map file.

Warnings and errors

Most instances of push_warning in this plugin are reserved for invalid input from map files or incorrect API usage- so you won't encounter them if you're following the documentation. But there are some warnings you will naturally encounter when using FuncGodotLightpass, unfortunately. These warnings are covered in this section. They are harmless or at least easily fixed, provided you know about them going in to using this plugin.

Duplicating lights

You may get warnings after duplicating lights in either Godot or TrenchBroom. If you can tell that the warnings correspond to lights you just duplicated, then you can safely ignore them.

As a rule of thumb, though, if you see warnings go away after one export, that means that some auto fix-up was applied to your nodes and you can ignore the warnings.

Nodes with resources

Most nodes have some field which contain a resource. For example, lights can have projector textures, and audio players can have audio streams. When encountering such a resource when writing to the map file, FuncGodotLightpass will write the resource's path to the file. There are two possible situations here:

  1. The resource is some .res file, and so the res://path/to/resource.res path is stored in the .map file. No warnings are emitted, but the loading process will break if you move the resource file somewhere else. FuncGodotLightpass does not have a mechanism to update paths written to .map files.
  2. The resource is unique, and not saved to a file. That means the path that FuncGodotLightpass will store is to the scene file, with the random unique ID of the resource appended to the end. In this case, FuncGodotLightpass will print a warning. Godot has a habit of regenerating UIDs (especially when a project is edited by multiple hosts), so the path saved to the .map file may randomly stop working. Additionally, whether or not this path can still be loaded by ResourceLoader is dependent on editor state. It will usually work, but it will break if the owning node is deleted and the project is reloaded.

tldr: save all your resources out to a file location, and never move those files.

If you absolutely need to move the files, you will have to manually find and replace the paths (all beginning with res://) in the .map file.

Adding nodes to TrenchBroom layers or groups from Godot

This feature is only enabled for FuncGodotMap nodes whose map settings have use_trenchbroom_groups_hierarchy enabled. When not enabled, exportable nodes will simply retain the same group or layer as defined in the .map file. Duplicated generated nodes will have the same group or layer as the original.

After enabling this feature, re-build your map in Godot. You should see that organizational Node3Ds have been added, with names such as layer_0_My Layer or group_2_lamppost. When exporting, nodes will check if they have any ancestors with a name starting with group_ or layer_ and use the number that follows that prefix to determine the group or layer of the node. Therefore, you can move nodes around, and their groups and layers will be determined by parent nodes. A node can only be on a layer or a group, never both, since groups are fundamentally all on the same layer, and the layer of grouped objects are therefore defined by the group, not the object itself. As FuncGodotLightpass traverses upwards from each exportable node towards the ancestor FuncGodotMap, the first encountered group is used. The last encountered layer is used. If a group is encountered at any point, it always overrides any layer information.

Note thate you cannot change the layer a group is in through this interface. It is intended only to edit the layers and groups of the exportable nodes themselves.

TrenchBroom linked duplicates

Linked duplicates in TrenchBroom are a way of copy and pasting a group of objects, and having TrenchBroom automatically copy and paste any changes you make from the edited group into all other groups.

When moving nodes around in Godot, you may cause these groups to become out of sync. According to the TrenchBroom manual, the correct approach to re-syncing the groups is to open the map in TrenchBroom and then make a small edit to one of the groups- then the contents of that edited group will be copied to all other instances.

Export API

In order to make a node exportable to TrenchBroom, two functions must be called in the node's script, and the script must be added to a generated node whose entity definition inherits from base_godot_exportable, an entity definition resource found within the plugin files, ie. addons/func-godot-lightpass/. This entity definition should already be in your FGD, since you should have added the FuncGodotLightpass FGD file as a base to yours.

The script on the generated node (set either by the "Script" option on the entity definition or by assigning the script to the root of the generated scene of the entity definition) must be @tool. The following base content is needed, where "misc_object" is replaced by the entity definition classname- "info_playerstart", or "light_point", etc.

@tool

func _ready() -> void:
	FuncGodotLightpass.apply_classname_metadata("misc_object", self)

func _func_godot_apply_properties(props: Dictionary) -> void:
	FuncGodotLightpass.apply_build_metadata(props, self)

FuncGodotLightpass needs to know the classname so that it can serialize a node to the map file and provide the correct classname there. However, apply_classname_metadata is internally called by apply_build_metadata, using a "classname" value found in props. So if you don't plan on ever creating your nodes in Godot, you can omit the contents of the _ready() function in the above example. The _ready() function is just necessary so that FuncGodotLightpass knows the classname / entity definition assigned to the entity even if it is placed normally, without ever recieving any data through a _func_godot_apply_properties() call.

By default, when serializing your node, FuncGodotLightpass will serialize all @export properties, as well as builtin node properties. It learns what properties a node has by reading a "property list" data structure, usually returned by Object.get_property_list(). Read the documentation for that function to learn how to format a property list. You can define _get_property_list_with_context() to change what properties FuncGodotLightpass knows about, and you can override _get() to change how it gets them. For example, here is a script which has only one property, regardless of what node type it inherits from:

@export var custom_amount: float = 0.0

func _get_property_list_with_context(context: Variant) -> Array[Dictionary]:
	if context is FuncGodotMapSettings:
	    return [
			{ name = "custom_prop", type = Variant.Type.TYPE_FLOAT, ignore_if = 0.0, usage = Object.PropertyUsageFlags.PROPERTY_USAGE_STORAGE, }
		]
	else:
		return get_property_list()

func _get(property: StringName) -> Variant:
	match property:
		&"custom_prop":
				return custom_amount
	return null

ignore_if is not a standard value for a property list. It is an additional property description value understood only by FuncGodotLightpass. It instructs the plugin to ignore the property, if it is some value. It is usually set to the default value.

If a property is of type float, FuncGodotLightpass will try to account for floating point error when comparing for equality with the ignore_if value. Values which are very slightly different from the ignore_if will be ignored, too.

usage must always contain PROPERTY_USAGE_STORAGE, as FuncGodotLightpass ignores all properties which do not have this usage flag. It must never contain PROPERTY_USAGE_INTERNAL, as FuncGodotLightpass also ignores any properties with that flag. FuncGodotLightpass will also ignore any properties that begin with "metadata/", or have the name "script" or "export_all_exportable_nodes".

FuncGodotLightpass will also always ignore "name", "owner", and "scene_file_path" when writing out to a map file. Also, in Node3D, "visibility_parent". And, if the node inherits from Light3D, "light_color" is serialized under just "color", so do not try to add a property called "color" to a light.

In your property list, do not include position or rotation values- if your node inherits from Node3D, FuncGodot will detect that and automatically handle it.