Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write a "Guide for writing idiomatic Piston code" #1048

Open
bvssvni opened this issue Mar 21, 2016 · 3 comments

Comments

@bvssvni
Copy link
Member

commented Mar 21, 2016

See https://www.reddit.com/r/rust_gamedev/comments/4b8s9h/i_love_the_idea_of_piston_but_and_some_questions/

People have a hard time making the transition from writing application code to generic code. This requires knowledge about how to structure the code, which generic parameters to use, and which library to depend on.

The amount of confusion increases because in an application, by depending on generic libraries, you need the backends, and maybe a convenience wrapper like piston_window on top. In generic code this is pretty much the other way around, with a library only depending on a few others. There is a large conceptual gap from how a new user experience doing a few smaller projects to the attempt of extending the ecosystem.

Some points I noticed people are often confused about:

  • What is all the "cruft" or all these dependencies that get pulled in?
  • How do I write generic code to handle events, textures etc.?
  • Which libraries do I use?

The guide should explain in details, but in a simple way, the following stuff:

Event handling

  • pistoncore-input is used for event handling in generic code
  • event<E: GenericEvent>(e: &E)

2D Graphics

  • piston2d-graphics is used for 2D graphics in generic code
  • render<G: Graphics>(c: &Context, g: &mut G)
  • T: ImageSize for textures

Texture creation

  • piston-texture is used for texture creation in generic code
  • T: Rgba8Texture<F> where F is the factory

Window

  • pistoncore-window is used for window generic code
  • W: Window for simple stuff
  • W: AdvancedWindow for advanced stuff

What is all the "cruft"?

Piston uses backend agnostic design to remove the dependency on OS platform or API where it is expected that 90% or more of the total amount of code is reusable. This requires backend libraries that glues together the generic abstraction with the API specific code. On top of that, since several backends often go together to make an application, you might need a convenience wrapper like piston_window.

The result is that an application requires extra libraries just to work, and this makes the dependency graph larger than a platform specific game engine.

On the upside:

  • Generic libraries only need to a few dependencies
  • Modular design prevents unrelated parts from breaking each other
  • Swapping backends helps debugging bugs
  • Testing backends against each other provides useful feedback to API authors
  • Big portions of ecosystem reusable outside Piston applications - more tested code in the real world
  • More people engaged in the individual libraries - since most people are not long term invested in the ambitions of the projects as a whole
  • Important parts can be developed in parallel outside the PistonDevelopers organizations, such as 3D and audio, since we do not have to commit to a specific API, but can explore and test alternatives

These benefits are more enough to pay for the extra dependencies, and we develop tools to help getting this right. However, in periods of design changes it can be quite difficult to keep up, so we try to avoid breaking existing code. If your project works, then that set of dependency versions should work in the future too.

@bvssvni bvssvni added the discussion label Mar 21, 2016

@robojeb

This comment has been minimized.

Copy link

commented Mar 21, 2016

Speaking as the person who made that post, thank you. Even looking at this I notice some differences between what I am doing in my code and what appears to be idiomatic for Piston2D.

That said I love piston's modularity and if I can I would love to help build such a document.
I am also willing to put forward the crate I am working on (cavebat) as an example of generic code (with the upside that I am learning piston generics right now and will run across a lot of gotcha's). It is intended as a pure rust alternative to Tcod. Right now the only part that is working is cavebat_display (and not very well it is very slow and has no optimizations, and might be over-scoped). but later portions such as cavebat_widgets and cavebat_engine eventually will hook into larger things like helping handle events and such.

@robojeb

This comment has been minimized.

Copy link

commented Mar 21, 2016

#1013 Is along the same vein as this. But this seems more targeted than just "Improve all the docs"

@Phlosioneer

This comment has been minimized.

Copy link
Contributor

commented May 25, 2016

I've started sprinkling bits and pieces of an "Idiomatic Piston" guide throughout the docs I'm writing (see #1068, #1069, and probably more to come as I continue through the code). I'll keep these things in mind while I'm writing.

I definitely agree with robojeb's point in that reddit post, where the connection between the name of the crate and the name of the modules it provides are too different. I think we should make an effort to make scopes more explicit. Crates should have a single scope they provide that contain everything that the user needs, and the name of that scope should be very similar to the name of the crate.

piston_window should give the user things inside of piston_window::, piston_2d should give things inside of piston_2d::, etc. The user will have to add in one or two more use statements, and everything becomes sooooo much more clear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.