Next Broadcast

Learning Rust, for real this time!

kellswhere Code and Eng DK30 New Year 2023 1 0

Description

Rust is compelling to me because of its compile-time guarantees and focus on zero-cost abstractions. I’ve already tried to learn it a few times. Now, with the power of public accountability, I may succeed!

Recent Updates

kellswhere 2 years ago

Ok, forgot to mark as completed so I get the checkmark!

kellswhere 2 years ago

Ok, 30 days come and gone! Hex library is done but not tested; I’ve been integrating it into my game logic as a test of sorts, with a proper test suite to follow. I actually ran into a tricky borrow checker thing during this process; I’ve asked around, messed with it, and done some experiments to try and understand lifetimes better, and I think I have a good understanding of how to proceed. I definitely slacked off a bit this last few days, especially when I was procrastinating on figuring out the hard bits. Would have liked to make to graphics by now, but so it goes!

Time for a retrospective on this DK30. I definitely made a lot of progress on Rust. My overall goal was to get past the initial stages, where I got stuck the last few times, and acquire a good working knowledge. Can’t become an expert in 30 days, of course, but I’m generally happy with the knowledge I’ve gained. I finished the Rust book and implemented a variety of game logic things in Rust; I made it past the hump, and I’m excited to learn more.

I definitely could have been more productive. There were a few 3-or-4-day spans where I got relatively little done. Sometimes that was because I encountered a difficult thing and didn’t want to deal. In the future, I’ll try either breaking hard things down into smaller tasks, or taking a break to work on a related task. I definitely could have convinced myself to work on some of the rendering stuff while I was procrastinating on the hard logic bits.

All in all, I declare victory.

kellswhere 2 years ago

So much for only having one more day of work to do on the hex library! Still not done. I’ve done a first pass on most of the functionality, but I still need to finish hex data storage and port all of hex chunking. (Making Minecraft-style chunks on a hex grid is actually really rough. You can subdivide a square into squares, but you can’t subdivide a hex into hexes! To make larger hex-shaped chunks that tessellate, you have to give them a little bit of a skew offset.) I also haven’t tested anything, so that might end up being a pain. I’d like to add proper documentation and publish it to crates.io as well, but I might let that wait until after I get going on graphics stuff. I really want to draw a triangle!

After further thought, I’ve decided to go with wgpu for graphics instead of a pure Vulkan wrapper.

  • wgpu is an extra layer of abstraction and might therefore be smoother for porting to various ecosystems.
  • My understanding is that a lot of the concepts are similar, so learning wgpu should teach me a lot about using Vulkan, and if I decide to convert to Vulkan in the future, it shouldn’t be too bad.

I’ll also take this opportunity to commend myself for providing an update after only three days, despite not hitting my milestone yet. That’s the system working as intended, and is a solid improvement from my last update, which took a whole nine days of radio silence.

kellswhere 2 years ago

I slipped up on my updates, and let it go a week and change. Not great, but we’ll take that as an opportunity to do better next time!

My goal for week 3 was to learn an ECS library in Rust and begin porting over some game logic from Unity. I settled on the hecs ECS library because it’s simple and looks like it’s still being updated. With hecs as the foundation, I’ve made a lot of progress porting things over. I found the entity and component parts straightforward, but the system part of the ECS paradigm in Rust had me struggling for awhile before I changed how I thought about things and got a basic resource gathering system up and running. That’s one of the cool thing I’ve found about Rust, by the way! The borrow checker can seem like a pain, but a lot of the time that’s just Rust telling you to avoid a harmful pattern that would sneak by in C# or similar.

The last big piece of the game logic puzzle is my hex library, based in part on Amit Patel’s excellent hex tutorial. I’ve begun porting it over from C#, but I’ve got another day or so of work left. Once I’ve finished with that, I’ll be ready to tackle week 4.

I’ve decided I’m going to try to learn the Vulkan low-level rendering API during this last week. My first goal will be to draw simple hex terrain. If I get that working with time to spare, I’ll focus on rendering buildings, or maybe on starting to learn a UI library.

kellswhere 2 years ago

I made it through The Rust Book, one day early! Lots of information to digest, and I’m pretty sure I’ve forgotten a lot of the stuff in the earlier chapters, but I’m eager to dive in and actually try making something on my own.

I think I’ll go forward with learning an ECS system for week 3. (The entity component system pattern is a data-driven design pattern that favors composition over inheritance, avoiding some OOP pitfalls and achieving great memory performance.) My plan is to make a game loop with console output and a simple ECS-based game state to iron out what I’m sure will be some preliminary issues with the borrow checker. After that, I’ll try porting over some of the actual game logic from my in-progress colony defense game.

