PadraigK / SceneGen

Swift Code Generator for Godot Scenes — renders typed descriptions of each node in a godot project's scene files.
MIT License
21 stars 0 forks source link

SceneGen

Renders typed descriptions of each node in the scene files (.tscn) of a Godot project. Provides an access function to get a reference to the nodes called node(). This tool is intended for use with Miguel de Icaza's SwiftGodot bindings and generates Swift code that depends on SwiftGodot being available.

Example

A Node Tree in Godot

In SwiftGodot a node is referenced as follows:

let marker = getNodeOrNull("Sprite2D/Marker2D") as? Marker2D

This requires the programmer to ensure that the path to the node, and its type, are correct. If there is a mismatch, the marker variable will be nil.

If we run SceneGen on this project, our root Player type will be extended with typed descriptions of each node. These can then be accessed in a type-safe way:

let marker = node(.sprite2D_marker2d)

The programmer is no longer responsible for maintaining the types and the paths. This will lead to fewer run-time bugs and crashes, provide helpful code completion suggestions in your IDE, and allow faster iteration cycles.

Usage

I'm still figuring out the Swift PM story for how to run this, but in the meantime, here's an approach that works well:

  1. Install Mint (brew install mint) if you don't already have it.
  2. Add a file named Mintfile to your project and put PadraigK/SceneGen@0.1.2 (or whatever the latest release tag is) in there.
  3. Run mint bootstrap (takes a while, maybe 5 mins)
  4. Run code generation using mint run scenegen <project-path> <output-path> — note that output path will be deleted each time this is run before code is generated. This is necessary to clean up if you remove or rename a scene.

Use with a Watcher

The recommended usage of SceneGen is with a watcher, like entr, which can be used re-run the generation anytime one of the scene files changes.

I suggest making a shell script like this:

#!/bin/zsh

# loop because the `-d` flag on `entr` makes it exit when it 
# detects a new or deleted file in any of the folders its watching,
# otherwise it would only detect modifications to existing files
while sleep 0.1; do
    find ../ -name '*.tscn' -not -path '*/.*' | entr -d -s 'mint run <project-path> <output-path>'
done

and then leaving it running in a terminal window as you work.

Benefits