Skip to content

Commit 8841ed6

Browse files
authored
Merge pull request #1342 from godot-rust/qol/readme
ReadMe: update + code example
2 parents 813af32 + 17b2f99 commit 8841ed6

File tree

3 files changed

+113
-43
lines changed

3 files changed

+113
-43
lines changed

ReadMe.md

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,108 @@
1-
![logo.png](misc/assets/gdext-ferris.png)
1+
![logo.png](misc/assets/godot-rust-ferris.png)
22

33
# Rust bindings for Godot 4
44

5-
_**[Website]** | **[Book][book]** | **[API Docs]** | [Discord] | [Mastodon] | [Twitter] | [Sponsor]_
5+
_**[Website]** | **[Book][book]** | **[API Docs]** | [Discord] | [BlueSky] | [Mastodon] | [Twitter] | [Sponsor]_
66

7-
**gdext** is a library to integrate the Rust language with Godot 4.
7+
**godot-rust** is a library to integrate the Rust language with Godot 4.
88

99
[Godot] is an open-source game engine, focusing on a productive and batteries-included 2D and 3D experience.
1010
Its _GDExtension_ API allows integrating third-party languages and libraries.
1111

12-
Rust bindings for Godot 3 (GDNative API) are available in [`gdnative`].
13-
1412

1513
## Philosophy
1614

1715
The Rust binding is an alternative to GDScript, with a focus on type safety, scalability and performance.
1816

19-
The primary goal of gdext is to provide a [**pragmatic Rust API**][philosophy] for game developers.
17+
The primary goal of godot-rust is to provide a [**pragmatic Rust API**][philosophy] for game developers.
2018

2119
Recurring workflows should be simple and require minimal boilerplate. APIs are designed to be safe and idiomatic Rust wherever possible.
2220
Due to interacting with Godot as a C++ engine, we sometimes follow unconventional approaches to provide a good user experience.
2321

2422

25-
## Development status
26-
27-
The gdext library has evolved a lot during 2023 and 2024 and is now in a usable state for smaller projects.
28-
However, there are still certain things to keep in mind.
23+
## Motivating example
24+
25+
The following Rust snippet registers a Godot class `Player`, showcasing features such as inheritance, field initialization and signals.
26+
27+
```rust
28+
use godot::classes::{ISprite2D, ProgressBar, Sprite2D};
29+
use godot::prelude::*;
30+
31+
// Declare the Player class inheriting Sprite2D.
32+
#[derive(GodotClass)]
33+
#[class(init, base=Sprite2D)] // Automatic initialization, no manual init() needed.
34+
struct Player {
35+
// Inheritance via composition: access to Sprite2D methods.
36+
base: Base<Sprite2D>,
37+
38+
// #[class(init)] above allows attribute-initialization of fields.
39+
#[init(val = 100)]
40+
hitpoints: i32,
41+
42+
// Access to a child node, auto-initialized when _ready() is called.
43+
#[init(node = "Ui/HealthBar")] // <- Path to the node in the scene tree.
44+
health_bar: OnReady<Gd<ProgressBar>>,
45+
}
46+
47+
// Implement Godot's virtual methods via predefined trait.
48+
#[godot_api]
49+
impl ISprite2D for Player {
50+
// Override the `_ready` method.
51+
fn ready(&mut self) {
52+
godot_print!("Player ready!");
53+
54+
// Health bar is already initialized and straightforward to access.
55+
self.health_bar.set_max(self.hitpoints as f64);
56+
self.health_bar.set_value(self.hitpoints as f64);
57+
58+
// Connect type-safe signal: print whenever the health bar is updated.
59+
self.health_bar.signals().value_changed().connect(|hp| {
60+
godot_print!("Health changed to: {hp}");
61+
});
62+
}
63+
}
64+
65+
// Implement custom methods that can be called from GDScript.
66+
#[godot_api]
67+
impl Player {
68+
#[func]
69+
fn take_damage(&mut self, damage: i32) {
70+
self.hitpoints -= damage;
71+
godot_print!("Player hit! HP left: {}", self.hitpoints);
72+
73+
// Update health bar.
74+
self.health_bar.set_value(self.hitpoints as f64);
75+
76+
// Call Node methods on self, via mutable base access.
77+
if self.hitpoints <= 0 {
78+
self.base_mut().queue_free();
79+
}
80+
}
81+
}
82+
```
2983

