Gooey Updates: Text Input, MSAA, and a new math library

It’s been two and a half weeks since the last update, but I’ve been busy. I’ve stayed focused on the Gooey ecosystem, but I’m very close to switching back to BonsaiDb to pursue the next chapter in our architecture.

Text Input

Adding a simple text input widget was a lot of work. For example, before even starting on the input widget, I needed a way to draw borders – because that’s how the focus ring was going to be drawn.

However, despite the challenges faced, I updated the previous implementation from Kludgine and got it working:

As you can also see, I’ve added a splash of color by adding a Palette trait with a primary color.

As part of this, I also spent a fair amount of time making keyboard focus work as expected:

Keyboard focus is still a work in progress. The first implementation of TabIndex requires global indexes because of how the browser works. I’d like to alleviate that requirement, so that components can have their own internally consistent tab order, but it will require a lot more DOM management when widgets are added/removed.

Introducing figures

As I was updating my old text input code, I became more and more unhappy with a few issues I had with the euclid library. It’s an excellent library, but there is one issue that affected my personal desires of my APIs and code usage: most APIs do not use the Length type. I worked around it in Kludgine by using extension traits, but as I was pondering whether I wanted to duplicate those traits between Kludgine and Gooey or create a create just for those traits, I realized I also had a few other changes I would do if I were implement it myself.

So, I decided to write my own library: figures. It is very similar to euclid, but doesn’t have nearly as much functionality. Specifically, it only has exactly the things needed to implement Gooey, Kludgine, and easygpu.

The real win, to me, is the Displayable trait. Rust doesn’t have trait specialization, but through associated types, I was able to create a very useful concept: DisplayScale.

The idea is pretty straightforward: When rendering graphics on the desktop, the end result are physical pixels being rendered. However, different monitors have different resolutions, so often there is OS-level scaling to help make displays more readable. Finally, as an author of an application/game, you may want to give users an additional zoom setting for your user interface.

That’s what DisplayScale wraps up into one type, and Displayable allows you to convert between the three representations. The Renderer trait has been updated to accept parameters through this trait, which enables you to do your rendering math in whichever scale desired. When passing in Pixels, the code path boils down to a copy, ensuring that your floating point math doesn’t get muddied with precision loss of unnecessary conversions.

I plan on adding some more functionality to figures over time, but I don’t expect the number of types in that library to increase significantly.

Multisample Anti-Aliasing

I added MSAA support to easygpu, and enabled it by default in Kludgine. The net effect is that 2d shape rendering will look much cleaner. In the current examples for Gooey, since everything is drawn as a rectangle, there aren’t many opportunities to see it in action. However, in our headless-captured examples, we can see the before and after effect on the dynamically rendered cursor.



Moving Kludgine Forward

As I finished hooking up figures, I started feeling like Kludgine was getting ready to be called 0.1 finally. I spent time updating the ecosystem to wgpu’s latest release, and put together the first release of Kludgine in 11 months: 0.1.0-dev.0.

It’s funny to see that lapse in updates. It represented my struggle of implementing my user interface library the first time through. Rather than a small game engine, the codebase peaked at 18,695 lines of code, according to tokei. Today, it weighs in at 7,481 lines of code. There’s still a bit of code I still want to rip out too!

This leaner version of a 2d rendering layer is much more focused and thus, much closer to an actual 0.1 release. I’d like to figure out what I’m doing with the tilemap code before I officially release it as 0.1.

On the horizon: BonsaiDb tease

While I’ve been hard at work on Gooey, @dAxpeDDa and I have been starting to think about the next steps of getting us towards our goal of developing Cosmic Verge. Despite being eager to work on Cosmic Verge, we’ve been talking about our goals for the project’s we’re building.

As you’ve heard me talk about in this post already, we believe in modularity. We also believe that BonsaiDb empowers developers to create secure, database-driven applications. We have lofty goals for many aspects of Cosmic Verge, often because we want to do things “the right way.”

We’ve known since March what we want our chat system in Cosmic Verge to support: end-to-end encryption (opt-in on a per-conversation basis), group messaging, out-of-game access via the web or an app on your phone, and more. If we’re going to such extents to build the standalone experience, and it’s all open-source, why wouldn’t the chat functionality be able to be separated from Cosmic Verge?

Thus, the tease of where we’re going soon: BonsaiDb packages. We are envisioning a way to distribute packages with semantic versioning that can interoperate with each other. The chat package will be consumed and extended by Cosmic Verge, and likewise, if it suits the needs of any other developers, they can build atop it as well. Packages will be able to be consumed natively or dynamically using WASM.

With that said, we still have a little more work we’re planning on doing in Gooey before getting back into BonsaiDb. I want to be able to write management user interfaces in Gooey, and we need a little more functionality before we’re ready to do that.

I look forward to sharing more about the vision we’re working towards! In the meantime, if you want more timely updates, definitely come by and chat with us on our Discord server.

Thank you as always for reading.