Changelog
Changelog
This document tracks changes of released library versions.
See also Pulse for recent activities.
Cutting-edge API docs of the master branch are available here.
๐ indicates a breaking change. Deprecations are not marked breaking.
Quick navigation
- v0.5.0, v0.5.1, v0.5.2, v0.5.3, v0.5.4
- v0.4.0, v0.4.1, v0.4.2, v0.4.3, v0.4.4, v0.4.5
- v0.3.0, v0.3.1, v0.3.2, v0.3.3, v0.3.4, v0.3.5
- v0.2.0, v0.2.1, v0.2.2, v0.2.3, v0.2.4
- v0.1.1, v0.1.2, v0.1.3
v0.5.5
_9 August 2026_
๐ป Features
- EngineBitfield: add with() and without() methods (#1627)
- #[func(virtual)] now supports async fn for GDScript coroutines (#1645)
- Add PhantomData<T> support for GodotConvert derive macro (#1619)
๐ Performance
- Singletons are now cached (#1636)
- Cache user singleton pointers (#1644)
- Cheaper refcount operations (#1669)
๐งน Quality of life
- Always use godot_error in panic hook (#1647)
- Rename cast_int/cast_float to to_vector/to_rect (#1661)
- Validate class registrations against ClassDB (#1664)
๐ ๏ธ Bugfixes
- Fix #[var(pub)] panic during OnEditor<Gd<T>> reload (#1639)
- Fix async SignalFuture panic when object is freed before exit flag (#1648)
- Fix api-custom build when prebuilt lags detected Godot version (#1649)
- Harden various parts of codebase (#1660)
- Fix GFile BufRead past EOF (#1670)
๐๏ธ Maintenance
- Replace godot-cell borrow-state proptests with exhaustive model check (#1650)
- Make accidental access of #[doc(hidden)] symbols more explicit (#1651)
- Follow-up to rustc / Godot changes (#1659)
- Name virtual-callback layers after user-facing I* virtuals (#1662)
- Move ref-counting operations from DynMemory to RawGd (#1667)
v0.5.4
_23 June 2026_
๐ป Features
- Godot 4.7: add api-4-7 level (#1641)
- Type-Safe API for User-defined RPCs (#1535, #1634)
- String conversions: to_gstring(), to_string_name() etc (#1623)
- Thread-safe FFI scaffolding + cross-thread printing (#1632)
- Gd introspection APIs: dynamic_class, is_dynamic_class[_of], is_ref_counted (#1631)
- Support async versions of tools::load() and tools::try_load() (#1601)
- Support @export_node_path attribute (#1620)
๐งน Quality of life
- Slightly more flexible GodotStringExt through unsized impls (#1629)
- Suppress Godot errors in fallible functions (#1637)
๐ ๏ธ Bugfixes
- Fix Linux hot-reload panic when TLS destructors fire before init (#1611)
- Fix panic-in-drop in future tests; harden against race conditions (#1617)
- Auto-remove custom callables also when connected in untyped APIs (#1612)
- Fix async panics at shutdown (#1625)
- Fix Object returns with dynamic type RefCounted (#1628)
- Fix memory leak for connect_self() on RefCounted (#1635)
- Fix dangling singleton pointer after deinit (#1638)
- Fix RPC borrow panic for call_local (#1643)
๐๏ธ Maintenance
- Add once flag to defer_startup_warn! and defer_startup_error! (#1613)
- CI: unzip occasionally fails; retry (#1616)
- Rename self-registration parts: plugin -> shard (#1618)
- Replace internal PassiveGd with safer BorrowedGd (#1633)
๐ Documentation
- Document register-docs security; warn when used in export builds (#1615)
- Document #[class(tool)] + ready() behavior across editor reload (#1614)
- Fix borrow panic in godot::task::spawn doc example (#1622)
v0.5.3
_19 May 2026_
๐ป Features
- JSON-based workflow -- no more bindgen/LLVM (#1562)
- Import Godot documentation for methods (#1573, #1582)
- Complete missing ScriptInstance functions (#1592)
- API to check class/singleton availability (#1576)
๐ Performance
- Doc tags: use linear scanner instead of regex replacements (#1580)
- Optimize JSON -> Domain mapping + some doc-imports (#1584)
- Simplify object casts and migrate to Object::is_class() (#1586)
- Tweak monomorphizations -> 7-9% lower godot-core compile times (#1587)
๐งน Quality of life
- check.sh now accepts --full (#1608)
๐ ๏ธ Bugfixes
- Instance creation now goes through proper placeholder process (#1597, #1606)
- Opt-in to new behavior with upcoming-editor-placeholders feature (#1607)
- Main thread discovery must be first (#1574)
- Fix pruning stored stale signal connections in the editor (#1585)
- Avoid potential use-after-free by unregistering EditorPlugins early (#1590)
- #[export_tool_button]: fix use-after-free in captured Gd pointer (#1589)
- Generate gdextension_interface.json out of Godot binary for Godot versions newer than latest/stable (#1572)
- Fix version check in godot_exe (#1579)
- custom-api-json - allow to specify custom header (#1583)
- Fix several issues in GDScript test framework (#1594)
๐๏ธ Maintenance
- Use new initialization for Godot 4.7 (#1567)
- Internal AtomicEnum<T> for global enum variables (#1593)
- #[itest(editor)] for itests running only with -e --headless (#1591)
- Reduce number of "ERROR" prints in itest (#1595)
- Remove LLVM from CI; runner updates (#1599)
- Make godot::signal the canonical signal API (#1602)
๐ Documentation
- Add more realistic godot::task::spawn example (#1581)
- Add info about #[func(rename = ...)] to #[godot_api] docs (#1605)
v0.5.2
_28 April 2026_
๐ป Features
- Support Result<T, E> as return type in #[func] (#1544, #1564)
- Import Godot docs for classes, not yet methods (#1552)
- Add print_custom() for low-level Godot printing (#1569)
๐งน Quality of life
- Virtual methods in I* traits now follow lifecycle order (#1555)
- Implement convenience conversions for Error (#1528)
- Unify CALL_FAILED_STATUS; silence redundant print (#1557)
- Collect uninitialized OnEditor fields into single panic message (#1558)
๐๏ธ Maintenance
- Follow up Godot 4.7 nullability changes (#1556)
- Codegen directly uses correct module path for global enums (#1559)
๐ Documentation
- Discourage use of WeakRef class (#1560)
v0.5.1
_12 April 2026_
๐ป Features
- #[signal(internal)]: hide from Godot docs/autocomplete (#1543)
๐งน Quality of life
- Improve error message for reference params/returns in #[func] (#1542)
- GodotConvert::Via: Clone is now implied (#1545)
๐ ๏ธ Bugfixes
- Replace magic error code 40 with thread-local CallError propagation (#1548)
๐๏ธ Maintenance
- Update GitHub Action dependencies to latest (#1540)
- Reorganize meta module, move parts to godot::private (#1546)
- Focused GDScript itests (#1547)
- Replace GodotNullableFfi with GodotNullableType (#1549)
- Follow Bash best practices in check.sh (#1553)
v0.5.0
_27 March 2026_
๐ป Features
- Typed dictionaries
- ๐ Typed Dictionary<K, V> (#1502)
- Engine APIs: accept AnyDict instead of VarDict; support future typed dicts (#1507)
- Typed dictionary iterators (#1516)
- Toolchain
- Godot 4.6 API level (#1484)
- Rust Edition 2024 (#1500)
- Allow to use other GDExtensions as dependencies (#1467)
- WebAssembly
- Godot-bindings: dispatch on target OS instead of host OS (also supports Wasm) (#1479)
- Wasm unit tests on CI (#1275)
- Engine APIs
- Add generic Gd::duplicate_node + Gd::duplicate_resource (#1492)
- Format bitfields in Debug impl (#1496)
- Access to ClassDB singleton in Core level (prepare for 4.7) (#1474)
- Update markdown to 1.0.0 (#1522)
- Class registration
- Add #[export_tool_button] (#1499)
- Enable Var (including PhantomVar) for engine enums (#1438)
- ๐ Var now supports #[var(pub)]; add SimpleVar to reuse existing Godot conversions (#1466)
- Shape metadata
- ๐ GodotShape refactor; open Element for enums (#1513)
- ๐ Integrate param/return metadata into GodotShape (#1534)
- Follow-ups around GodotShape + PropertyInfo (#1514)
๐ Performance
- Callable: restore name in disengaged mode, add caching (#1446)
- Remove Mutex from GdCellInner (#1442)
๐งน Quality of life
- Registration
- #[godot_api(secondary)] in other files (#1503)
- #[var] changes
- ๐ Make #[var(get, set)] orthogonal (#1454)
- Getters/setters now only accessible in Rust with #[var(pub)] (#1458)
- ๐ Add type-checking to #[var(get, set)] (#1469)
- Improve #[var(no_get)] UX (#1518)
- Typed array/dictionary API
- InnerArray: remove generic + unsafe methods in favor of AnyArray (#1506)
- ๐ Rename to Element/PackedElement, dictionary soundness (#1510)
- Remove AsVArg/DisjointVArg, use AsArg<Variant>; add array)Dictionary::{key,value}_element_type
- Add pre-4.4 polyfill for (#1515)Dictionary::default()
- Fix not setting type (#1536)dict!
- /array! macrosdict! { key => value }
- ๐ syntax, varray/vdict use AsArg<Variant> (#1523)iarray!
- Use + idict! instead of = syntax (#1530)run_deferred
- Engine APIs
- ๐ Heuristic to const-qualify Godot getters (#1497)
- Add and run_deferred_gd to DynGd (#1451)Rect2
- /Rect2i: rename from_corners() -> from_position_end() (#1463)Node::get_tree()
- ๐ returns non-null (#1493)GFile::read_as_gstring_entire()
- ๐ removes skip_cr parameter (#1494)ScriptInstance
- Simplify implementation (#1519)IObject
- Prefix callbacks with on_ (#1527)GDRUST_
- Error ergonomics
- Span improvements across many proc-macro APIs (#1457)
- Do not print twice on user panic (#1520)
- Toolchain
- All env vars now have prefix (#1521)api-4-*
- Check.sh: add logic to detect "SCRIPT ERROR" + memory leaks, like in CI (#1468)
- ๐ Limit features to minor versions (#1505)deprecated=no
- Deferred startup warn/error mechanism; detect builds (#1477).init_array
- Use to call constructors in WASM instead of JS snippet (#1476)--quiet
- Mute godot-rust preamble in the presence of (#1487)--no-header
- Mute godot-rust preamble in the presence of too (#1525)meta
- Module structure
- ๐ Reorganize + register modules (#1531)obj::signal
- MSRV, dependencies, module (#1537)arg()
- Deprecated symbol removal
- ๐ Remove deprecated symbols from v0.4 (#1459)
- ๐ Remove string method, update TODOs (#1526)NodePath::arg()
- ๐ Remove (#1539)unsafe
- Internal refactors
- Cleanups regarding (#1504)special_cases.rs
- minor refactor; don't generate default-params for private methods (#1482)
๐ ๏ธ Bugfixes
- Avoid #[cfg] in fn param -> generated #[doc(cfg(...))] invalid (#1449)OpenXrExtensionWrapper
- Godot API fixes
- Small Aabb cleanup (#1447)
- Aabb refactor/cleanup (#1461)
- Const-ness fixes in Godot virtual methods (#1456)
- Set proper initialization level for (#1445)IEditorSyntaxHighlighter::create
- Mark as required (#1453)MainLoop
- Testing and CI
- CI runs unit tests in minimal-codegen config, to catch doctest mistakes (#1455)
- Catch panics; make itest fail if init/deinit panics (#1473)instance
- Add regression test for auto-generated setters/getters to a field named (#1481)PropertyUsageFlags::INTERNAL
- Adjust test to Godot 4.7-dev: now used (#1495)
- Address unsoundness of typed signals after hot reload (#1512)
๐ Documentation
- TypedSignal: document different ways of connecting signals (#1443)ClassId::none/new_dynamic
- Expose , document PropertyInfo + MethodInfo (#1470)UserSingleton
- Misleading docs: must be registered before MainLoop stage (#1478)#[export_tool_button]
- Polish implementation (#1509)
v0.4.5
_12 December 2025_
Hotfix release: backports an update due to a breaking change in the Rust compiler.
๐ ๏ธ Bugfixes
- Fix compiler error caused by raw pointer cast no longer extending lifetimes (#1441)
v0.4.4
_4 December 2025_
๐ป Features
- Fix Vector2i using FFI; add functions to Vector3i/Vector4i (#1418)StringName::chars()
- Allow to register user-defined engine singletons (#1399)
- Add (#1419)
๐ Performance
- Fix Vector2i using FFI; add functions to Vector3i/Vector4i (#1418)
๐งน Quality of life
- Rename untyped collections to VarArray + VarDictionary (#1428)-e --headless
- Run integration tests in mode (#1432)
๐ ๏ธ Bugfixes
- Add special casing for PrimitiveMesh methods (#1430)
๐ Documentation
- Update comment to use to_cow_str() for class_id() (#1412)
v0.4.3
_26 November 2025_
๐ป Features
- Safeguard levels: fine-tune the amount of runtime validations (#1278)
- Support rename for #[var] (#1388)Array::functional_ops()
- Add (#1393)#[opt(default = ...)]
- Default parameters via syntax (#1396)
๐ Performance
- Only provide function name to CallContext in debug (#1331)
๐งน Quality of life
- Failed ptrcalls: instead of panic, print error + return default (#1387)
- #[bench(manual)] for more control, including setup (#1390)GodotImmutable
- Add to constrain #[opt(default)] types (#1406)runtime_version
- Update to use non-deprecated get_godot_version pointer (#1394)#[cfg(debug_assertions)]
- Start phasing out in favor of safeguards (#1395).ord()
- Remove macOS x86 (Intel) from CI (#1402)
- Remove unnecessary calls for enums/bitfields (#1414)experimental-required-objs
- Remove Cargo feature (#1416)
- Various small cleanups (#1386)
๐ ๏ธ Bugfixes
- Fix non-deterministic register-docs XML output (#1391)__are_oneditor_fields_initalized
- needs explicit usage of Singleton trait (#1400)max_align_t
- Blocklist from bindings generation (#1401)get_godot_version2
- Prevent procedural macro hygiene issue with eager macros (#1397)
- Fix unavailable on older builds (#1403)GString::find()
- Temporarily disable itest due to upstream bug (#1411)
v0.4.2
_26 October 2025_
๐ป Features
- Simple API to fetch autoloads (#1381)
- Experimental support for required parameters/returns in Godot APIs (#1383)
๐งน Quality of life
- ExtensionLibrary::on_main_loop_*: merge into new on_stage_init/deinit API (#1380)hash()
- Rename builtin -> hash_u32(); add tests (#1366)
๐ ๏ธ Bugfixes
- Backport Godot fix for incorrect Glyph native-struct (#1369)gd_self
- Validate call params for virtual methods (#1382)Array<Option<Gd>>
- Fix codegen regression: -> Array<Gd> (#1385)
v0.4.1
_23 October 2025_
๐ป Features
- Add main loop callbacks to ExtensionLibrary (#1313, #1380)#[godot_api(secondary)]
- Class Docs โ register docs in , simplify docs registration logic (#1355)
- Codegen: support sys types in engine APIs (#1363, #1365)
๐ Performance
- Use Rust str instead of CStr in ClassIdSource (#1334)
๐งน Quality of life
- Preserve doc comments for signal (#1353)
- Provide error context for typed array clone check (#1348)
- Improve spans; use tuple type for virtual signatures (#1370)
- Preserve span of arguments for better compile errors (#1373)
- Update to litrs 1.0 (#1377)
- Allow opening itests in editor (#1379)
๐ ๏ธ Bugfixes
- Ease AsArg<Option<Gd<T>>> bounds to make it usable with signals (#1371)auto_init
- Handle panic in OnReady (#1351)GFile::read_as_gstring_entire()
- Update after Godot removes skip_cr parameter (#1349)Callable::from_sync_fn
- Fix doc example using deprecated Result<T> return (#1347)#[class(no_init)]
- Deprecate for editor plugins (#1378).gdextension
- Initialize and cache proper return value for generic, typed array (#1357)
- Fix hot-reload crashes on macOS when the file changes (#1367)
v0.4.0
_29 September 2025_
๐ป Features
- Godot 4.5 API level (#1339)
- Allow to use #[func(gd_self)] with Interface methods (#1282)PackedArray<T>
- Generic (#1291)#[export]
- ๐ Numeric limits and type checks (#1320)ToGodot::Pass
- ๐ Argument passing: new is either ByValue/ByRef (#1285)POSTINITIALIZE
- ๐ More type-safe engine APIs (mostly int -> enum) (#1315)
- Emit notification after init() (#1211)TypedSignal::to_untyped()
- Add (#1288)Dictionary::get_or_insert()
- Add (#1295)ElementType
- Add ; expose it in arrays and dictionaries (#1304)singleton()
- Migrate inherent fn to new Singleton trait (#1325)
๐ Performance
- base() + base_mut() no longer clone Gd pointer (#1302)ToGodot
- Restore pass-by-ref for objects (#1310)StringName::from(&CStr)
- Remove static lifetime in (#1307)AsArg
- for objects now consistently passes by reference (#1314)ToGodot::Pass
- ๐ Argument passing: new is either ByValue/ByRef (#1285)From
- ๐ Remove by-value conversions between strings (#1286)
๐งน Quality of life
- ๐ Remove support for Godot 4.1 (#1292)
- MultiplayerApi: getters now use &self receiver rather than &mut self (#1274)ClassName
- construction from dynamic values (#1298)ClassCodegenLevel::Core
- Implement Send and Sync for PhantomVar (#1305)
- Add (#1289)AsObjectArg<T>
- ๐ Merge into AsArg<Gd<T>> (#1308)SignedRange
- ๐ Add for negative indices in range ops (#1300)clippy::nursery
- ๐ Require that classes starting with "Editor" be marked internal (#1272)
- Address lint errors in macros (#1317)AsArg
- FFI: make internals safer to use (#1321)AsArg
- now supports Option<DynGd> (#1323)ClassName
- Rename -> ClassId (#1322)apply_deferred()
- ๐ Split -> run_deferred() + run_deferred_gd() (#1327)StringName
- ๐ : remove From impl for &'static CStr (#1316)Callable::from_local_fn()
- ๐ now returns R: ToGodot (#1332)CallErrorType
- ๐ Add higher-level for script instance APIs (#1333)Callable::from_linked_fn
- ๐ Remove deprecated symbols, other small cleanups (#1340)
- ๐ now returns R: ToGodot instead of Variant (#1344)Callable
- : rename from_local_fn -> from_fn, keep deprecated from_local_fn with old signature (#1346)
๐ ๏ธ Bugfixes
- Fix ThreadConfined<T> using thread-unsafe Drop (#1283)#[rpc]
- Emit proper compile error when attribute is used in #[godot_api(secondary)] block (#1294)RenderingServer
- Drop_strong_ref โ make sure that given instance haven't been freed before dropping stored StrongRef (#1301)
- Improve init-level tests; fix singleton error (#1309)PassiveGd
- Remove lifetime from (#1312)std::mem::transmute
- Codegen excludes classes only on certain targets (#1338)
- Fix typo in causing UB while using AsArg<DynGd<Base, D>> (#1345)quote!
- Itest: work around clippy errors when generates one big line (#1336)
๐ Documentation
- ReadMe: update + code example (#1342)
v0.3.5
_18 August 2025_
๐ป Features
- Implement Gd::try_dynify (#1255)PhantomVar<T>
- Add to support properties without a backing field (#1261)
- Access to base pointer during initialization (#1273)
๐งน Quality of life
- match_class! fallback branch is now optional for () (#1246)match_class!
- now supports _ @ Class discard pattern (#1252)Gd
- Add bounds for future-proof deref (#1254)GString
- Mark as Send (#1260)reference
- Properly register GDExtension /unreference callbacks (#1270)
- Code style: stricter imports (#1269)
- Nightly rustfmt + internals (once-calls, robust refcounts) (#1271)
๐ ๏ธ Bugfixes
- Fix is_main_thread being gated behind #[cfg(not(wasm_nothreads))] despite being necessary to build wasm nothread (#1251)node_call_group
- Godot can use a different "main thread" for the main loop (#1253)
- Fix test accidentally renaming root tree (#1277)
๐ Documentation
- Add extra class docs for ResourceFormatLoader to mention that the experimental-threads feature is required (#1258)Packed*Array
- Clarify + test behavior w.r.t. copy-and-write + #[var] (#1268)
v0.3.4
_22 July 2025_
๐งน Quality of life
- Derive Hash for Rect2i and a few enums (#1241)#[export]
- Emit proper compile error while trying to Gd<T> or DynGd<T, D> (#1243)
๐ ๏ธ Bugfixes
- Re-export deprecated dict! macro (#1247)
v0.3.3
_21 July 2025_
๐ป Features
- match_class! macro to dispatch subclasses (#1225)match_class!
- Simplify syntax + implementation (#1237)mut
- Support bindings in match_class! (#1242)call_deferred
- Type-safe alternative (#1204)
- Access all enum/bitfield values programmatically (#1232)
๐งน Quality of life
- Start phasing out dict! macro in favor of vdict! (#1234)RawGd
- casting is now simpler and safer (#1226)Debug
- Improve impl for objects (#1227)GdRef<T>
- Verify that panic messages support UTF-8 (#1229)
- Clarify lifetimes: -> GdRef<'_, T> (#1238)
๐ Documentation
- Update editor plugin docs (#1233)
- Document how to use custom getters/setters with the OnEditor<T> (#1240)Export
- Clarify semantics for objects (#1244)
v0.3.2
_3 July 2025_
๐ป Features
- vslice)
- Disconnection of type-safe signals (#1198)
- Callables linked to objects; let Godot auto-disconnect signals (#1223)
๐งน Quality of life
- Implement Debug for OnEditor (#1189)
- Color: const constructors, add ALL_GODOT_COLORS constant (#1194)
- Deny manual init() if #[class(init|no_init)] is present (#1196)
- Relaxed Variant conversions (#1201)
- Allow custom types to be passed as impl AsArg<T> (#1193)
- Verify that marshalling errors cause failed GDScript function (#1203)
- Inline most string interpolations (cargo +nightly clippy --fix --workspace) (#1206)
- Work around breaking change in GDExtension API (VisualShader class) (#1210)
- Allow clippy::uninlined_format_args (Rust 1.88) (#1222)
๐ ๏ธ Bugfixes
- Fix inaccurate Color constants (#1195)
- Make hot-reload work with #[class(no_init)] (#1197)
- Wasm registration fn names now based on crate name + index (#1205)
- Fixed bug causing ConnectHandle::is_connected() to sometimes panic (#1212)
v0.3.1
_5 June 2025_
๐ป Features
- Support @export_file, @export_dir etc. for Array<GString> and PackedStringArray (#1166)
- Support @export_storage attribute (#1183)
- Implement XformInv<...> for Transform2D, Transform3D, Basis (#1082)
- Implement GString concatenation operator (#1117)
- Codegen from user-provided JSON via api-custom-json feature (#1124)
- String formatting: support padding, alignment and precision (#1161)
๐ Performance
- Switch from Option to ManuallyDrop for blocking guard inner type (#1176)
๐ ๏ธ Bugfixes
- Release CI: fix doc post-processing, add integration tests (#1187)
๐ Documentation
- Improve #[var] + #[export] docs (#1188)
- Clarify Node::duplicate() semantics on #[var] and #[export] fields (#1141)
v0.3.0
_31 May 2025_
See devlog article for highlights, and migration guide to update.
๐ป Features
- Godot 4.4 support (#1065)
- Type-safe signals
- ๐ User-defined signals (#1000)
- Explicit signal visibility (#1075)
- Type-safe signals for engine classes (#1111)
- Inherited typed signals (#1134)
- emit() now available on inherited symbols + smaller cleanups (#1135)
- User classes expose typed-signal API even without #[signal] (#1146)
- Generated emit() functions now take impl AsArg<T> (#1150)
- Simplify connect* usage (#1152)
- Clean up ConnectBuilder and some other signal APIs (#1171)
- ConnectBuilder::connect_*_gd() takes Gd instead of &mut Gd (#1175)
- Replace macro approach with indirect trait (#1179)
- Async/await
- Async Signals (#1043)
- Allow Gd<T> to be passed as a parameter in async signals (#1091)
- Prevent signal_future_send_arg_no_panic test from panicking (#1137)
- Itest runner must call on_finished deferred (#1095)
- Impl DynamicSend for Array<T> (#1122)
- Registration
- ๐ Add OnEditor<T>, remove impl<T> Export for Gd<T> and DynGd<T, D> (#1051, #1079)
- Add OnReady::from_loaded() + #[init(load = "PATH")] (#1083)
- Add support for @experimental and @deprecated attributes for user-generated docs (#1114)
- Builtin types
- Callables to builtin methods; Array::bsearch_by, sort_unstable_by (#1064)
- GString, StringName: add conversions from bytes and C-strings (#1062)
- Array, Dictionary: add into_read_only() + is_read_only() (#1096)
- Interface traits
- Virtual methods can become optional/required/removed in derived classes (#1136)
- ๐ Final and non-instantiable classes (#1162)
- ๐ Final classes no longer have a I* interface trait (#1182)
- Support f32 directly in process and physics_process (#1110)
๐ Performance
- Reduce number of classes in minimal codegen (#1099)
- Decrease CallError size from 176 to 8 bytes (#1167)
๐งน Quality of life
- Usability
- Propagate panics in object constructors to Gd::from_init_fn(), new_gd(), new_alloc() (#1140)
- ๐ Correct ConnectFlags classification (enum -> bitfield) (#1002)
- Bitfields now have |= operator (#1097)
- Panic handling: thread safety; set hook once and not repeatedly (#1037)
- Add diagnostic hints for missing ToGodot/FromGodot traits (#1084)
- bind/bind_mut borrow errors now print previous stacktrace (#1094)
- Make CollisionShapes ...debug_color methods available in Release builds (#1149)
- ๐ Add _rawptr suffix to all unsafe virtual functions (#1174)
- ๐ Remove deprecated symbols for v0.3 (#1160)
- Refactoring
- Experiment with splitting up signature differently (#1042)
- XML doc generation: code cleanup (#1077)
- GodotFfi::variant_type can be constant (#1090)
- Refactor parsing of #[godot_api] inner attributes (#1154)
- Adjust test to account for Node::set_name() change (String -> StringName) (#1153)
- Dependencies, project structure, tooling
- Move examples out of repository (#1085)
- Remove paste, simplify plugin macros (#1069)
- ๐ Bump MSRV from 1.80 to 1.87 (#1076, #1184)
- Validate that api-custom is run for Godot Debug binary (#1071)
- Centralize + update dependencies in workspace Cargo.toml (#1127)
- ๐ Reduce number of classes in minimal codegen (#1099)
- Post Rust 1.86 update: apply clippy lints (#1115)
- Move itest default feature codegen-full into build script (#1100)
๐ ๏ธ Bugfixes
- WebAssembly
- Wasm threading fixes (#1093)
- Remove gensym, fix Wasm class registration (#1092)
- Undo Wasm threading fix on panic context tracking (#1107)
- Editor integration
- Fix editor docs not generating when class itself is undocumented (#1089)
- Fix crash related to adding EditorPlugin to the editor before all the classes are registered (#1138)
- Misc
- ๐ Callable::from_local_static() now requires Godot 4.4+ (#1029)
- Masked enums can now be constructed from integers (#1106)
- Properly set GDExtensionBool is_valid to true in to_string function (#1145)
- Virtual dispatch: fix incorrect matching of renamed methods (#1173)
- Tooling workarounds
- Release job in minimal CI; temporarily work around Godot blocker (#1143)
- Work around OpenXR* APIs wrongly exposed in release; wider release checks in CI (#1070)
- Work around ResourceDeepDuplicateMode wrongly marked as an global enum in extension_api.json (#1180)
๐ Documentation
- Move builtin API design to __docs module (#1063)
- Regression test for checking if RustCallable is connected to signal (#1068)
- Describe semantics of base_mut() in docs (#1103)
- Document DynGd<_, D> type inference (#1142)
- #[derive(GodotClass)], #[godot_api] docs: replace table of contents with sidebar (#1155)
- Add rustc-args to package.metadata.docs.rs (#1169)
- Document runtime class in editor requirement (#1168)
- Improve signal/async docs (#1184)
v0.2.4
_24 February 2025_
๐ป Features
- Support additional doc comment markdown (#1017)
- Provide safe way for implementing IScriptExtension::instance_has (#1013)
- Global main thread ID (#1045)
- Add validate_property virtual func (#1030)
๐ Performance
- Speed up creating and extending packed arrays from iterators up to 63ร (#1023)
๐งน Quality of life
- Test generation of proc-macro code via declarative macro (#1008)
- Test: support switching API versions in check.sh (#1016)
- Support Variant::object_id() for Godot <4.4; add object_id_unchecked() (#1034)
- Rename Basis + Quaternion methods, closer to Godot (#1035)
- Compare scripts via object_id (#1036)
- Add Godot 4.3 to minimal CI (#1044)
- Add .uid files for GDScript + GDExtension resources; update script cache (#1050)
- Add #[allow(...)] directives to macro-generated entries (#1049)
- Clippy: disable excessive operator-precedence lint (#1055)
๐ ๏ธ Bugfixes
- Fix Variant -> Gd conversions not taking into account dead objects (#1033)
- Fix DynGd<T,D> export, implement proper export for Array<DynGd<T,D>> (#1056)
- In #[var]s, handle renamed #[func]s (#1019)
- ๐ #[signal]: validate that there is no function body (#1032)
- Disambiguate virtual method calls (#1020)
- Parse doc strings with litrs (#1015)
- Register-docs: don't duplicate brief in description (#1053)
- Move some compile-time validations from godot to godot-ffi (#1058)
- Clippy: fix "looks like a formatting argument but it is not part of a formatting macro" (#1041)
v0.2.3
_30 January 2025_
๐ป Features
- Map Vector2.Axis and Vector2i.Axis to Vector2Axis enum (#1012)
- Implement Var and Export for DynGd<T, D> (#998)
- Support associated types in #[godot_dyn] (#1022)
- Add Aabb::intersect_ray() (#1001)
- FFI: compatibility layer for virtual methods (#991, #1007)
- FFI: postinit create, icon paths (#991)
๐งน Quality of life
- Follow clippy 1.84; limit NodePath::subpath() polyfill again (#1010)
- Remove dead binding code regarding Godot 4.0 (#1014)
- API consistency for bounding boxes (#1001)
- Document and refactor PluginItem related stuff (#1003)
๐ ๏ธ Bugfixes
- Fix nightly compiler warnings about #[cfg(before_api = "4.3")] in the generated #[godot_api] impl (#995)
- Fix #[derive(Var)] generating incorrect hint_string for enums (#1011)
๐ Documentation
- Document + test limitations of Callable::from_local_static() (#1004)
- Document builtin API design (#999)
v0.2.2
_31 December 2024_
๐ป Features
- Feature parity with Godot builtin types
- Vector2i (#978)
- Projection (#983)
- Callable (#979)
- Quaternion (#981)
- GString + StringName (#980)
- NodePath (#982)
- PackedByteArray (#994)
- Support static functions in Callable (#989)
- Codegen can directly expose Inner* builtin methods (#976)
- Generate builtin methods with varargs (#977)
๐งน Quality of life
- More accurately provide spans to errors in the GodotClass macro (#920)
- Improve some proc-macro attribute error messages (#971)
- Add required virtual method IScriptInstance::get_doc_class_name() in test (#975)
- Clean up Callable + tests, fix check.sh test (#990)
๐ Documentation
- Improve docs in DynGd (re-enrichment) + Cargo features (#969)
v0.2.1
_8 December 2024_
๐ป Features
- #[godot_api(secondary)] for multiple impl blocks (#927)
- DynGd<T, D> smart pointer for Rust-side dynamic dispatch (#953, #958)
- Callable::from_local_fn() + Callable::from_sync_fn() (#965)
- Add Variant::object_id() (#914)
๐งน Quality of life
- #[gdextension] macro: rename entry_point -> entry_symbol and write docs (#959)
- Use GDExtensionCallableCustomInfo2 instead of deprecated GDExtensionCallableCustomInfo (#952)
- sys::short_type_name, conversions and relaxed GodotType (#957)
- Clippy (elided lifetimes) + rustfmt (#956)
- Add test verifying that custom callables don't crash when Err is returned (#950)
- Minor signal cleanup; prevent #[signal] from being used in secondary impl blocks (#964)
๐ ๏ธ Bugfixes
- Fix #[godot_dyn] causing error when implemented for two traits (#962)
- Prevent abort on double-panic if single-threading check fails (#965)
๐ Documentation
- #[gdextension] macro: rename entry_point -> entry_symbol and write docs (#959)
- Helpful doc aliases: func, var, init, .. (#960)
v0.2.0
_15 November 2024_
See devlog article for highlights.
๐ป Features
- Godot 4.3 support in CI and api-4-3 feature (#859)
- ๐ Drop support for Godot 4.0 (#820)
- ๐ Ergonomic arguments
- AsObjectArg trait enabling implicit conversions for object parameters (#800)
- Pass-by-ref for non-Copy builtins (#900, #906)
- String argument conversion + AsArg trait (#940)
- Callable is now passed by-ref (#944)
- Require AsObjectArg pass-by-ref, consistent with AsArg (#847, #947)
- Godot docs from RustDoc comments
- Generate documentation from doc comments (#748)
- Generate valid XML from doc comments (#861)
- Include register-docs feature in CI (#819)
- RPC attributes
- Add #[rpc] attribute to user-defined functions (#902)
- Registration APIs
- ๐ Add OnReady::node() + #[init(node = "...")] attribute (#807)
- Support Unicode class names (Godot 4.4+) (#891)
- Unicode support in ClassName::new_cached(); adjust test (#899)
- Derive Ord and PartialOrd for ClassName (#928)
- Implement Debug for InitState and OnReady (#879)
- Enums
- #[derive(GodotClass)] enums can now have complex ordinal expressions (#843)
- Enums can now be bit-combined with known masks (#857)
- Add as_str and godot_name to non-bitfield enums (#898)
- Required virtual functions
- Detect whether virtual functions are required to override (#904)
- ๐ Required virtual methods should be required at compile-time (#771)
- Conversions + operators
- Implement GodotConvert for Vec<T>, [T; N] and &[T] (#795)
- Implement From<&[char]> for GString (#862)
- Add From<[Elem; N]> for Packed Array and Optimize From<Vec<Elem>> (#827)
- Handle typed array metadata (#855)
- Vector conversion functions (#824)
- Add Mul operator for Quaternion + Vector3 (#894)
๐ Performance
- RawGd: cache pointer to internal storage (#831)
- ClassName now dynamic and faster (#834)
- Pass-by-ref for non-Copy builtins (backend) (#906)
๐งน Quality of life
- Renames and removals
- ๐ Remove deprecated symbols from before v0.1 (#808)
- Deprecate instance utilities in godot::global (#901)
- Shorten #[init(default = ...)] to #[init(val = ...)] (#844)
- #[class] attribute: rename hidden -> internal, deprecate editor_plugin (#884)
- Cleanup around godot::meta argument conversions (#948)
- Remove to_2d() + to_3d(); clean up ApiParam (#943)
- ๐ Simplify property hint APIs (#838)
- Validation
- Fix validation for api-* mutual exclusivity (#809)
- Validate that virtual extension classes require #[class(tool)] (#850)
- Validate that editor plugin classes require #[class(tool)] (#852)
- Best-effort checks for Array<Integer> conversions; fix Debug for variants containing typed arrays (#853)
- ๐ Disallow Export if class doesn't inherit Node or Resource (#839)
- ๐ Validate that Nodes can only be exported from Node-derived classes (#841)
- CI and tooling
- Cargo-deny maintenance: update to advisories/licenses v2 (#829)
- CI runner updates (#941)
- Skip notify-docs job when running in a fork (#945)
- Allow manually triggering full-ci workflow (mostly useful for forks) (#933)
- Code generation and Godot APIs
- Allow codegen for UniformSetCacheRD for Godot >=4.3 (#816)
- Enable ResourceLoader::load_threaded_* with experimental-threads (#856)
- Dependency update, more tests for vector angle functions (#860)
- Upstream follow-up
- ๐ Support GDExtensionScriptInstanceInfo3 in 4.3 (#849)
- Support meta char16 and char32 (#895)
- Add GodotConvert impl for *const u8 pointers (#866)
- Update list of experimental classes (#897)
- Update hint_string tests to account for Godot 4.4 floats with .0 formatting (#936)
- Panics
- Disable panic hooks in Release mode (#889)
- In debug, include location information in error message on panic (#926)
- Refactoring
- Rewrite #[var] + #[export] registration to use type-safe API behind scenes (#840)
- Get rid of placeholder names like "foo" (#888)
๐ ๏ธ Bugfixes
- Argument passing
- Set null into Godot Engint APIs nullable parameters as default (#823)
- Fix Ex* builder parameters: ObjectArg<T> -> impl AsObjectArg<T> (#830)
- Godot doc generation from RustDoc
- Fix doc comments not showing up if only some class members are documented (#815)
- Fix register-docs feature not being tested (#942)
- Registration
- Fix Array<T> registered without element type (#836)
- Virtual methods now take Option<Gd<T>> (unless whitelisted) (#883)
- Make arrays exportable only when their inner type is exportable (#875)
- Display script-virtual methods as _method instead of method in Godot docs (#918)
- Implement the safe_ident strategy for virtual call parameter identifier generation (#822)
- FFI and memory safety
- Fix user-after-free in AsObjectArg pass-by-value (in default-param methods) (#846)
- RawGd::move_return_ptr with PtrcallType::Virtual leaks reference (#848)
- Don't abort on panic inside Callable (#873)
- Tooling and dependencies
- Dev-dependencies are enabling full codegen (#842)
- OpenXR is not available on Web (#872)
- Fix enum_test.rs accidentally excluded from itest (#931)
- Codegen-rustfmt: use 2021 edition (#937)
- Math
- Vecor3::sign() gives incorrect results due to i32 conversion (#865)
๐ Documentation
- Builtin docs (impl blocks, navigation table, link to Godot) (#821)
- Add docs for #[rpc] (#949)
- Overview about type conversions (#833)
- Document godot::meta argument conversions (#948)
- Add a doc to point users to kwarg builders (#876)
- Resolve doc warning with global enums (#896)
- ReadMe update + clippy error (#929)
v0.1.3
_22 July 2024_
๐งน Quality of life
- Add helpful error for renamed Wasm module (#799)
- More thoroughly document unsafe in godot-ffi (#774)
๐ ๏ธ Bugfixes
- Map Vector3i.Axis enum to builtin Vector3Axis (#797)
- Prevent out! from actually formatting the input if disabled (#801)
- Disable main_thread_id assertion for Android debug build (#780)
- GdCell::borrow_mut should block on main thread if shared ref exists (#787)
๐ Documentation
- Typos + code reordering (#802)
- Add crates.io ReadMe + docs logo (#804)
v0.1.2
_15 July 2024_
๐ป Features
- Add more normalized functions (#761)
- Add conversion from Vec<$Element> to $PackedArray types (#785)
- Add snapped to integer vectors (#768)
- Add determinant to Transform2D (#770)
- Support #[export(range = (radians_as_degrees, suffix=XX))] (#783)
- Add support for nothreads Wasm builds (Godot 4.3+) (#794)
๐งน Quality of life
- Reorder compile errors for #[derive(GodotClass)] (#773)
- Change Global to use Once (#752)
- Prevent global CallError tracker from growing indefinitely (#798)
๐ ๏ธ Bugfixes
- Change logic to disable OpenXR for iOS (#781)
- Pointer is already *const u32 on aarch64 (#788)
- Handle panics in virtual interface methods (#757)
๐ Documentation
- Document why Basis columns are a, b, and c (#776)
v0.1.1
_24 June 2024_
Initial release on crates.io. See devlog article.
---
Contributing
Contributing to godot-rust
We appreciate if users experiment with the library, use it in small projects and report issues they encounter.
If you intend to contribute code, please read the section _Pull request guidelines_ below, so you spend less time on administrative tasks.
The rest of the document goes into tools and infrastructure available for development.
Pull request guidelines
๐ Larger changes need design
If you plan to make bigger contributions, make sure to discuss them in a [GitHub issue] before opening a pull request (PR).
Since the library is evolving quickly, this avoids that multiple people work on the same thing, or that features don't integrate well,
causing a lot of rework. Also don't hesitate to talk to the developers in the #contrib-gdext channel on [Discord]!
๐งฎ One commit per logical change
Commits as logical units make it easier to review changes. In the future, they allow to reconstruct what happened when and --
in case of regressions -- revert individual changes. The exception are tiny changes of a few lines that don't bear semantic significance
(typos, style, etc.). Larger code style changes should be split though (possibly even in individual pull requests).
Since we use GitHub merge queues, we can unfortunately not use GitHub's "Squash & Merge" feature.
If your pull request changes a single logical change, please squash the commits into one. This is quite simple:
git reset --soft master # keeps current changes, but moves HEAD
git commit -am "Descriptive commit message"
git push --force-with-lease # updates PR branch to this 1 new commitAvoid commits like "integrate review feedback" or "fix rustfmt". If you have multiple commits, use git commit --amend or git rebase -i
and force-push follow-up commits to your branch (--force-with-lease is safer than -f or --force).
โ๏ธ Draft PRs
If you plan to work on a feature/bugfix for a longer time, consider opening a PR as a draft.
This signals that reviews are appreciated, but that the code is not yet ready for merge.
Non-draft PRs that pass CI are assumed to be mergeable (and maintainers may do so).
If you have to abandon a pull request you started, that's totally fine -- but please communicate this,
so that it doesn't stay in limbo. Maybe someone else can step up to finish it :)
๐ค AI policy
If you use AI assistants or agents, it is your responsibility to:
- Carefully review and adjust the code before submitting a pull request.
- Understand 100% of the submitted code and be able to explain it in your own words. Do not generate the PR description with AI.
- Uphold any copyrights and licenses. For involved algorithms, do research to properly credit (or directly use) sources.
The section _Larger changes need design_ is even more important here. Dropping big amounts of code without a clear approach
can result in your PR being closed with zero reviews.
Development tools
Further information for contributors, such as tools supporting you in local development, is available in the [godot-rust book].
The book also elaborates design principles and conventions behind our API.
[GitHub issue]: https://github.com/godot-rust/gdext/issues
[Discord]: https://discord.gg/aKUCJ8rJsc
[godot-rust book]: https://godot-rust.github.io/book/contribute
---
ReadMe
Rust bindings for Godot 4
_[Website] | [Book][book] | [API Docs] | [Discord] | [BlueSky] | [Mastodon] | [Twitter] | [Sponsor]_
godot-rust is a library to integrate the Rust language with Godot 4.
[Godot] is an open-source game engine, focusing on a productive and batteries-included 2D and 3D experience.
Its _GDExtension_ API allows integrating third-party languages and libraries.
Philosophy
The Rust binding is an alternative to GDScript, with a focus on type safety, scalability and performance.
The two languages can be mixed in a project, and your custom Rust APIs can be called type-safely from GDScript.
The primary goal of godot-rust is to provide a [pragmatic Rust API][philosophy] for game developers.
Recurring workflows should be simple and require minimal boilerplate. APIs are designed to be safe and idiomatic Rust wherever possible.
Due to interacting with Godot as a C++ engine, we sometimes follow unconventional approaches to provide a good user experience.
Motivating example
The following Rust snippet registers a Godot class Player, showcasing features such as inheritance, field initialization and signals.
/ Detailed source-code truncated for AI context efficiency. /Development status
The library has evolved a lot since 2023 and is now in a usable state for projects such as games, editor plugins, tools and other applications
based on Godot. See [ecosystem] to get an idea of what users have built with godot-rust.
Keep in mind that we occasionally introduce breaking changes, motivated by improved user experience or upstream changes. These are usually
minor and accompanied by migration guides. Our [crates.io releases][crates-io] adhere to SemVer, but lag a bit behind the master branch.
See also [API stability] in the book.
The vast majority of Godot APIs have been mapped to Rust. The current development focus lies on a more natural Rust experience, to enable
design patterns that come in handy for day-to-day game development. To counter bugs, we use an elaborate CI suite including clippy, unit tests,
engine integration tests and memory sanitizers. Even hot-reload is tested!
At the moment, there is experimental support for [Wasm], [Android] and [iOS], but documentation and tooling is still lacking.
Contributions are very welcome!
Getting started
The best place to start is [the godot-rust book][book]. Use it in conjunction with our [API Docs].
We also provide practical examples and small games in the [demo-projects] repository.
If you need help, join our [Discord] server and ask in the #help channel!
License
We use the [Mozilla Public License 2.0][mpl]. MPL tries to find a balance between permissive (MIT, Apache, Zlib) and copyleft licenses (GPL, LGPL).
The license provides a lot of freedom: you can use the library commercially and keep your own code closed-source,
i.e. game development is not restricted. The main condition is that if you change godot-rust _itself_, you need to make
those changes available (and only those, no surrounding code).
Contributing
Contributions are very welcome! If you want to help out, see Contributing.md for some pointers on getting started.
[API Docs]: https://godot-rust.github.io/docs/gdext
[API stability]: https://godot-rust.github.io/book/toolchain/compatibility.html#rust-api-stability
[Android]: https://github.com/godot-rust/gdext/issues/470
[Discord]: https://discord.gg/aKUCJ8rJsc
[Godot]: https://godotengine.org
[BlueSky]: https://bsky.app/profile/godot-rust.bsky.social
[Mastodon]: https://mastodon.gamedev.place/@GodotRust
[Sponsor]: https://github.com/sponsors/Bromeon
[Twitter]: https://twitter.com/GodotRust
[WASM]: https://godot-rust.github.io/book/toolchain/export-web.html
[Website]: https://godot-rust.github.io
[gdnative]: https://github.com/godot-rust/gdnative
[book]: https://godot-rust.github.io/book
[ecosystem]: https://godot-rust.github.io/book/ecosystem
[demo-projects]: https://github.com/godot-rust/demo-projects
[iOS]: https://github.com/godot-rust/gdext/issues/498
[mpl]: https://www.mozilla.org/en-US/MPL
[philosophy]: https://godot-rust.github.io/book/contribute/philosophy.html
[crates-io]: https://crates.io/crates/godot
---