Registering scripts and members
Before Godot can use a JVM class as a script, the class and the members you
want to expose must be registered. In most projects, this only means adding a
few annotations and building the project.
The usual workflow
The default registration mode is Inferred. It is the best starting point
for a new project.
- Mark a Godot subclass with
@Script.
- Use
@Export for values you want to edit in the Inspector.
- Use
@Register for ordinary functions that Godot, another script, or the
editor needs to call.
- Build the project after adding or changing a script, an Inspector property,
a signal, or a function that Godot calls.
For example:
After a successful Gradle build, attach the source file to a node in the
editor in the same way that you would attach another script. The health
property is available in the Inspector, heal is available to Godot, and
healthChanged is available as a signal.
Source file naming
Godot automatically associates a project source file with its compiled JVM
class from the package declaration and the source file name. The file name,
without its extension, must therefore match the simple name of the script
class:
| Player.kt -> class Player
Player.java -> class Player
Player.scala -> class Player
|
For example, Player.kt may declare com.example.game.Player, but a file
named Character.kt cannot be automatically associated with that class.
Keep one attachable script class in each source file.
This source-loading rule is separate from the Automatic annotation
processing mode described below. It applies whenever Godot automatically
links a .kt, .java, or .scala project resource to its compiled class.
You do not need to add @Register to Godot callbacks such as _ready in the
default mode. Godot recognizes compatible overrides automatically.
What each annotation is for
| What you want to do |
Use |
| Make a class available as a Godot script |
@Script |
| Give a script class a custom Godot name |
@Script("PlayerCharacter") |
| Show and edit a property in the Inspector |
@Export |
| Choose an Inspector control, such as a range or file picker |
A property hint such as @IntRange |
| Let Godot call an ordinary function |
@Register |
| Configure a remote procedure call |
@Rpc |
| Give signal arguments readable names |
@Emit("amount") |
Property hints also export a property in the default mode. For example, this
creates an Inspector slider without requiring a separate @Export:
Signals declared with the supported signal helpers are recognized
automatically. Add @Emit only when you want to name their arguments:
Functions and Godot overrides
Use @Register on an ordinary function when it is part of your script's
Godot-facing API:
Godot callbacks are different. When a function overrides a Godot method, such
as _ready, _process, or _physicsProcess, simply override it. Do not call
these methods yourself; Godot calls them at the appropriate time.
Use @Rpc when a function is intended for multiplayer. It provides the RPC
settings and makes the function available in the default mode:
See Functions, Properties, and
Signals and callables for the available types
and options.
Changing the registration mode
Most projects should keep the default Inferred mode. Choose another mode
only when its behaviour matches how your project is written.
| Mode |
When to use it |
What to remember |
Inferred |
The normal choice |
Add @Script and @Register where needed; exports, signals, callbacks, and RPCs are handled naturally. |
Explicit |
You want every Godot-facing declaration marked directly |
Add every required registration annotation yourself. |
Automatic |
You deliberately want public compatible members exposed by default |
Public properties and functions can become part of the Godot API without annotations. |
Set a mode in build.gradle.kts only if you need a non-default mode. This
configuration is the same for Kotlin, Java, and Scala projects:
In Explicit mode, annotations do not imply one another. An Inspector
property therefore needs both @Visible and @Export; a range hint still
only controls the Inspector widget:
In Automatic mode, take care with public members. Prefer Inferred if you
want to decide member by member what becomes visible to Godot.
Note
In Automatic mode, the source filename must match the registered class
name. Otherwise, use @Script as you would in Inferred mode.
If you use the IntelliJ plugin, set the same mode in Settings | Godot
Kotlin/JVM | Annotation processing mode. Gradle controls the actual build;
the IDE setting keeps inspections and highlighting accurate.
Before building
When registration fails, check the following first:
- The script extends a Godot class such as
Node or Resource.
- A public constructor with no parameters is optional. When present, Godot can
instantiate the script; constructors with parameters are not exposed to
Godot.
- Every registered script has a unique Godot name. Use
@Script("AUniqueName") if two classes share the same simple name.
- Exposed properties and function parameters use Godot-supported types.
- Registered classes and functions are not generic.
Build again after adding, removing, renaming, or changing an exported property,
signal, function that Godot calls, or script class. Changing only code inside
an existing method does not require any additional registration steps.
For project-wide settings such as registration names and .gdj files from
dependencies, see Gradle plugin configuration.