ENGLISH | 中文
Progressive tutorial examples for godot-java — Java 25 + Panama FFI bindings for Godot.
The native library is required for Godot to start the JVM. Build it for your platform:
# macOS (requires Xcode command line tools)
cd godot-java-core/native && ./build-macos.sh
# Linux (requires clang++)
cd godot-java-core/native && ./build-linux.sh
REM Windows (requires MSVC or MinGW)
cd godot-java-core\native && build-windows.bat
This compiles godot_java.cpp and deploys the library to examples/shared-native/.
cd godot-java-examples
mvn package
This produces the fat JAR and automatically deploys it to examples/shared-native/.
Before running any example, set these environment variables:
# macOS / Linux
export JAVA_HOME=/path/to/jdk-25
export GODOT_JAVA_CLASSPATH=$(pwd)/examples/shared-native/godot-java-examples.jar
# Windows PowerShell
$env:JAVA_HOME = "C:\path\to\jdk-25"
$env:GODOT_JAVA_CLASSPATH = ".\examples\shared-native\godot-java-examples.jar"
Open any example directory under examples/ as a Godot project:
# macOS
open -a Godot.app ./examples/01-hello-world
Or run in headless mode:
# Step 1
/Applications/Godot.app/Contents/MacOS/Godot \
--path godot-java-examples/examples/01-hello-world \
--editor --quit-after 2
# Step 2
/Applications/Godot.app/Contents/MacOS/Godot \
--path godot-java-examples/examples/01-hello-world \
--headless --quit
| # | Name | Concepts | Description |
|---|---|---|---|
| 01 | hello-world | @GodotClass, _ready() | Print a message from Java when the node enters the scene tree |
| 02 | export-properties | @Export | Expose fields to the Godot Inspector for editing |
| 03 | godot-methods | @GodotMethod | Call Java methods from GDScript with parameters and return values |
| 04 | signals | @Signal | Declare and emit signals from Java, connect in GDScript |
| 05 | process-loop | _process(delta) | Per-frame updates — circular orbit motion |
| 06 | node-tree | getChildren(), addChild(), getNode() | Scene tree traversal and dynamic node creation |
| 07 | physics-2d | CharacterBody2D, _physicsProcess(), move_and_slide() | 2D physics with gravity and movement |
| 08 | math-types | Vector2, Vector3, Color | Math type operations (pure computation, no movement) |
Each example follows the same pattern:
@GodotClass, extends a Godot node type (e.g., Node, Node2D, CharacterBody2D)ClassDB.instantiate("ClassName") and adds it to the scene treeproject.godot, godot-java.gdextension, and a sceneThe godot-java.gdextension file tells Godot to load the native bridge library (libgodot-java.so/.dylib), which starts a JVM and registers all @GodotClass-annotated classes found on the classpath.
@GodotClass(name = "MyNode", parent = "Node2D") // Register as a Godot class
public class MyNode extends Node2D {
@Export // Visible in Godot Inspector
public double speed = 200.0;
@Override
public void _ready() { ... } // Lifecycle: called once when added to tree
@Override
public void _process(double delta) { ... } // Lifecycle: called every frame
@GodotMethod // Callable from GDScript
public int compute(int x) { return x * 2; }
@Signal // Declare a signal
public void onHit(int damage) {}
}
Emit signals from Java:
call("emit_signal", "onHit", 42);
Connect signals in GDScript:
var node = ClassDB.instantiate("MyNode")
node.connect("onHit", _on_hit)
godot-java-examples/
├── pom.xml # Maven build (shade → fat jar)
├── src/main/java/examples/ # Java example classes
└── examples/
├── shared-native/ # Shared deployment target (JAR + native lib)
│ ├── godot-java-examples.jar
│ └── libgodot-java.dylib # (or .so / .dll per platform)
├── 01-hello-world/
│ ├── native/ # Symlinks → ../../shared-native/
│ ├── godot-java.gdextension
│ └── main.tscn
├── 02-export-properties/
└── ...
Each example's native/ directory contains symlinks to shared-native/, so a single build deploys to all examples.
Apache-2.0