Rust 1.0 has been released

(Rust the programming language, not the game)

Throughout Rust’s development, a lot of breaking changes have happened, but now that 1.0 is released, things are guaranteed to be mostly backwards-compatible (Changes are allowed that would require parts of code to be more explicit, as long as the explicit form works on both the old and new versions of the compiler).

Over the last 1.5 years I’ve been learning Rust (well, you never really stop learning a language until you stop using it), and have found myself preferring it over Java for use in gamedev. I’ve entered two Ludum Dares, written an Entity-Component System library, amongst other various utility libraries (thankfully, most of which I’ve abandoned as the language and other libraries evolved to make them redundant), and have two more libraries in progress (windowing and graphics) that aren’t publicly available yet.

This paragraph from the documentation does a better job of explaining Rust than I ever could.

The biggest difficulty I found in learning Rust was that you have to get out of the OOP & inheritance mindset of Java. Rust still supports OOP, but not in the same sense that Java does. Think of Java where you can extend interfaces, but not classes and you get the general idea of Rust’s OOP. Fortunately, the generics system is very powerful (not as much as C++ templates, but they cause headaches), which makes using traits (equivalent of Java interfaces) much more viable. Most importantly: You can’t write Java in Rust.

Several useful features didn’t make it into 1.0 because at the time they weren’t deemed stable enough to commit to. If you want these features, there’s always the nightly builds.

If you’re interested in learning Rust for gamedev, here’s a list of libraries:

  • glfw-rs: GLFW3 bindings (For those of you who like LWJGL 3)
  • rust-sdl2: SDL2 bindings (For those of you who like SDL2)
  • glutin: Cross-platform windowing library. Similar to GLFW3, but easier to compile on Windows because it’s written in pure rust.
  • gl-rs: OpenGL bindings generator for the people who use Pure LWJGL (For those of you who only have experience with LWJGL, you’ll need a windowing library such as glfw-rs, rust-sdl2, or glutin)
  • piston: Higher-level abstracted graphics library.
  • piston-image: Pure rust image encoding/decoding (Part of the piston project, but is standalone).
  • glium: Safe abstraction over OpenGL. Only supports glutin for windowing, or can run in headless mode.
  • gfx-rs: High-performance bindless graphics API (Abstracts over OpenGL/D3D/Vulkan)
  • gfx_scene: Scene management built on top of gfx-rs
  • snowmew: Multi-threaded game engine that uses a Copy-On-Write game state for high performance and safe concurrency (possibly out of date)
  • ecs-rs: Entity-Component System framework. (Written by me. Only works on nightly for now)
  • Various other things

Various useful links:

It would also be interesting to have a discussion on what you think of the language.

I think it’s great; it’s a lot of what I’ve been wanting in a language: heavily systems-oriented (native, compiled/static guarantees, performance-oriented) with a functional flavor while not being too rigid in purity and such philosophy (large ML influence, but still highly relatable to C++ people/etc.). C/C++ are the de facto systems langs, but are laden with cruft and footguns. Haskell and similar are powerful, but I’m just not quite enough of a mathematician to truly appreciate. Rust seems an intelligent middle ground, with positive aspects from each “domain.”

Looks like an interesting language. I haven’t read much about it, but apparently it’s much more low-level than java and seeks to compete with C++.
For example, its memory management decisions evolved to be similar to C++ with manual heap or stack allocation, and optional library-level garbage collection.
http://pcwalton.github.io/blog/2013/06/02/removing-garbage-collection-from-the-rust-language/

This sounds like a handy feature of the Rust language: “sharing mutable state across a concurrency boundary without a mutex is a compile-time error in Rust”. That would have saved me some time finding bugs and learning how to code with threads properly.
https://www.codementor.io/rust/tutorial/steve-klabnik-rust-vs-c-go-ocaml-erlang

Yeah currently the only “GC” is reference-counted pointers, Rc and Arc in the stdlib.
It’s pretty much a different language from what it was in 2013 as from that article.

Another useful guarantee is if you code segfaults, it had to have been a bug in an unsafe region of code (marked by the unsafe keyword, so grep-able). So if your software doesn’t have unsafe blocks, then it won’t have memory errors. (including concurrency errors such as data races, although stuff like deadlock can happen, as it’s not a memory error)

Interesting. I notice that the Rust license is MIT and apache. It’s nice to have a less-constraining license than java’s GPL, but the downside might be the chance of fragmentation.
Also it looks like Rust is cross-platform since it uses LLVM.

@HeroesGraveDev, you said that you can’t write java in rust.
Is that because Rust doesn’t support classes and there’s no such thing as null? Or are there other more serious problems with translating java source across to rust?

I think he meant you can’t straight port the class-inheritance style java uses to rust’s traits. (for reference traits are very similar to haskell’s typeclasses if you know them)
And semantically since java has null, every field would be Option if translated procedurally, so that’s not a problem in that sense.

I don’t think fragmentation is really a concern, and the license doesn’t affect it anyway.

