Looking at cgmath, it seems that it’s not well maintained anymore (the owner was just recently asking for new maintainers). I haven’t looked too much at nalgebra yet, but my boss is in love with it.
Haha, that would be me! Yeah, I recently made an issue about this. Lots of people seem to be getting on fine with cgmath for the last several years, but alas I haven’t had the time or head space among my other commitments to clean it up and give it the love it deserves! It has been through many iterations during the early years of Rust (I think I started it back in late 2012), and I never really managed to land the API in a state I was happy with after getting burned out just before Rust 1.0.
I’m hoping that in passing it on I might be able to empower other people to make decisions that are more grounded in the reality of game development.
nalgebra has by far the best chance at longevity out of any known Rust math library.
- @sebcrozet’s Patreon campaign is edging ever closer to a monthly patronage that’ll support a steady part-time commitment on his part.
- No other Rust physics library comes close to nphysics. If Rust gamedev takes off there’ll be plenty of commercial interest in such a library, which could support a whole team of maintainers.
- It has excellent documentation
- It has a forum that’s well tended to, further adding to the public knowledgebase.
If the community can’t come up with a way to standardise on nalgebra I strongly suspect we’ll be back here in a year from now with another call for cgmath maintainers. Thanks to nphysics, nalgebra will see increasing adoption, but the community appears to favour cgmath as far as plain math libraries go.
Looking at nalgebra’s progress over time @sebcrozet has made a lot of changes as a result of constructive feedback. The main problem appears to be a lack of feedback from the community. Understandably so, because it’s easier to just switch to cgmath and not make a fuss. But I think if the Rust gamedevers were more outspoken about why they prefer cgmath over nalgebra it’d be a net gain for everyone.
But I wanted to direct you (and anyone else) to this internals thread as well:
It might not be ready tomorrow, or in six months, but anything involving official support for units of measurement would certainly help both nalgebra and cgmath in the long run.
To be honest, as a game developer I don’t need a general purpose linear algebra library. I need a lightweight math library with a focus on computer graphics; 3x3 and 4x4 matrices, 3- and 4-element vectors, quaternions, and that’s about it.
I love vector libraries, but having made a lot of raytracers and some raster(ers?) I can say it’s been the same for me. I haven’t needed anything else from a library user standpoint when making graphics demos.
A recent quote from the community rust discord #gamedev channel:
meshpotato: Hey guys, any suggestions for a math crate good for gamedev with OpenGl? I’m currently using cgmath. Just wondering what other people are using
impl Learning<Rust> for Gegy: Personally use cgmath too
ozkriff: +1 for cgmath - it’s API is simple and it’s capable of most of the gamedev-related math
meshpotato: Yeah, okay, well then I picked the right one it seems
ozkriff: I’m using nalgebra for Zemeroth atm, but it’s because ggez engine uses and reexports it so it feels wrong to add another math library on top of this
meshpotato: Makes sense, haven’t checked that one out. Might just give it a try too
unreachable!(“Leah”);: using cgmath as well
ozkriff: https://github.com/ggez/ggez/issues/106#issuecomment-389985651 - nalgebra is a good library too, but I find its API too complicated for my needs
ozkriff: i have a feeling that nalgebra is more popular mostly because of the http://nphysics.org/
Nalgebra and cgmath have greatly converged in terms of APIs, so I don’t think it’s too hard to switch between them. This is one of the values of having good algebraic foundations! We eventually hoped to standardise on alga. This was an iteration on algebra, which was in turn an iteration on my attempts to bring a numeric tower to the std:
Sadly I never held up my end of the deal in cgmath, so alga integration hasn’t landed. I have a decently nice tower that I’m happy with for vector spaces, but the documentation is lacking, and I didn’t get around to extending it to numbers and transformations (was running into trait bound issues with that).
I really think there’s value in keeping to thinking in terms of algebraic foundations, and progressively teaching them to game developers and artists. But I’ve found it difficult to make it look nice in Rust. Perhaps cgmath could benefit from some inherent methods on the types. These would just dispatch to the ones implemented on the cgmath traits. This might make it easier to navigate the API as a newcomer. Perhaps nalgebra could benefit from that as well.
Anyway, all this being said, I am perfectly fine if the new maintiners of cgmath want to take things in a different direction. The challenges in this space are real (wooo floating point), and I don’t begrudge them if they just end up ripping out the algebraic stuff.
Here is a good exprience report from the nanou maintainers that might be interesting for others to read. I don’t necessarily take this as ‘artists can’t learn abstract algebra’, but more that I failed to provide good enough progressive disclosure in my API design, and documentation, tutorials, and help. I think Rust’s syntax for traits might also be fighting us too, and some of the Rustdoc formatting.
A quote from the gitter rust-gamedev room:
@kvark: Math vendors lean to genericity and abstraction. Math consumers demand simplicity and lightweightness. Clearly a disagreement, and we don’t have a clear vision on what a simple math library should be like.
I think that’s all the more reason to standardise on whichever library is sure to be maintained in the long run so it can evolve in lockstep with the needs of its users.
One thing I missed (after a cursory look) in the nalgebra docs was some justification for why things have been implemented the way they are. The vek crate for instance goes into great detail about the reasoning behind its design decisions.
It’s not really my place to say, but I can think of two straight forward solutions to that:
Split nalgebra into two or more libraries. I don’t think that’s a good way to go right now.
Make the game-specific features of nalgebra more accessible, e.g. with gamedev-specific tutorials.
Here is an idea: what if we created a crate that would just be a simpler facade to nalgebra? I’m thinking of a crate implementing the exact same functions as glm (which is a very renown C++ library) but taking
nalgebra types as argument. Such a crate would be maintained by me as well as the rustgd organization (if they want it). Because this rust glm crate would just be a set of free functions taking
nalgebra as input types:
- There wouldn’t be any issue regarding interop with libraries like ncollide/nphysics.
- Maintenance of glm itself would be easy since most of the core work would happen on nalgebra itself anyway.
- Adoption should be easy since glm as already a well-known C++ library that has been around for years.
Is this something worth considering?
All problems in computer science can be solved by another level of indirection, except for the problem of too many layers of indirection. – David J. Wheeler.
It actually may solve most of the usability issues, but what troubles me is that all this types/traits complexity that Rust is barely capable of expressing (one symptom of this is that native docs at docs.rs/nalgebra are more or less useless for newcomers atm) will still be there one layer below. Not sure if that’s really a problem that we should care about or what are the exact consequences of this, but personally I’d prefer the linalg library of Rust to be more straightforward and not stretching the language to its limits even in its implementation.
I think some beginner issues with
nalgebra can be partially improved by making
rustdoc to show all implementations for a given alias, ideally with inlined types if they get pinned by alias. It should make indirection problem significantly less painful. Have this option been discussed?
I’m also personally a user of cgmath over nalgebra. In a small toy project, done using ggez, I’ve actually started with nalgebra (because it’s what ggez uses), but then switched over to cgmath.
The commit where I did that is there:
The reasons behind the switch were mostly around ergonomics of the API, as well as of the documentations. As was stated before, nalgebra does way too much for my normal gamedev usage. It also doesn’t do some things that I needed (or I failed to find them), such as getting a squared vector magnitude (to avoid doing expensive square roots where possible).
Very interesting! Yet nalgebra would be great to use eventually, because of its integration with nphysics/ncollide. I really wish there was a way for us to have our cake and eat it on this one.
That’s kind of why I brought up progressive disclosure of complexity as a tricky design/documentation problem to solve. We want to expose powerful ways of combining algebraic structures, but at the same time we want to avoid scaring off newcomers who have yet to take all the rounds of iterative deepening we (as library authors) have taken. Ideally our APIs and documentation should help our users on that journey for as far as they want to go, without having them to do it all at once (which is an impossible task for most humans).
Yeah, I’ve found that two element vectors are also occasionally useful, but beyond that there really isn’t more I need from a math library. It isn’t clear to me what use games or 3D graphics has for the abstractions in nalgebra or to a lesser degree cgmath. I rarely find myself abstracting over scalar type, and I’m practically never in situations where my code can be generic over dimension: 2D and 3D end up being quite different, and any time I’m using 4D vectors they’re in homogeneous coordinates which makes them different as well. Abstracting over whether something is a vector or a matrix, or using any sort of dynamically sized matrices just doesn’t really come up at all.
Even having a separate notion of a Point type always seems to be more hassle than it is worth. Mathematically points and vectors aren’t the same thing, but any time I try encoding a position as a point sooner or later I invariably run into some reason I need it as a vector. For instance converting to a global coordinate system when given a point and the origin of the local coordinate system that point is in, it is necessary to add the two points, even though this is one of the main operations that points are meant not to have.
More broadly, I’m not really sure what problem we’re trying to solve here. It would be good to have someone to merge any bug fixes/documentation tweaks that come up, but in general the current cgmath crate works quite well as it is, and it isn’t like math is going to be changing any time soon. Better interoperability would be nice, but even just exposing some zero-overhead conversion functions between different libraries’ types would probably be fine.
I think that https://github.com/kvark/mint is more or less a standard for this for this at this point.
Indeed! I’m not sure how I missed it… Thank you.
I agree with @newpavlov, a “flatter” documentation might help with discoverability issues such as this. I also wish that RLS/Racer could be better; it’s not doing much for me with nalgebra (nor cgmath, really, but the doc was easier to read).