Hands-on Rust B4.0: general feedback

Hi. First, thank you for the book. Even though I came here to leave some critical comments, it doesn’t mean I don’t like it; quite the opposite, it’s one of the best things that happened to me lately. It really helps me do my own roguelike (I had a nice idea in a backburner for a decade now) and study Rust (about 4 years due).

I’m creating my own project, loosely based on the book’s dungeon crawler. I haven’t got very far yet. I’ve read TRPL and “Rust by example” now, and did a few exercises.

The book is a great source of knowledge about things I had a very distant idea of: game design in general, ECS-based data-oriented design, and their implementation in Rust.

Now, things that, I feel, reduce the quality of life when following the book:

  • I’m not a fan of re-exporting names from other modules in a prelude, and generally of importing *. It’s been an anti-pattern in Java, IIRC. As a result, you never know what have you imported, not even what library you have imported it from. This can create invisible dependencies that are hard to untangle later. I thought it was a Rust way to do things, but I doubt that.
  • It’s a bit dated to hardcode the console dimensions into constants. We no longer work/play on 80x25 consoles. As long as we are introducing a Camera very early, why no make it a “Viewport”, and add dimensions to it?
  • I’m reading the ePub version of the book in iBooks and in Calibre, and when I copy-paste (fingers crossed) code from there, I bring a few unwanted nonprintable characters in each line, and an excess tab offset. Is it something hard to fix?

Thank you very much for your work and for listening!

I’m glad you’re enjoying the book! You’re running into a few things that ended up the way they are because the book is targeted at beginners, so I simplified things a little bit to keep things moving forward:

  • The prelude system in particular splits the Rust community a bit. There are a lot of crates out there that use it, it is convenient - but like you say, it can cause some fun namespace issues. I went with the prelude because I didn’t want to be reminding the reader to update their imports every few pages. It’s a good topic to expand on for more advanced readers, so I think I’ll add it to the list of articles to publish post-release (there’s a few topics that will be getting additional content via my website due to page constraints).
  • Expanding on preludes a bit, I personally tend to import things directly (it gets messy with some libraries like wgpu - the use section can be HUGE) at the top if they are used everywhere, and directly in functions otherwise. Sometimes, I’ll use the full namespace (e.g. libname::funcname) - but only if collisions are likely. I just find it hard to read a page full of fully-qualified names!
  • I agree that 80x25 and similar are pretty dated. This was a simplification issue. If you use a fixed size in bracket-terminal, the window will scale if you resize it. There’s options in the library to handle dynamic resizing (see the bench_scalable example), but it imposes a lot of work on the reader - you have to catch the resized event and rescale your UI dynamically each time you render because the size may have changed. It’s a good idea for a production game, but it would add a LOT of size to the book code - so I stuck with the straightforward approach.
  • Unfortunately, I have very little control over what goes into the various output formats. I may be able to fix the tab offset - I’ll take a look. I’ve been primarily debugging the PDF output and obeying the Publisher’s instructions not to worry about formatting yet. Hopefully we can get at least some of that fixed on the way to final release.

Thanks!

Re: the constant size. I’ll wade in that I’ve come to see that Herbert needs to keep page count under control, as opposed to building a fleshed out application.

That said, I found it a bit constraining as well, so (while waiting between beta releases) I added command line options to allow me to run with arbitrary dimensions. Learned a bit making the changes.

I didn’t know about the ability to respond to resize events, but that seems a bit “odd” to me, I can’t really imagine that I’d regenerate a level on a resize (ah, I guess I could respond by modifying the camera dimensions… that could be interesting.)

I’ve added this to the potential topics list for post-release articles. I really can’t squeeze much more content into the book, but I’d love to keep supporting it with a few blog posts.

The “resize” event wouldn’t be used to recreate the map - but for dynamic window sizing you need to restructure a lot of the render code to use whatever window size has become available. For example, the GUI would need to know the window width (in characters) to scale the health bar. You’d probably need some tweaks to avoid it looking ridiculous. (GUI work tends to be really time consuming for that reason!)