30-
> [!WARNING]
31-
> The public API introduces breaking changes from time to time, primarily motivated by new features and improved ergonomics.
32-
> Our [crates.io releases][crates-io] adhere to SemVer, but may lag behind the `master` branch. See also [API stability] in the book.
3384

34-
**Features:** Most Godot APIs have been mapped at this point. The current focus lies on a more natural Rust experience and enable more design
35-
patterns that come in handy for day-to-day game development. See [#24] for an up-to-date feature overview.
85+
## Development status
3686

37-
At the moment, there is experimental support for [Wasm], [Android] and [iOS], but documentation and tooling is still lacking. Contributions are very welcome!
87+
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
88+
based on Godot. See [ecosystem] to get an idea of what users have built with godot-rust.
3889

39-
**Bugs:** Most undefined behavior related to the FFI layer has been ironed out, but there may still be occasional safety issues. Apart from that,
40-
new additions to the library are typically not feature-complete from the start, but become more robust with feedback and testing over time.
41-
To counter bugs, we have an elaborate CI suite including clippy, unit tests, engine integration tests and memory sanitizers. Even hot-reload is tested!
90+
Keep in mind that we occasionally introduce breaking changes, motivated by improved user experience or upstream changes. These are usually
91+
minor and accompanied by migration guides. Our [crates.io releases][crates-io] adhere to SemVer, but lag a bit behind the `master` branch.
92+
See also [API stability] in the book.
4293

94+
The vast majority of Godot APIs have been mapped to Rust. The current focus lies on a more natural Rust experience and enable more design
95+
patterns that come in handy for day-to-day game development. To counter bugs, we use an elaborate CI suite including clippy, unit tests,
96+
engine integration tests and memory sanitizers. Even hot-reload is tested!
4397

44-
## Getting started
98+
At the moment, there is experimental support for [Wasm], [Android] and [iOS], but documentation and tooling is still lacking.
99+
Contributions are very welcome!
45100

46-
To dive into Rust development with gdext, check out [the godot-rust book][book]. The book is still under construction,
47-
but already covers a _Hello World_ setup as well as several more in-depth chapters.
48101

49-
To consult the API reference, have a look at the online [API Docs].
102+
## Getting started
50103

51-
Furthermore, we provide some practical examples and small games in the [demo-projects] repository.
104+
The best place to start is [the godot-rust book][book]. Use it in conjunction with our [API Docs].
105+
We also provide practical examples and small games in the [demo-projects] repository.
52106

53107
If you need help, join our [Discord] server and ask in the `#help` channel!
54108

@@ -58,29 +112,30 @@ If you need help, join our [Discord] server and ask in the `#help` channel!
58112
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).
59113

60114
The license provides a lot of freedom: you can use the library commercially and keep your own code closed-source,
61-
i.e. game development is not restricted. The main condition is that if you change gdext _itself_, you need to make
115+
i.e. game development is not restricted. The main condition is that if you change godot-rust _itself_, you need to make
62116
those changes available (and only those, no surrounding code).
63117

64118

65119
## Contributing
66120

67121
Contributions are very welcome! If you want to help out, see [`Contributing.md`](Contributing.md) for some pointers on getting started.
68122