kellswhere 2 years ago

Midweek check-in. I was hoping to be finished with all 20 chapters by now, but I’m only on chapter 18 - I got sidetracked thinking about Rust smart pointers and doing some IRL things. (And, if we’re being honest, also by Path of Exile!) I had enough of a buffer going that I’m still on track to finish by the end of week 2, though, so that’s good enough for me.

I’ve been thinking a lot about Rust’s borrow checker and its consequences for circular references. It’s impossible to create circular references in fully borrow-checked (“safe”) Rust. One solution is to use structs with safe APIs but unsafe implementations (RefCell<T> etc.). The Internet seems to think that while tools like this have legitimate uses, many new Rust programmers misuse them as a crutch to keep thinking the way they’re used to in other languages, instead of adapting to Rust.

I’m trying to avoid that pitfall if possible and learn to do things “the Rust way”. Here are two big instances where I might use circular references in other languages:

  • Large manager classes that need to link with each other to read state or pass messages. This is a bit of a code smell in general, and I’d say Rust’s borrow checker is helping us do things “the right way” by refactoring to avoid the circular dependences here.
  • Graph data structures. This one is trickier. In C#, I might make a GraphNode class with references to neighboring GraphNode instances. This doesn’t work in safe Rust without RefCell<T> or similar! One solution I see online is to move the connection data outside of the GraphNode class: for example, make an external dictionary that maps a GraphNode to a list of its neighbors. That’s probably what I’ll go with. It’s interesting to me, though, that “ownership” means something different in this context because it’s encoding relational data instead of the responsibility of owner to manage owned.

I’m sure there are other cases, including some that fall between those two, but we’ll cross that bridge when we come to it!

kellswhere 2 years ago

Week 1 check-in! Didn’t quite make my ambitious modified goal of all 20 chapters. I’m currently hip deep in chapter 15, though, five chapters past my original goal, so I’ll call that a win. The more I learn about Rust, the more excited I am to learn more.

Once I’ve got a basic idea of the language, the next challenge will be to figure out how to proceed with gamedev. The smart solution is probably to use Bevy, a mostly all-in-one Rust game engine that appears to be the leading tool of its kind. I’ve kind of got a hankering to mess around with Vulkan, though, so I might poke at some Vulkan bindings in Rust and see how far I get.

In other news, I’ve made the executive decision to relax my update-every-two-days goal and just try to update at least a few times a week.

kellswhere 2 years ago

I’ve made a strong push and finished the first 10 chapters of The Rust Book, my week 1 goal, three days early. Solid progress! It helped that I was very eager to get to chapter 10, which describes generics, traits, and lifetimes, all things I’ve been very curious to learn about. I’m going to aim now for a tentative goal of finishing the whole book in week 1, but I’m not going to sweat it if I don’t make it.

I have a lot of smaller details to work out, but the one remaining big piece of the Rust puzzle that I have to learn is how inheritance and polymorphism work. That comes in chapter 17. I’ll be very curious to learn more about how Rust approaches these topics in the context of its goal of zero-cost abstractions.

kellswhere 2 years ago

Ok! Dev environment is set up, and I’ve gone through the first four chapters of The Rust Book, putting me in a great place to hit my week 1 goal of 10 chapters.

I’m using VS Code with the rust-analyzer and debugging via the official C/C++ extension. I’ve hit a few minor issues getting everything running, but all-in-all I’m very impressed with the dev experience so far. Everything is lightning-fast, and rust-analyzer provides very helpful type annotations inline with my code.

One of my big gripes about Rust has been that its type inference system is incredibly powerful. You can define a variable with no type annotation, and the compiler will figure out its type because of how you use it 20 lines down. In my opinion, this makes code a lot harder to read because types aren’t immediately obvious. The automatic inline type annotation system goes a long way toward easing this issue.

Estimated Timeframe

Sep 12th - Oct 12th

Week 1 Goal

First 10 chapters of The Rust Book, with updates at least every two days on my progress and occasional thoughts.

Week 2 Goal

Second 10 chapters of The Rust Book, with updates at least every two days on my progress and occasional thoughts.

Week 3 Goal

Tackle one of these:

  • learn about an ECS system
  • draw a triangle on the screen
  • learn about a physics system

Week 4 Goal

Tackle one of these, different from week 3:

  • learn about an ECS system
  • draw a triangle on the screen
  • learn about a physics system

Tags

  • Rust