中文 | ENGLISH
Godot 的 Java 绑定,通过 GDExtension + Panama FFI 让 Java 在 Godot 生态中成为一等公民。
状态:0.1.0——生产就绪,具备 scoped 内存管理和完整的 GDExtension 功能覆盖。
项目示例:
在游戏开发领域,语言的”默认组合”很多年都没有 Java 的位置:
而与此同时,Java 仍然是全球使用最广泛的语言之一——在企业后端、Android 开发和大规模数据处理领域占据主导地位。每天有数百万开发者在写 Java,但游戏引擎生态却几乎不给他们任何选择。
这对已经有成熟 Java 技术栈的团队来说,是一个真正的缺口:
godot-java 想做的事情,就是打破这种“游戏开发没有 Java”的惯例:
从工程角度看,目标是:
这个项目一开始就选择 Java 25+,而不是兼容 Java 8/11/17 等 LTS 版本,原因有三点:
避免历史包袱
不再背负旧版 Java 的限制,只针对一个现代版本设计 API 和内部实现,代码可以更干净、更直接,不需要为了兼容早期 JDK 写各种分支和适配层。
用上最新的语言与平台特性
可以放心使用:
switch 表达式和 var 等语法糖java.lang.foreign Panama FFI API满足你对现代 Java 的一切想象
目标是让使用者可以在游戏项目里,尽情使用最新一代 Java 的表达能力和工具链:
如果你只是想探索 “Godot + 现代 Java + Panama FFI” 能做到什么,这个项目会更偏向一个“给你一个完全现代的起点”,而不是一个“从历史包袱里一路升级上来的 SDK”。
目前已实现的核心能力包括:
Godot GDExtension 绑定(C API)
GDExtensionInterfaceGetProcAddress 动态加载 Godot APIGDExtensionClassLibraryPtr, GDExtensionPropertyInfo, GDExtensionClassMethodInfo 等)完成注册Java 25 Panama FFI 集成
java.lang.foreign(Linker, FunctionDescriptor, MemorySegment 等)调用 Godot 的 C 函数注解驱动的类 / 方法 / 属性 / 信号注册
@GodotClass:声明一个可以在 Godot 中实例化的 Java 类@GodotMethod:暴露给 Godot 调用的成员方法@Export:导出到 Godot Inspector 的属性,支持 hint 和 hintString 参数用于编辑器集成@Signal:在 Java 侧声明并发射 Godot 信号godot-java-processor)在编译期生成类型化分派代码,热路径零反射虚方法与生命周期回调
extension_api.json 自动扫描)_ready, _process, _physics_process 等)notification)、字符串表示(toString 桥接)、引用计数(RefCounted 的原子引用计数)、属性验证等ptrcall 零拷贝分派
Variant 装箱开销MethodHandle 分派,针对注册的 @GodotMethod 方法RefCounted 派生类使用 ref_get_object/ref_set_object 处理 RefPtr 参数类型系统与 Variant 互操作
Variant, GodotStringName, GodotString, GodotArray, GodotDictionary 等类型从技术栈角度,这个项目的几个关键点:
GDExtension(Godot 4 官方扩展机制)
.dylib / .so / .dll)Java 25 Panama FFI
java.lang.foreign),不需要第三方 native bridgeFunctionDescriptor、MemoryLayout 精确建模注解驱动的注册模型
分派架构与 gdext(Rust 绑定)对齐:upcall stub 在类注册时按需创建,仅为用户实际 override 的方法创建 stub。未实现的方法返回 NULL,由 Godot 使用默认的 C++ 实现。
注解处理器(godot-java-processor)在编译期为每个类生成分派代码:
TypedDispatch_<ClassName> — 基于 MethodHandle/VarHandle 的方法分派(热路径零反射)PropertyAccess_<ClassName> — 基于 VarHandle 的 @Export 属性访问VirtualDispatch_<ParentClass> — 按父类分组的虚方法哈希映射(将候选方法名从 1000+ 缩减到约 12 个)get_virtual_func upcall stub — 按需创建,仅为用户实际 override 的方法生成MethodHandle 预缓存分派,辅以反射回退StringName 指针比较解决哈希冲突notification_func — 将 Godot 通知转发到 Java 实例的 onNotification(int)to_string_func — 将 Java toString() 桥接到 Godot 的字符串表示reference_func / unreference_func — 为 RefCounted 派生类提供原子引用计数validate_property_func — 属性验证透传,用于编辑器集成Variant 装箱开销RefPtr 参数使用 ref_get_object/ref_set_objectMethodHandle 分派,用于已注册的 @GodotMethod 方法@Export 注解支持 hint 和 hintString 参数,用于 Godot 编辑器集成get_property_list_func — 将 @Export 字段暴露到 Godot Inspectorproperty_can_revert_func / property_get_revert_func — 默认值支持,提供还原行为@Signal 注解用于信号声明和从 Java 发射信号将其他语言引入 Godot 有多种方式。以下是 godot-java 与主要替代方案的对比:
| 集成方式 | FFI 层 | 虚方法 | ptrcall | 用户门槛 | 成熟度 | |
|---|---|---|---|---|---|---|
| godot-java | GDExtension | Panama FFI (Java 25) | 全部 1144 个 | 支持 | 低(无需重编译引擎) | Alpha |
| godot-rust/gdext | GDExtension | Rust FFI | 全部支持 | 支持 | 低(无需重编译引擎) | 稳定 |
| graphics.gd (Go) | GDExtension | CGO | 支持 | — | 低(无需重编译引擎) | 社区维护 |
| godot-kotlin-jvm | 引擎模块 | JNI | 全部支持 | 支持 | 高(需要重编译 Godot) | 稳定 |
| C#(官方) | 引擎模块 | N/A | 全部支持 | 支持 | 中(内置 Mono) | 官方 |
两种集成方式的核心差异在于语言如何与 Godot 结合:
GDExtension 是 Godot 4 的官方插件 API。基于它的语言会编译为共享库(.so/.dylib/.dll),Godot 在运行时加载。用户只需下载标准 Godot 即可,无需重编译引擎。godot-java、gdext、graphics.gd 均走这条路。
引擎模块 将语言直接编译进 Godot C++ 进程。好处是可以完全访问引擎所有能力(全部虚方法、直接调用 Input.* 等),但代价是必须从源码重编译整个 Godot。godot-kotlin-jvm(JVM 必须嵌入进程)和 C#(Godot 内置)走这条路。
godot-java 选择了 GDExtension 路线。支持全部 1144 个虚方法(从 extension_api.json 自动扫描)。分派架构对齐 gdext(Rust 绑定):upcall stub 在类注册时按需创建,仅为用户实际 override 的方法创建 stub。未实现的方法返回 NULL,由 Godot 使用默认 C++ 实现。
如果你熟悉 gdext:godot-java 的架构目标与其相似,只是用 Java 替代了 Rust,用 Panama FFI 替代了 Rust 原生 FFI。
本仓库的文档分为英文与中文两套,针对不同读者做了区分。
docs/README.md
中文文档分为两部分:
用户文档:docs/zh/user/
getting-started.md — 快速开始api.md — 常用 API 与类型说明guide.md — 使用指南与实践建议troubleshooting.md — 常见问题处理开发者文档:docs/zh/dev/
architecture.md — 项目架构与内部实现building.md — 如何构建、打包与升级 Godot 版本contributing.md — 面向贡献者的指南debugging.md — 如何调试 Godot + Java 交互问题godot-java/
├── pom.xml # 根 Maven 项目(聚合模块)
├── godot-api/ # Godot API JSON 文件(代码生成器输入)
│ ├── extension_api.json # Godot 类/方法/属性定义
│ ├── gdextension_interface.json # GDExtension C 接口定义
│ └── gdextension_interface.h # GDExtension C 头文件(参考)
├── godot-java-core/ # 核心运行时与 Godot Java 绑定
│ ├── native/src/godot_java.cpp # C++ 入口(GDExtension 初始化)
│ ├── src/main/java/org/godot/
│ │ ├── annotation/ # @GodotClass, @GodotMethod, @Export, @Signal
│ │ ├── bootstrap/ # JVM 启动与 GDExtension 入口
│ │ ├── bridge/ # Panama FFI 桥接(VirtualDispatch, InstanceCallbacks)
│ │ ├── core/ # Variant, StringName, GodotString, Callable…
│ │ ├── collection/ # GodotArray, GodotDictionary
│ │ ├── math/ # Vector2/Vector3, Transform2D/3D…
│ │ ├── node/ # 1016 个生成的节点封装(Node, Node2D, Control…)
│ │ ├── internal/api/ # 自动生成:ApiIndex, ApiSignatures, VariantType, VirtualMethods…
│ │ └── registration/ # 注解扫描与类注册
│ └── src/test/java/ # 单元测试
├── godot-java-code-generator/ # 代码生成器(基于 Godot API JSON)
│ └── src/main/java/com/godot/codegen/
│ ├── Main.java # 入口
│ ├── ApiIndexGenerator.java # 176 个 API 函数索引
│ ├── ApiSignaturesGenerator.java # Panama FunctionDescriptor
│ ├── VariantTypeGenerator.java # Variant 类型枚举
│ ├── VirtualMethodGenerator.java # 虚方法元数据
│ ├── ClassGenerator.java # 1016 个节点封装类
│ └── StructLayoutComputer.java # C 结构体偏移计算
├── godot-java-processor/ # APT 注解处理器
│ └── src/main/java/org/godot/processor/
│ └── GodotClassProcessor.java # 编译期生成 TypedDispatch/VirtualDispatch
├── godot-java-examples/ # 示例项目(10 个示例)
│ ├── src/main/java/examples/ # Java 源码(helloworld, pong, snake…)
│ └── examples/01-*/~10-*/ # Godot 项目(.tscn, .gd, native/)
├── upgrade-godot-api.sh # 一键升级 Godot 版本
└── docs/ # 文档(中英文)
├── en/user/ | en/dev/
└── zh/user/ | zh/dev/
当 Godot 发布新版本时,godot-java 只需一步即可完成升级:
./upgrade-godot-api.sh 4.7
该脚本会:
extension_api.json 和 gdextension_interface.json然后验证:
./mvnw clean install -DskipTests
如果你想快速跑起来:
确保本地有:
阅读:
然后根据文档:
godot-java-core 和 godot-java-code-generator@GodotClass Java 脚本进行试验欢迎:
具体细节请参见:docs/zh/dev/contribution.md