69-
[#24]: https://github.com/godot-rust/gdext/issues/24
70123
[API Docs]: https://godot-rust.github.io/docs/gdext
71124
[API stability]: https://godot-rust.github.io/book/toolchain/compatibility.html#rust-api-stability
72125
[Android]: https://github.com/godot-rust/gdext/issues/470
73126
[Discord]: https://discord.gg/aKUCJ8rJsc
74127
[Godot]: https://godotengine.org
128+
[BlueSky]: https://bsky.app/profile/godot-rust.bsky.social
75129
[Mastodon]: https://mastodon.gamedev.place/@GodotRust
76130
[Sponsor]: https://github.com/sponsors/Bromeon
77131
[Twitter]: https://twitter.com/GodotRust
78132
[WASM]: https://godot-rust.github.io/book/toolchain/export-web.html
79133
[Website]: https://godot-rust.github.io
80134
[`gdnative`]: https://github.com/godot-rust/gdnative
81135
[book]: https://godot-rust.github.io/book
136+
[ecosystem]: https://godot-rust.github.io/book/ecosystem
82137
[demo-projects]: https://github.com/godot-rust/demo-projects
83138
[iOS]: https://github.com/godot-rust/gdext/issues/498
84139
[mpl]: https://www.mozilla.org/en-US/MPL
85140
[philosophy]: https://godot-rust.github.io/book/contribute/philosophy.html
86-
[crates-io]: https://crates.io/crates/godot
141+
[crates-io]: https://crates.io/crates/godot

godot/crate-readme.md

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
# Rust bindings for Godot 4
44

5-
_**[Website]** | **[GitHub]** | **[Book]** | **[API Docs]** | [Discord] | [Mastodon] | [Twitter] | [Sponsor]_
5+
_**[Website]** | **[GitHub]** | **[Book]** | **[API Docs]**_
6+
_[Discord] | [BlueSky] | [Mastodon] | [Twitter] | [Sponsor]_
67

78
The **godot** crate integrates the Rust language with Godot 4.
89

9-
[Godot] is an open-source game engine, focusing on a productive and batteries-included 2D and 3D experience.
10+
[Godot] is an open-source game engine, focusing on a productive and batteries-included 2D and 3D experience.
1011
Its _GDExtension_ API allows integrating third-party languages and libraries.
1112

1213

@@ -21,39 +22,43 @@ Due to interacting with Godot as a C++ engine, we sometimes follow unconventiona
2122

2223
## Example
2324

24-
The following code snippet demonstrates writing a simple Godot class `Player` in Rust.
25+
The following Rust snippet registers a Godot class `Player`, showcasing features such as inheritance, field initialization and signals.
2526

2627
```rust
28+
use godot::classes::{ISprite2D, ProgressBar, Sprite2D};
2729
use godot::prelude::*;
28-
use godot::classes::{ISprite2D, Sprite2D};
2930

3031
// Declare the Player class inheriting Sprite2D.
3132
#[derive(GodotClass)]
32-
#[class(base=Sprite2D)]
33+
#[class(init, base=Sprite2D)] // Automatic initialization, no manual init() needed.
3334
struct Player {
3435
// Inheritance via composition: access to Sprite2D methods.
3536
base: Base<Sprite2D>,
3637

37-
// Other fields.
38-
velocity: Vector2,
38+
// #[class(init)] above allows attribute-initialization of fields.
39+
#[init(val = 100)]
3940
hitpoints: i32,
41+
42+
// Access to a child node, auto-initialized when _ready() is called.
43+
#[init(node = "Ui/HealthBar")] // <- Path to the node in the scene tree.
44+
health_bar: OnReady<Gd<ProgressBar>>,
4045
}
4146

4247
// Implement Godot's virtual methods via predefined trait.
4348
#[godot_api]
4449
impl ISprite2D for Player {
45-
// Default constructor (base object is passed in).
46-
fn init(base: Base<Sprite2D>) -> Self {
47-
Player {
48-
base,
49-
velocity: Vector2::ZERO,
50-
hitpoints: 100,
51-
}
52-
}
53-
5450
// Override the `_ready` method.
5551
fn ready(&mut self) {
5652
godot_print!("Player ready!");
53+
54+
// Health bar is already initialized and straightforward to access.
55+
self.health_bar.set_max(self.hitpoints as f64);
56+
self.health_bar.set_value(self.hitpoints as f64);
57+
58+
// Connect type-safe signal: print whenever the health bar is updated.
59+
self.health_bar.signals().value_changed().connect(|hp| {
60+
godot_print!("Health changed to: {hp}");
61+
});
5762
}
5863
}
5964

@@ -64,10 +69,19 @@ impl Player {
6469
fn take_damage(&mut self, damage: i32) {
6570
self.hitpoints -= damage;
6671
godot_print!("Player hit! HP left: {}", self.hitpoints);
72+
73+
// Update health bar.
74+
self.health_bar.set_value(self.hitpoints as f64);
75+
76+
// Call Node methods on self, via mutable base access.
77+
if self.hitpoints <= 0 {
78+
self.base_mut().queue_free();
79+
}
6780
}
6881
}
6982
```
7083

84+
7185
## More
7286

7387
For more information, check out our [Website] or [GitHub] page!
@@ -79,6 +93,7 @@ For more information, check out our [Website] or [GitHub] page!
7993
[GitHub]: https://github.com/godot-rust/gdext
8094
[Godot]: https://godotengine.org
8195
[Mastodon]: https://mastodon.gamedev.place/@GodotRust
96+
[BlueSky]: https://bsky.app/profile/godot-rust.bsky.social
8297
[philosophy]: https://godot-rust.github.io/book/contribute/philosophy.html
8398
[Sponsor]: https://github.com/sponsors/Bromeon
8499
[Twitter]: https://twitter.com/GodotRust
File renamed without changes.

0 commit comments

Comments
 (0)