godot-rust / gdnative-book

The user guide for godot-rust.
https://godot-rust.github.io/book
MIT License
64 stars 42 forks source link

[tracker] The godot-rust Book #1

Open ghost opened 4 years ago

ghost commented 4 years ago

Over time, the godot-rust library grows, and the intricacies of the project can no longer fit in a simple README file. While there is the API documentation, it is very technical and hard to navigate for new users. The presence of multiple community-written "getting started" tutorials is evidence that the learning curve is problematic and we really need an expanded user guide.

Topics that should be covered

Contributing to the book

Since the book is still a very early work-in-progress and mostly blank, please leave a comment here before going ahead to write a section, to avoid duplication of work. PRs for the book should be made against the book branch, instead of master.

If there are other topics that you think should be covered in the book, please feel free to suggest them in the comments here.


Supersedes godot-rust/godot-rust#209.

tommywalkie commented 4 years ago

Very interested to the godot-rust book project ! I mostly agree with the mentionned Topics that should be covered, I'll just list a few things that comes first to my mind about explaining the whole thing if i had to do it all again :

  1. Installing Godot Engine.
  2. Creating a basic Godot project.
  3. Making sure the reader understands what are Nodes and Scenes, which are fundamental concepts in Godot, the idea is to make everyone start from the same minimal knowledge basis and not rush official Godot docs.
  4. Installing rustup.
  5. Understanding the Rust toolchains we may / may not need
    # Borrowed from 'mozilla/rust-android-gradle'
    rustup target add armv7-linux-androideabi   # for arm
    rustup target add i686-linux-android        # for x86
    rustup target add aarch64-linux-android     # for arm64
    rustup target add x86_64-linux-android      # for x86_64
    rustup target add x86_64-unknown-linux-gnu  # for linux-x86-64
    rustup target add x86_64-apple-darwin       # for darwin (macOS)
    rustup target add x86_64-pc-windows-gnu     # for win32-x86-64-gnu
    rustup target add x86_64-pc-windows-msvc    # for win32-x86-64-msvc
  6. (bis) Understanding MSVC vs GNU for Windows users and what they need to install.
  7. Building a GDNative/Rust library example.

It doesn't need to be something too complicated or too simple but once there, the reader may understand when he wants a Button for example, he can get some API documentation on docs.godotengine.org and translate his knowledge into the doc.rs one, while also knowing he can use some methods and properties in BaseButton, Control, CanvasItem, etc. because Button inherits from X.

  1. Linking the Godot scene to the GDNative/Rust libraries we built.

At this point, the reader should be able to understand what is going on here. diagram

Assuming yes, we can start talking about exporting (and the purpose of export_presets.cfg) and more specific topics in GDNative/Rust like handling signals, interacting with assets and Instance downcasting.

ghost commented 4 years ago

@tommywalkie I agree that a quick refresher of Godot's Scene/Node architecture can be useful here for convenience. Added to the topic list! Also clarified a bit about the tutorial: it should include instructions for installing dependencies, of course. MSVC vs GNU for Windows is also a good point that I missed. Thanks for the suggestions!

steelx commented 4 years ago

Hi, I'm not sure if its practical request. I'm new to Rust, But i have been following this tutorial with amethyst it is very good. Can you maybe write the same in Godot-Rust ? https://bfnightly.bracketproductions.com/rustbook/

ghost commented 4 years ago

Hi @steelx!

Thanks for asking! This documentation effort is, first and foremost, focused on the usage of this binding library. For the limited contributor time available to us, this means that we cannot afford to spare long chapters on complex game mechanic, which is not really related to this library. In short, while the book will contain a guided tour, I don't think a "full game" tutorial would fit in our scope.

As an aside, the GDNative bindings are orthogonal to how your game logic is implemented. It's completely possible to use a Rust ECS like Specs or Legion alongside Godot: I'm aware of several users that do this. You can still make use of the tutorial that you've linked!

paytonrules commented 4 years ago

If you're looking for topics to cover - you've already mentioned Instance but perhaps more specifically when to use Instance vs node.cast. I've been porting a small tutorial project to Rust and that's one of the issues I've had so far, and frankly I'm not sure I'm using it correctly.

ghost commented 4 years ago

Some recent issues are caused by users not using standalone .gdnlib files as specified in the official C/C++ examples. Similar instructions should be added to the book since we should not assume that users would have already read the C/C++ docs.

tommywalkie commented 4 years ago

On a side note, some recent studies in https://github.com/tommywalkie/sample-godot-rust-app/issues/17 could lead to a possible successful iOS build/export.

TL;DR : The catch here is I need to enroll into Apple Developer Program (99 USD/yr, it apparently has a free tier, but it still requires a registered Apple trusted device) to get a required Apple Team ID and be able to certify the setup.

