Rust-SDL2 / rust-sdl2

SDL2 bindings for Rust
MIT License
2.76k stars 473 forks source link

Feedback needed to decide how we're going to move rust-sdl2 forward #752

Open Cobrand opened 6 years ago

Cobrand commented 6 years ago

It's been quite a few months I've been in charge of maintaining this rust-sdl2 crate now. Something that I think I've been lacking deeply (even though my contributions were small over the past year), was overall feedback for this crate and more exactly, where it should be headed in the future for 1.0.0.

I've been craving for someone to help me release 1.0.0 (see #702), but alas no one was interested enough. Which is fine -- I can understand that contributing to an open-source library and time consuming, while I would have loved some help, I'm blaming no one here.

However, something that I feel like is really needed, (and I mean it) is to have some feedback regarding this crate. I've been working on my own projects that work with sdl2, (alone and on my spare time) and my point of view of what should be improved in this crate is pretty much limited to the stuff that I use (hard to tell what to improve if you're not using it in the first place). And as the main maintainer now, I can't feel it's right to tweak this crate based on only what I think should be right.

I know that sdl2 is getting pretty popular, and some of you have been using it or are planning to use it in production (sooner or later). I'm thinking on top of my head about @michaelfairley and @kyren, but I'm sure there are others as well.

What I would love to hear from you guys, is simply your opinions about what should be improved, what should be kept as-is, what should be tweaked/re-done completely, etc regarding this crate. If I had one question precisely, that would be if you had unlimited time to change anything you wanted in this crate, what would those changes be?.

As an example, here is what I would like to change if it was my decision alone (on top of my head):

Thank you for your time. Please give any feedback, however small it is!

phrohdoh commented 6 years ago

For the time being I only have two opinions/suggestions:

1) Move gfx, mixer, image, and ttf into their own crates 2) Create an {IRC, gitter, ...} channel for real-time discussions (whether that be helping consumers or discussing implementing the SDL2 crate itself)

Cobrand commented 6 years ago

Thanks for the feedback @Phrohdoh

It's funny that you mention moving gfx, mixer image and ttf into their own crate, because that's how it used to be. We decided to merge them all into one because it was a pain to maintain (admittedly, they all had different maintainers back then, while if we were to do this again, we would have full control, unlike back then). Can you elaborate why you think this is necessary?

I think the closest that you have for help regarding sdl2 is the rust-gamedev channel on Mozilla's IRC. I'm not sure about creating IRC channel just for that, it would just be empty most of the time, while more people in rust-gamedev may be able to help you.

phrohdoh commented 6 years ago

I've put my foot in my mouth a bit and for that I must apologize.

I did not realize that gfx, mixer, image, and ttf were behind feature flags. Since they are I believe keeping them in-tree is the right choice (to reduce maintainer overhead).

Regarding IRC / etc I do believe there is value in having a gathering place for a particular topic (gamedev is quite broad and is, in my experience, just another #rust-offtopic).

Of course your point regarding it being empty is valid and may actually harm perception that potential users have.

This crate sits in an interesting spot in that once you get it working the way you want you pretty much don't have to touch it again (assuming you've built your own rendering abstractions, for example) which makes it difficult for me to identify pain points (until I start a separate SDL2-based project).

Unfortunately I am at a point in life where I have seemingly a negative amount of free-time so I cannot devote time to stabilizing this crate though I agree that reaching 1.0 is necessary.

Perhaps part of promising stability could be providing an in-depth 'book' / usage guide.

In my opinion a guide for this crate that assumes no knowledge of the C API/impl (and even better, never mentions it!) could go a long way.

kyren commented 6 years ago

I would really love to see this crate reach a 1.0 state, but I'm not sure that I have enough experience using it to provide much of an opinion. How Chucklefish uses SDL2 internally (from all languages) is.. limited at best. In the interests of science, here is the ENTIRETY of our use of SDL2 in the current rust project (some long uninteresting code has been removed):

(Edit: Moved to gist) https://gist.github.com/kyren/c21350b26eb3dbda547153b81dd808b4

You can see that we try to use SDL2 basically as little as possible, because it is only one of several platform layers that we support. We have a separate abstraction for rendering, and we implement that on SDL2 platforms using OpenGL 3.3.

We are using SDL2 to

  1. create a window with an opengl context
  2. get keyboard / mouse / controller input
  3. start an audio thread and call a callback to fill the audio buffer
  4. start / stop text input
  5. get / set the clipboard
  6. find the "base application path" which is important for mac .app bundles.

Eventually, we will probably use a tiny bit more of SDL2. If we extend this to use everything from SDL2 that Starbound also used, we can throw in:

  1. setting fullscreen / borderless fullscreen windows
  2. showing / hiding the system cursor

It's hard to have TOO many pain points in ~400 lines of code. If I had to list some things:

  1. Setting up an audio callback is a bit complex, with having the callback receive the spec. This does, however, closely match the SDL2 C API, because you have to set the callback on SDL_OpenAudioDevice, so this is forgivable. A possible improvement would be to set a callback with a userdata that contains another callback RefCell, which would allow you to set the callback separately from opening the audio device. This could be too magical, though?
    1. Opening / closing controllers and handling controller hot-plugging is a bit tricky if all you want is ALL the events from every controller. Again, this matches very closely with the SDL2 C API, so it's quite forgivable. Changing this could be far too magical, and I'm not entirely sure that opening every controller automatically is even a good idea?
  2. The vsync setting is annoying and often there is not a great way to tell if it REALLY worked and gl_swap_window will actually wait for anything. I don't think there is anything that rust-sdl2 can do about this, different platforms and drivers have tons of oddities like this. (EDIT: in case it wasn't obvious, this is of course the EXACT same behavior that the SDL2 C API has)

