Project Review

Game concept: To what extent did your game concept change from initial concept to what you implemented? If it did change, how did it change and why?

Our game concept has remained largely the same since the first day of the course, when we sat in those cool rolling chairs. We set out to make a chair racing game, and our final product has remained faithful to our vision for it as that. Audience interaction was also central to our initial vision and remained a major part of the game experience.

Design: How does your final project design compare to the initial design, and what are the reasons for the differences, if any?

Time constraints and wanting to make a more innovative concept were big factors in the changing of our initial design. Our idea to include powerups was scrapped around week 7 in favor of focusing on improving the audience interaction, which was a more original of the two ideas. Aside from this, however, our final project realized most of the initial design ideas: We implemented all of our original chair ideas, and even gave them different play styles. Additionally, a lot of the early concepts for potential audience interactions have made their way into the final iteration of the game.

Schedule: How does your final schedule compare with your projected schedule, and what are the reasons for the differences, if any? (You should be able to glean this from your status reports.)

We originally sought to have an MVP done by the end of week 6. This didn’t happen - we didn’t come close to this until week 10. I think we didn’t revisit our plan each week which I think would have helped us to better define what work we needed to do early on. There was alot more time earlier spent ‘waiting’ for code, and we could have prioritized building out features that unblocked us earlier then (ie unlocking everyone to work on ui graphics stuff earlier).

General Questions

What software methodology and group mechanics decisions worked out well, and which ones (if any) did not? Why?

  1. Our biggest departure from traditional 125 projects was our use of Rust, and we think that this overall was a great decision that made many parts of the project better. In particular, Rust has an excellent package management system, compiles fairly well across different problems, and of course by design has many fewer memory errors than you’d expect from C++. Rust libraries are also very mature and we were able to find libraries for everything we needed without difficulty (see later for specifics).
  2. We also took a very “industry-like” approach to pull requests and merging: we (mostly) reviewed each other’s pull requests thoroughly, (mostly) kept all work on branches off of main, etc. (Check out our commit history!) This was less true for graphics code, where we didn’t have a second person besides Nick with a ton of expertise in the weeds of graphics such that we could really do detailed graphics review; we also had peer review become much more cursory in the last few days of the project, although we still reviewed code semantics. Nevertheless, we think that this was overall a good choice; it saved us some headaches on code that multiple people touched. We only broke the code once with a hasty merge, and we were able to fix the issue relatively easily.
  3. We also had a lot of CI/CD going on, with automated testing (although, truth be told, that was not particularly useful - game code doesn’t usually work well with unit testing), automated build packaging, and packing our resources into the binary - those last two in particular meant that our demo day experience was relatively smooth; we just had to download the pre-built executables and the one asset (the racetrack) too big to fit in the binary.
  4. organizing everything into a core / client / server / web structure. core shared types between client and server, making it really easy to build things together. This structure overall just made development clean + organized.

Which aspects of the implementation were more difficult than you expected, and which were easier? Why?

None of us were very experienced in Rust before starting, so we didn’t really think about the fact that the data structures and general approaches we had to use should have been tailored to the constraints of Rust. For example, we initially used a tree-based scene graph for our graphics code; unfortunately, getting ownership and mutability right for a tree when you’re trying to mutate some of the nodes in the tree turned out to be pretty difficult in Rust, so we switched to a flat indexed vector-like data structure instead, which turned out to be a better fit for Rust’s memory model. Another example is that the physics backend for moving players around is awkwardly split between immutable and mutable functions to get around Rust constraints around mutability - in an ideal world, the one small section of that code that needed to operate immutability wouldn’t have condemned all the processing code after it to be immutable as well. (For anyone trying to use Rust in the future: watch this talk and/or read the linked blog post! I really wish we had seen this; we probably would have avoided some of the annoying false starts we had in developing) (Alistair)

UI implementation was weirder than expected for me personally, but it was cool to figure out a solution by heavy use of putting the ui in the background + using images for everything. (Ronak)

Networking was stupid easy to pull off and there was almost no additional work to do on that side after week 2, which was unexpected. (Aaron)

Graphics ended up being quite a bit more time consuming then expected since WGPU is a bit lower level then OpenGL. (Aaron)

Which aspects of the project are you particularly proud of? Why?

  1. Our networking approach was very nice, Aaron set up a nice setup with enums that made adding datatypes to send data super smoothly