Filius-Patris commented 4 years ago

Testing code that depends on the engine ("Godot tests")

Is there a recommended method? Or is this also WIP in the code?

ghost commented 4 years ago

@tommywalkie I don't think the article says you need a device to run apps on the emulator? Obviously you'll need to physically own an actual device to run build on it, though, and that device needs to be registered to your Apple Developer ID. I'm not sure if I can be of any help here, sadly.

@Filius-Patris In the repo we have our tests in the test directory. It's a bit complicated to set up currently, but basically you create a project and write some GDScript to invoke the test code. It's not the most ideal solution, I'll admit. Something like inventory or linkme might be useful if we want to simplify setup in the future, but there is no work done on that yet.

tommywalkie commented 4 years ago

@toasteater I left the article link mainly for the “free tier” subject through.

Filius-Patris commented 4 years ago

Currently there's getting-started.md and introduction.md, as well as the getting-started subdir.

What's the purpose of each of them? I just figured I might start writing instructions on how to set up Godot + rust, since I already managed to do it.

ghost commented 4 years ago

@tommywalkie I see. Still, I don't really think I'm able to do anything here. I also don't have an Apple Developer subscription. Sorry.

@Filius-Patris introduction.md is intended to be an introduction to the book, which I'm planning to write myself. getting-started.md is intended to be an introduction to the "getting started" tutorial mentioned in OP. The actual tutorial goes into the getting-started directory. Instructions on how to set up, specifically, belongs in getting-started/setup.md. If you want to make a PR for that chapter, feel free to go ahead! You're also encouraged to be inspired by the Setup section of @tommywalkie's sample-godot-rust-app guide, which I find very detailed and got his permission to reprint. Just remember to make it against the book branch!

ntswamp commented 4 years ago

the basic and easiest way: 6E17A5CA-C618-4514-ACE4-D4F595E2A060

tommywalkie commented 4 years ago

@milkvolleyball I don't think this will be adequate. GDScript and C# are primarily supported by Godot. GDNative integrations are community projects (iirc). Plus, the official Godot docs would need to detail any Python/Kotlin/D/Rust/C++/etc. requirements and build steps, this will become heavy.

halzy commented 4 years ago

Perhaps a note in the docs about using the consts instead of enums?

ghost commented 4 years ago

@halzy But there will be no enums after godot-rust/godot-rust#424?

halzy commented 4 years ago

@toasteater For people coming from the Godot docs. They may look for enums that don't exist.

ghost commented 4 years ago

I see. Makes sense.

paytonrules commented 4 years ago

As the book is in progress it could really use more explanation and examples around Ref/TRef and assume_safe and all it's variations. I'll give an example for clarification:

I'm moving my 0.8 code over to 0.9, and as part of my code I had a struct that held an Optional sprite, that's been changed to fit:

pub struct Enemy {
    sprite: Option<Ref<Sprite>>,
...
}

When I create the sprite I give it a name and assign it a texture at random from the resources. Unfortunately the entire function is still unsafe. At this time I create a mutable shared ref, and assume it's safe. After setting the texture I add the child, and then after it's added I save a reference - making sure to claim it. This compiles, huzzah, but I'm 99% sure it's wrong.

    #[export]
    unsafe fn _enter_tree(&mut self, owner: &Node2D) {
        /* ...  */ 
        let mut sprite = Sprite::new().into_shared().assume_safe();
        let sprite_name = /* irrelevant */
        let mut resource_loader = ResourceLoader::godot_singleton();
        let texture = /* irrelevant *

        sprite.set_texture(texture);
        owner.add_child(sprite, false);
        self.sprite = Some(sprite.claim());
    }
ghost commented 4 years ago

@paytonrules Acknowledged. If you need more information on Ref at this moment you can read the API documentation: https://docs.rs/gdnative/0.9.0-preview.0/gdnative/struct.Ref.html

As for the example code you have posted, you don't need to mark the entire function unsafe. You should only need it around assume_safe. Also the let binidngs don't need to be mutable anymore:

    #[export]
    fn _enter_tree(&mut self, owner: &Node2D) {
        /* ...  */ 
        let sprite = Sprite::new();
        let sprite_name = /* irrelevant */
        let resource_loader = ResourceLoader::godot_singleton();
        let texture = /* irrelevant */;

        sprite.set_texture(texture);

        let sprite = unsafe { sprite.into_shared().assume_safe() };
        owner.add_child(sprite, false);
        self.sprite = Some(sprite.claim());
    }
paytonrules commented 4 years ago

Thanks @toasteater - I knew I didn't need the function unsafe, I just wanted to post it up before I forgot.

Is this still the best place for suggestions for the book? Or should there be new issues?

ghost commented 4 years ago

@paytonrules It might be better to open new issues now that we have a separate repo!