11 ms·
Making a Game in Rust
- wyldfire 9y ago> The include_* macros are great for “packaging”. Being able to compile small assets directly into the binary and eschewing run time file loading is fantastic for a small game. For C/C++/etc devs looking for something similar, BFD objcopy supports an "-I binary". It will emit an object file with _binary_objfile_start, _binary_objfile_end and _binary_objfile_size symbols. But I have got to say that making it a language feature means that Rust is truly a batteries included language.
- Pxtl 9y agoAgreed. I code in C# and there's facility for bundling assets into the binary but they're handled at the project file level and not the C# file level, and this means the keys to access this binary content is not available as a compile-time constant. You're still just passing strings around and hoping they match. Having first-class language support for resource files looks fantastic.
- voltagex_ 9y agoI wonder how XNA's asset pipelines worked. I also wonder if you could "pack" a binary into an assembly by writing a tiny bit of IL around it.
- voltagex_ 9y agohttp://stackoverflow.com/a/28191247 http://stackoverflow.com/a/28191247
- Pxtl 9y agoYeah, that's the workflow I was mentioning, cooking the file into a resource by referencing it as resource in the csproj, but then it's keyed by a string of the file-path within the project file, which isn't nearly as nice as having it bound to a variable in C#.
- flukus 9y ago> and this means the keys to access this binary content is not available as a compile-time constant Isn't that exactly what resource files give you or am I confusing something? Anything you add in resource files have are accessible as a static variable.
- Sean1708 9y agoIt looks like you're right (for C# at least): https://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.90).aspx#Anchor_2 https://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.90).a...
- sillysaurus3 9y agoTo embed binary assets into any language, write a program that emits the binary as a string containing hex codes. E.g. bytes [0, 12, 99] would become "\x00\x0C\x63". Almost every language has facilities to treat a string as a set of bytes, so this works basically everywhere. It's nice because you don't need any special language-level support for it.
- jamescostian 9y agoWhile I do agree that it is possible to do something like that, I think we can all agree that the following (available in Rust) is soooooo much nicer: let stuff = include_bytes!("my.file");
- phkahler 9y agoNow I have to rewrite my arcade game emulator in rust just so I can use that to load rom images...
- FreeFull 9y agoinclude_bytes! is for compile-time inclusion of files though, not for runtime.
- phkahler 9y agoYeah but when it only runs 15 games with a max size of 32K... But yeah it makes it non-distributable because it would then include the images.
- jamescostian 9y agoNot only did you completely miss the point (a systems language has a very nice thing very well built-in - yay!), but you also built a strawman (as if praising a language means is the same as telling everyone to rewrite all code in that language) and then beat it up using a poor example (why package those images into the binary?). Congratulations! You just won the internet!
- Asooka 9y agoThat has also been a feature of Windows for quite some time, you have your IIRC .exe icon and various string resources packaged in the .exe itself. It's pretty useful on the whole.
- hawski 9y agoThere is also an option to use assembler or inline asm. I found quite a nice utility that uses inline asm [0]. It's widely portable and I think that I will use it instead of my naive asm/shell combo that doesn't work with mingw asm. The problem with objcopy outside of unconvenient usage and naming is that naive objcopy will result in your binary having executable stack [1]. You can change a symbol name, but that's also unconvenient. Check resulting binary with: $ readelf -lW the_binary | grep GNU_STACK GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x8 $ Notice: RWE instead RW. Also: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart#How_to_fix_the_stack_.28in_practice.29 https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart#H... [0] https://github.com/graphitemaster/incbin https://github.com/graphitemaster/incbin [1] https://news.ycombinator.com/item?id=10816322#10818085 https://news.ycombinator.com/item?id=10816322#10818085 EDIT: My shell script - bin2o.sh: #!/bin/sh set -e filename="$1" name=$(echo "$1" | sed "s/[^A-Za-z0-9]/_/g") obj="$2" echo \ " .section .rodata .global ${name} .type ${name}, @object .global ${name}_size ${name}: .incbin \"${filename}\" 1: ${name}_size: .int 1b - ${name} .section .note.GNU-stack,\"\",%progbits " | gcc -x assembler -c - -o "$obj"
- vvanders 9y agoGreat stuff, lines up a lot with what I'd care about as an ex-gamedev and spending a bit of time with Rust. One minor point: > First class code hot-loading support would be a huge boon for game developers. The majority of game code is not particularly amenable to automated testing, and lots of iteration is done by playing the game itself to observe changes. I’ve got something hacked up with dylib reloading, but it requires plenty of per-project boilerplate and some additional shenanigans to disable it in production builds. Lua is a great fit here and interops with Rust(and just about everything else) very well.
- aschampion 9y agoLua is great and generally the right tool for this sort of thing. As an alternative, though, there are several Rust-based scripting languages that attempt to expose some of the power of the type system, etc., while being more amenable to dynamic loading, REPL, etc: http://libs.rs/scripting/ http://libs.rs/scripting/
- jamescostian 9y agoDyon (from that link) looks very cool! I'd also like to add that JavaScript is another language used in this arena, and there is a crate with V8 bindings (https://crates.io/crates/v8 https://crates.io/crates/v8). Even Garry Newman (creator of Garry's mod) wrote that he believes JS would have been better than Lua for scripting: https://garry.tv/2014/08/16/i-fell-out-of-love-with-lua/ https://garry.tv/2014/08/16/i-fell-out-of-love-with-lua/
- vvanders 9y agoYeah, Lua certainly has it quirks. However binding to JS is a huge endeavor. For instance that v8 crate doesn't easily expose a way to call Rust from JS which is trivial in Lua. Also the JS runtime is huge and the build system is complex. You can run Lua in ~400kb or less and LuaJIT tends to walk over any other jitted interpreted runtime.
- 9y ago
- kibwen 9y agoI wasn't even aware that you were allowed to ship Rust code in iOS apps, I thought that Apple had a whitelist of allowed languages? EDIT: And for those interested, you might want to check out Rust's recent inclusion in a AAA title: https://www.reddit.com/r/rust/comments/69s225/rust_makes_it_into_a_aaa_video_game_as_an_art/ https://www.reddit.com/r/rust/comments/69s225/rust_makes_it_... :P
- wyldfire 9y agoReally? How do they know what the representation of the object code was before compilation? Seems like if they had a whitelist it would be difficult to enforce.
- kibwen 9y agoNote that I've obviously never written an iOS app, but I figured that Apple required you to submit the source of your app for their auditing process. Which sounds extreme, but this is Apple we're talking about. :)
- adrianmalacoda 9y agoThere was indeed a rule at one point that apps had to be written in C, C++, or Objective-C. This was allegedly implemented in order to ban cross-compilers such as Flash compiler[0]. Presumably they would either require the source code to verify this, or inspect the compiled binary for some identifying feature. However, these rules don't exist in the current version of the guidelines[1]. [0] http://daringfireball.net/2010/04/iphone_agreement_bans_flash_compiler http://daringfireball.net/2010/04/iphone_agreement_bans_flas... [1] https://developer.apple.com/app-store/review/guidelines/ https://developer.apple.com/app-store/review/guidelines/
- Impossible 9y agoThis rule got so much press 7 years ago that it will be one of those "truths" about a platform that never dies on internet forums, that and the Playstation platforms using OpenGL as their primary API...
- newsat13 9y agoGreat writeup. Eye opening that you can actually write iOS apps with rust. w00t, totally trying this for my next app. (It's a bit overly bit expensive for my liking but otherwise I would have given your game a shot).
- alkonaut 9y ago> I had two or three false-start attempts at learning Rust where I’d spend a few hours with it, not get anything done, and put it down until a few months later This sounds (sort of) encouraging. I was kind of expecting to learn it by putting in an hour here and there e.g. 2-4h/month. But I'm beginning to think that might not cut it...
- Manishearth 9y agoGo is a language that you can absolutely learn like that, and it's pretty amazing. (Python, too) Rust ... isn't. I love Rust, but you do need to put some dedicated time into learning it. We're hoping to improve this!
- alkonaut 9y agoYeah I'm guessing it's a treshold you need to get over that requires at least a bit (a week, two weeks, a month) of doing it more than sporadically. Wish I had a week I could do 40h rust in, but that's sadly not the case. I'm doing baby steps with Rust now but it almost feels like the language is walking away faster :)
- joncampbelldev 9y agoWhilst an easy start is nice, any language that you can pick up with no effort just means you're learning the same language + paradigm that you already know with a few differing features (in go's case CSP). Nothing wrong with that, CSP is awesome etc I'm not a rust dev (definitely interested in picking it up though), but heavily into clojure and learning haskell slowly on the side. I hear this complaint a lot from people who think that because they learnt C#, Go, Java and Swift in a weekend that all languages will be just as quick to stick in their heads.
- Jare 9y agoA lot of people have to unlearn "classic" OOP inheritance in order to learn Go. That's a significant change in paradigm.
- 9y ago
- lohengramm 9y agoI would love to read a detailed explanation of the packaging process for iOS and Android.
- deleted 9y ago[deleted]
- desdiv 9y agoThe author should seriously consider factoring out his build scripts and start a crowd-funding campaign to open source it for X thousands of dollars. Hell, I don't even know Rust and I'll donate ten bucks. The five platforms support is bloody impressive.
- ilanco 9y agoThe author explains the process briefly here: https://gist.github.com/michaelfairley/d86137085307d2e5c16ee0df2fb84cd9 https://gist.github.com/michaelfairley/d86137085307d2e5c16ee.... I think the most obvious pitfall is the native API calls for both platforms. Maybe a cross platform framework like PhoneGap for Rust?
- MaulingMonkey 9y agoNeat! I was just complaining about the lack of multiplatform Rust games proving out the concept. If only there were some consoles or handhelds on the list... although iOS/Android being on the list is somewhat encouraging.
- deleted 9y ago[deleted]
- felipemnoa 9y agoThis is probably not a popular opinion here in HN but why does it matter what language you use to make your game in? You can use virtually any language to make a game. From my point of view the best language for a game is that which makes you the most productive for cranking out that code. And we all have our own personal preferences about which language is best, which I think is fine, you should code with the one that you feel most productive with. At the end of the day users will not be able to tell the difference. All that matters is whether your game is fun or not.
- Jare 9y agoThe language he chose doesn't matter except to him, but writing about his experience using it does matter to anyone interested in choosing a similar path.
- wastedhours 9y ago100% agree with you. However - posts like these might give encouragement to people who know a language that they can actually accomplish Project XYZ in said language, especially if there's accepted norms about what types of work a language is "good for".
- felipemnoa 9y agoAlthough I did not point it out, I'm talking about experienced software/game developers. A novice can definitely make the mistakes you are mentioning, which makes your comment a valid point.
- 0xffff2 9y agoReplace "game" with "software", and your post is equally valid.
- BatFastard 9y agoAs long as it is not flash! Some serious flash hating here.
- Lerc 9y agoIt would be nice to have a minimal gameish program as a example for people learning Rust. When I teach kids javascript I start with an etch-a-sketch. It's aided by a simple library to hide the mechanics of the HTML canvas element, context, etc. This allows it to be small enough that they can view it all in one go and build upon it. print("Draw with the arrow keys"); var cx=320; var cy=240; function update() { // the arrow keys have key codes 37,38,39 and 40 if (keyIsDown(38)) { cy-=1; } if (keyIsDown(40)) { cy+=1; } if (keyIsDown(37)) { cx-=1; } if (keyIsDown(39)) { cx+=1; } fillCircle(cx,cy,6); } run(update); There might be merit in writing one of these in every language (and a companion that uses the mouse), maybe placing it on github . With a really simple program like this you can focus on learning the language while making something. It's a tough job figuring out how to learn a language while simultaneoulsy learning how to write the boilerplate needed to get something onscreen.
- steveklabnik 9y agoIt's not a graphical game, but the introductory project in the book has been the "guessing game" for years now https://doc.rust-lang.org/stable/book/guessing-game.html https://doc.rust-lang.org/stable/book/guessing-game.html
- Lerc 9y agoYeah, it's the dynamic interactivity that I was looking for. I'm afriad console IO isn't a starter here. I'm sure it's fine as a console IO example, but it's just a completely different class of thing.
- throwaway7645 9y agoI'm actually a huge proponent of learning through text type games in lieu of more complicated graphics related black boxes where someone is essentially letting a library do 98% of the work. A text game is literally as simple as it gets while requiring no modules (well maybe IO or system if your language doesn't include it by default). Guess my number also is seems more mathematical although that is just subjective rubbish on my part ;). I do believe you're correct that certain people would like a graphical introduction more. Maybe you could write a cool intro to Rust with graphics!
- deckarep 9y agoI largely echo the sentiment of using Rust for game development. The world doesn't need another Flappy Bird clone but that's what I wrote because I ended up porting a Go version that was using SDL originally by Francesc Campoy from the Golang team: https://github.com/campoy/flappy-gopher https://github.com/campoy/flappy-gopher I was able to build the Rust version fast, and the SDL library is actually quite usable/stable for most things. Flappy-Rust has particle effects, the beginnings of parallax-scrolling and basic collision detection. The rust code ended up being pretty reasonable however I'm quite sure there are a few places I could have simplified the sharing of assets. If anyone is interested in this space check out my repo: https://github.com/deckarep/flappy-rust https://github.com/deckarep/flappy-rust Also please see the README.md where I talk a bit more in-depth about how the Rust version differs from the Go version. Here is a .gif preview of the first iteration of the game: https://github.com/deckarep/flappy-rust/blob/master/flappy-rust.gif https://github.com/deckarep/flappy-rust/blob/master/flappy-r...
- remotehack 9y agoDid a double take on the title.
- educar 9y agoIs there a write-up on how the rust code ends up being embedded in the iOS app?
- Ace17 9y agoScreenshot, please!
- bronson 9y agoHit the second link in the article for a video: https://m12y.com/a-snakes-tale/ https://m12y.com/a-snakes-tale/
- Buge 9y agoThe performance on my Android phone (Nexus 6) is not good. I would have thought Rust would be fast. The fps is fairly low, a lot lower than Maps or Chrome, at least when Maps isn't freezing up. And it seems the transitions between levels might be proportional to fps, because they are irritatingly long.
- MaulingMonkey 9y agoI'd guess any performance problems are probably on the GPU / OpenGL side of things, which Rust won't help with (nor hurt). The Nexus 6 has a 1440p screen powered by a mobile GPU maybe a little weaker than previous generation consoles (~172 gflops max for the Adreno 420, vs e.g. ~220 for the PS3 [1]) that were often handling 720p titles (a quarter of the pixels). Very easy to exceed your frame budget. [1] http://gpuflops.blogspot.com/ http://gpuflops.blogspot.com/
- yorwba 9y agoAbout floats implementing PartialOrd and not Ord: I have not tried out Rust yet, but couldn't this be solved by wrapping the float in a single-field struct that checks for NaN on construction, implements Ord using PartialOrd and otherwise passes everything through to the ordinary float inside? If this isn't possible, I'm definitely interested in the reasons.
- lifthrasiir 9y agoEvery calculation will have to check for NaN, so it's a non-starter when you need a lot of float calculations.
- yorwba 9y agoThe problem was in the context of looking up min_by_key with the key being a floating-point number, so I think the only NaN-check necessary should be for that key. I did not intend to imply that it should be done for all calculations, only those that need totally-ordered floats. (Or if you are really sure NaN will never happen, you leave out the check altogether, and claim total ordering anyway.)
- lifthrasiir 9y agoI guess that is a particularly bad use case of specialization, which itself is proposed as an RFC [1] and approved for implementation. It would look pretty similar to, say, C++'s `vector<T>` and `vector<bool>` split, because it does something more than what it should do. Probably the better solution is to merge PartialOrd and Ord, as the benefit from having two traits has been always unclear (I personally have no strong opinion against or for that though). [1] https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md https://github.com/rust-lang/rfcs/blob/master/text/1210-impl...
- frubar 9y agoIf the type proved there could be no NaN, why would the check be needed?
- esistgut 9y agoIt is an interesting educational project but staying away from Unreal or Unity3D is really a tough decision if your project is going to need some more features that are already developed and well tested in one of these engines.
- golergka 9y agoIn my experience, the real value of the engines aren't "features", but tools oriented at level designers and artists. Once you have a project with 10 or more members, managing art and assets becomes a real headache - and most of homegrown solutions, as well as open source engines start to fall apart at this point.
- jlebrech 9y agothat's a great twist on the snake game. does rust compile to wasm?
- cjg 9y agoYes, Rust can compile to WASM. https://hackernoon.com/compiling-rust-to-webassembly-guide-411066a69fde https://hackernoon.com/compiling-rust-to-webassembly-guide-4...
- jlebrech 9y agoI want to do an experiment with object oriented code that generates view code in wasm and keeps other code in the server.