In summary, I don't really feel strongly that anything I've used even NEEDS changing. I realize how unhelpful this feedback must be, I'm sorry :/

tl;dr: The writers of rust-sdl2 have ultimately done a pretty good job (modulo some minor bugs), and I'm really struggling to come up with suggestions. Also, the API surface I use is tiny, so what do I know.

Cobrand commented 6 years ago

@Phrohdoh Thanks for the feedback! I feel I've had negative amount of spare time as well lately, so I definitely feel you on that one.

As for the "write a guide" to make it stable, I feel like we would be biting our own tail since I'm actually waiting to ship 1.0.0 to write a fully-fledged tutorial developing a rust-sdl2 app with no C experience beforehand. I definitely agree with everything else you've said.

@kyren Thank you so much for the feedback this is definitely very useful! It's quite interesting to see how you've implemented that, I reckon you have 1 display backend for sdl and others for other consoles not compatible with sdl2?

From what I understand, what you have quoted are more papercuts than real pain points. But even though they may be papercuts, it's definitely worth to take a look at it!

  1. I definitely agree with the audio system as it is now. Not only it is hard to use, but it's also non-intuitive and hard to grasp if you've never used the C API before.
  2. I've had less experience with controllers and joysticks, but from what I've tested in the past some things could be improved as well.
  3. Very interesting problem, I will try to look it up

Thank you so much for the feedback, hearing that only so few things should be fixed is a huge step forward! Even though you may find it unhelpful, it's actually great to know what the actual users think, instead of guessing what they could think about this crate ;)

kyren commented 6 years ago

@kyren Thank you so much for the feedback this is definitely very useful! It's quite interesting to see how you've implemented that, I reckon you have 1 display backend for sdl and others for other consoles not compatible with sdl2?

That's exactly right. The details aren't terribly interesting, but there is an abstraction for the rendering API and a bare minimum of an "application" API, and it's currently implemented for four platforms: one PC implementation using SDL2 / OpenGL 3.3, and then one for each console. Eventually this will grow to also include things like Steam integration / console services integration, and possibly other rendering backends on PC.

michaelfairley commented 6 years ago

A handful of loosely connected thoughts:

Ditto most of what @kyren and @Phrohdoh said. I've been using this library exclusively for windowing, GL context creation, input handling, and audio (though I might be moving that to OpenAL for various reasons, none of which have nothing to do with rust-sdl2), and this library is already in great shape for those use cases.

I'll definitely remember to open issues for any paper cuts I encounter, as I do occasionally bump into small issues.

I keep an eye out for SDL2 related question in the #rust-gamedev IRC channel, and it seems like at least 90% of them are related to rendering (especially lifetime management on the various rendering structs). I don't personally use it, but the SDL2 renderer is IMO not all that great, and is very hard to make a rust wrapper for given that most things in it allow for both owned and non-owned data. (I think you've done a great job getting the wrapper to its current state, and I don't see any obvious/easy improvements). It's possible that the best long term thing for rust-sdl2 is to tell people "if you want to do simple 2d rendering, use ggez" and discourage use of the rendering parts of this wrapper.

Somewhat related, there's a bunch of stuff in SDL2 (threading, timers, assertions, rwops, etc, etc) that already have counterparts in Rust's std, and it seems like the std implementations of these are almost always preferable to the sdl2 ones when working in Rust. I don't entirely know how this wrapper should treat those features, but it's possible that removing them entirely and saying "just use sdl2-sys if you really want these (e.g. because you're porting an existing C SDL2 project to rust)" is the right way to go in terms of reducing how much code there is to maintain and keeping stuff that generally shouldn't be used out of the docs.

Every few months I get an email/PM with some questions about getting a rust-sdl2 game building on iOS or Android. It's unfortunate that I'm literally the only person who knows exactly what to do here, so I really need to get some of this knowledge into a shareable state. I have a personal goal to release a small, free, open source, runs-everywhere (mac/win/linux/ios/android/emscripten) game during 2018, and it should be something we can point to as an example of how to do things.

As always, feel free to ping me with Mac/iOS specific questions or requests.

tanis2000 commented 6 years ago

@michaelfairley if this can make you happy, you're no longer alone. I managed to get my own proof of concept working on Windows, Linux, macOS, iOS and Android as well so I know exactly what to do to get a project running on all those platforms with SDL2 underneath, but the way I do this isn't streamlined.

The easiest way would be to extend the actual "bundled" feature of this crate to correctly compile the iOS static library and Android dynamic library so that we can rule out all the C compile stuff which is the painful part.

What I'm working on right now is a cargo subcommand that would let me create a new game project with my engine as a dependency and with all the needed pieces in place, like the iOS and Android native projects generated from a template and a basic main.rs file with a simple game up and running.

The cargo subcommand should also be able to build for the different targets and invoke the build phase of the native projects as well.

It shouldn't really be that hard, but I've never wrote a cargo subcommand so I'm still learning while I code.

Flaise commented 6 years ago

Are there any plans to make the bundled feature work with sdl2_mixer? When I install sdl2_mixer on a mac, it automatically downloads sdl2 and the dynamic linking in sdl2_mixer references the non-bundled sdl2 library, thus defeating the point of the bundled feature.

darakian commented 6 years ago

More documentation please. I'm fighting with this crate just retrying to get my keyboard scancodes to be read.