brave-frontier-godot icon indicating copy to clipboard operation
brave-frontier-godot copied to clipboard

GDScript / Godot Standards and Formatting

Open aMytho opened this issue 1 year ago • 2 comments

I probably should have made this before we wrote all of the code (lol).

There are several patterns we should try to follow. We can make exceptions when needed, but we should try to keep them unless change is necessary.

Code Formatting

  • Local/instance variables are in snake_case. my_hp.
  • Custom Signals are in PascalCase SomethingHappened
  • Class/resource names are in PascalCase Unit
  • Globally available nodes are in PascalCase
  • Two lines of white space between functions

I come from a web dev background, so some of these seem pretty strange. However, we should try to follow them. Some early areas of the projected will need to be updated to match this.

Code architecture

  • Call down and signal up
    • This refers to how data, state, and actions are passed between nodes. The general convention is that a child node should never access or modify a parent node. It will receive data from a parent, but it never access it directly. The parent node will always be responsible for setting the properties of the child node. Many of our nodes have a set_properties function. This is an example of that.
    • When a child node needs to pass a change to a parent, it must use a signal. This has several advantages. The first is that is allows the child node to be used pretty much anywhere. If a change happens, it signals it and its job is done. The parent assumes responsibility from that point forward.
      • Consider if we didn't do this approach. A change occurs. The child node accesses the parent node. It sets some properties, and calls a few functions. Later, we want to reuse the child node. To prevent an error, the child node must bring along the parent node. Alternatively, the new scene must implement whatever the child needs. This makes it harder to use it dynamically.
    • One example of this is the large_button.tscn. This node is used in various areas throughout the project. It simply displays a button, and emits a signal when clicked. Since the parent always knows if the button exists, it knows to listen for that signal and respond accordingly. We can easily add hundreds of these nodes and all we have to do is listen for the signal. The button never has to change.
      • Consider if we didn't do this approach. The button would have to know every possible scene that it will be in. When it is clicked, it examines this list and calls the appropriate parent function. This would grow in complexity with every use.
  • If a child node needs something from a parent node, it can emit a signal and the parent would set the needed property. However, we should try to avoid this situation. Ideally, the parent node should have already set the data.
    • Basically, a child node function shouldn't have to request something from a parent. The parent should set it beforehand.
  • If a parent node needs something from a child node, it can wait for a signal or access the property directly.
    • Signals are generally used for events, rather than returning data. If you need something specific right now, it is probably best to access it directly.

We are doing a fairly decent job of following these guidelines. However, there are still some areas which need to be updated. I'm still learning this engine, so its possible I don't fully understand all of these.

aMytho avatar May 18 '23 20:05 aMytho