In addition to what @BurntPizza said, there’s also the problem of shared mutability. One of rust’s memory-safety guarantees is that when a mutable reference to an object is available, nothing else can read from or write to that object. If you tried to write lots of Java code in Rust, every type would pretty much be Rc<RefCell<Option<T>>> (Rc allows shared immutable ownership. RefCell allows runtime-checked internal mutability). This is a lot of unnecessary overhead and syntax noise.

(Fun fact about Rc: There is only an overhead when cloning the Rc to create a new shared owner or when an Rc gets destroyed. Accessing the contained value is absolutely zero-overhead thanks the the borrow-checker.)

But if you write Rust in Rust, you’ll be surprised how little you ever need shared ownership, multiple mutable references, global variables, or even nullable values.

If you really did want java-esque fields you could type alias to reduce noise, a feature which I sometimes with java had:


type Field<T> = Rc<RefCell<Option<T>>>;

One might also need something like an Arena or weak pointers to get java-style GC heavy code to type check.
But idiomatically these features are not needed as often as a java programmer might think, partially because not everything is assumed to be heap allocated all the time, like Heroes said.

So, other than the presumed speed increase, why do you like Rust for game development more than Java? I haven’t tried Rust but it sounds intriguing. I’ve done some work in C/C++ for a course on HPC, and Rust sounds like an interesting alternative.

  • Easy-to-use FFI which means accessing OpenGL and GLFW (and various other things) is much easier.
  • Lots of rust’s restrictions actually help you write code with less bugs. Unique mutability means you never accidentally modify the wrong variable.
  • Algebraic Data Types (Rust’s enums) are extremely useful.
  • Generics without type erasure.
  • Type erasure is still available when you really need it (Which is very rare).
  • Not having to worry about the GC causing lag.
  • Borrow checker stop pointless copying of data.

Probably a lot of other things I can’t think of off the top of my head.

Speedwise it’s apparently approximately the same as Java/C# JIT code.

Cas :slight_smile:

That’s an interesting one esp. on a Java-centric forum like this one where I don’t think anyone who’s written any serious Java code for the last … hmm … 10 years or so has actually ever noticed GC occurring because it’s just so fast for almost every use-case it’s ever put to. A more pertinent issue with GC based systems is that they tend to require considerably more resources up-front than non-GC systems though it’s remarkably tuneable and again, in most places it’s deployed, not actually a relevance.

Cas :slight_smile:

How fast is the compiler? When I am coding at home I often find this greatly effects my productivity. I value my free time and watching a compiler compile is not what I consider getting good value. I will happily give up language features for fast compile loop iterations.

Compile speed is not great, but has much low-hanging fruit and is one of the current top priorities post-1.0 according to the core team.
These fruit include rustc generating very verbose IR that takes LLVM a while to optimize down (when building an optimized build), and no incremental or parallel compilation.

I believe the attitude is “if it’s slower than the equivalent C++, that’s a perf bug.”

I know I’ve noticed the GC, although maybe perhaps I don’t make enough of an effort to please it, but one of Rust’s goals is to be usable wherever you might use C/C++, including embedded and realtime systems, where GC isn’t really an option, perceived ‘lag’ or not.

[quote]including embedded and realtime systems, where GC isn’t really an option, perceived ‘lag’ or not.
[/quote]
That is certainly not true.
A LOT of embedded systems use Java and a Virtual Machine with soft- and hard-realtime GCs, such as the Perc JVM from Atego (formerly Aonix). I was programming for these the last two years for a company building traffic light controllers.
Yes, they really use Java within the controllers of traffic lights. :wink:
And the CPUs and I/O subsystems inside those things are utterly slow…I can tell ya. But even there Java and the GC is not the bottleneck. :slight_smile:
And also take small systems like Android smartphones. What do you find there? A runtime environment featuring garbage collection. :slight_smile:

Yes, I know about specialty Java runtimes, but are we using those in the everyday or for gamedev? No.
Is android fast? No. Is it faster when you use C++? Yes.
Android systems are also pretty heavy compared to the small stuff that has only several K of RAM, etc. Good luck using even the best JVMs there, they won’t even fit on the device. That’s what I meant by embedded.

Don’t get me wrong, I like Java and managed environments for what they are good at, but they aren’t a silver bullet.

Android is an awful pro-GC statement. The best GC in HotSpot for the problem space is being removed. Azul’s is for a different design domain.

Granted that Android is not the best example for pro-GC. :wink:
But playing it back there, would we be using resource-restricted devices with 16K RAM for gamedev or in everyday?..

It was admittedly an orthogonal statement, not sure why I decided to include it in that post.

But then again, as the whole Internet-of-things and VR trends keep picking up, it becomes closer and closer to everyday/gamedev.
I doubt the nanobots of the future will be running JVMs :slight_smile:

(offtopic) @BurntPizza: eventually every runtime environment is virtualized/abstracted for programmer convenience, why not nanobots. :persecutioncomplex:

… then again, nanobots would fight rust. (dadum… tsssh) :emo: