Jenztsch

joined 5 months ago
[–] Jenztsch@discuss.tchncs.de 3 points 1 month ago (1 children)

Do you have any sources about this "unfitness" of Rust for gamedev? From my experience many people have problems with the borrow checker due to habits they obtained coding in other languages. Due to the strict enforcement of ownership rules some things can't be done exactly like in e.g. C++, but the language offers the tools to design and implement the software in a way to work with (not around!) the borrow checker (an example would be the discussion in another comment thread).

So I'd be interested what special behavior occurs in gamedev that makes coding in Rust more difficult than for other software.

Also, I really like that you're considering users with lower spec machines for your game. However, have you run a profiler over your software to see where there is optimization potential? In cases like this, I often use the (maybe over-used) quote from Donald Knuth:

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.

Many people think that with this quote, no optimization whatsoever should be considered. However, humans are often bad predictors on where the real bottlenecks are.

So yes, have some things in mind like e.g. algorithm performance for the expected input sizes. But in many cases, "optimization" done doesn't impact the runtime at all but makes the code much more difficult to understand and often more "unsafe" due to potentially increasing UB or other issues.

For this, a profiler helps to detect where your "critical 3%" are. And when you know them, then you can start optimization work to get big improvements. This also helps to direct your most likely limited effort to spend to the important parts of your game.

[–] Jenztsch@discuss.tchncs.de 1 points 1 month ago (1 children)

Then I think RefCell is exactly what you want to defer the mutable borrow to runtime instead of compile time: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3170c01849dc577a501ecb11dd44c5ba (source for this method on StackOverflow).

Maybe there could be syntactic sugar to use captures implicitely as RefCells inside a closure. But I would not be a fan of implicitely allowing multiple mutable borrows without any clue for that in the code.

[–] Jenztsch@discuss.tchncs.de 3 points 1 month ago (3 children)

I'm not sure how you intend to use this. When no variables are captured, the borrow checker will not have any issues with the closure method.

When you are still capturing, you could implement a macro like one answer suggests. However, IMO this highly depends on the complexity of the duplicated code and even then I don't immediately see what the benefits compared to extracting it as a closure/function are.

[–] Jenztsch@discuss.tchncs.de 6 points 1 month ago* (last edited 1 month ago) (7 children)

This is entering subjective taste, but in my opinion this also is a feature of Rust. Especially when the closures are more complicated, it may be not as obvious if and where they are changing state (the fact that Rust implicitely mutably borrows the variables to the closures doesn't help either).

So a solution of this issue for me would be to add the changed variables as parameters to the closures and explicitely mutably borrow them at the calls in the loop: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=78cc7947e2e0b07b54baf6e1a75a2632

I would agree with you that this increases code verbosity. However, this would be a price I'm willing to pay to help understand at quicker glances what happens inside this loop.