dev log #15 - try luxe now!

As we continue to wrap up our goals for a wider release we're happy to mention that you can try luxe already! Read this for details + a dev update.

dev log #15 - try luxe now!

Hello again friends!

As we continue to wrap up our goals for a wider release we're happy to note that you can try luxe already!

Is it 'done'? Is it perfect? Nope!

There is a download page with some expectations, links to some documentation and tutorials and we've got a roadmap (see below) to our first major checkpoint we call '2D ready'.

We're constantly improving the experience, documentation, and tools so check back for updates.

Reshare this post on Bluesky
Reshare this post on Mastodon

Preview plans

Here's some past and present things around the preview!

Join the community

Share your experience! We use the community forum as our main home, so we'd love if you joined and shared what you're making, any issues you're finding and your experiences.

Soon: luxe preview jam

We also have another game jam coming up for the preview, we'll let you know when!

The jam will be relaxed and plenty of time. We will also have some optional prompts to make something small to learn what luxe is like, in case you don't have time / bandwidth to think of or make a whole game ✨

Shadow drop

Back in January we put the preview up without saying too much (we hinted at it in a few spots!) - so there has been some testing so far and we've been continuing to land the rest of the big items for the big checkpoint.

We're now at the point where more testing will be useful, so come make and break stuff!

Sustainability

If you've been wondering how we planned on making luxe available cost wise, you can now read about our model on the download page. We're happy to see a bunch of people supporting the engine already, even from day 1 of the shadow drop <3

Roadmap

and the '2D ready' checkpoint? This roadmap also includes some of the things already done for clarity.

Visit the roadmap to read all about it!

If you have questions or something is unclear, let us know.

When that lands, we also have a new luxe website landing, you can sneak peek the branding style in the main image of this post!

Dev updates

We're always making progress on luxe because we're always using it to make our games. Every day! That means we're frequently iterating out frictions that slow us down, but also many of the roadmap items are things we'd need to ship.

Here's some updates on some recent things that we landed.

Animation

One of the biggest things we've been landing recently, Ronja made a branch and revised the animation system, and built a new animation editor.

For some context, the old world editor used to have an animation editor, but when the new world editor landed with the final data model and better handling of all things editing, the old one stopped working (unsurprisingly).

More so, it was designed for a different workflow, and now that we've had the time using it and making games with a lot more animation needs, it was time to revise. How we work with animation, how animation works with data, how animation previewing works and all that fun stuff needed to be redone.

Like most things, there's rough edges (preview and all) but we're rapidly iterating on the polish and experience of editing animations 🍂

Local animation

For a lot of animations we don't actually want to have to create a whole separate asset for the animation, instead, we'd prefer if the animation was stored inline, directly in the scene/prototype where it lives. Now it can!

This improves the clarity of the workflow, for the most common case, you can animate something within a few clicks. Of course if you want to share the animation, you can convert it to an asset as well.

Here's a 1 minute clip of creating an entity, attaching a sprite, anim and transform modifier, and animating the transform y value.

0:00
/1:00

Modifier animation track

One of the other new benefits of working in the new efficient data model is that we can now animate any of the fields in any modifier attached to an entity. This all happens very efficiently in the core code in a snappy way.

This simplifies workflow as well, as 'how' is always the same answer!

Sprite animation

The sprite animation track is also back with a new workflow as well, being able to easily pick the visual frame (or enter a number). We have some other nicety for the sprite track coming but it's already useful!

States

State machines are a useful concept in a lot of use cases, menus, gameplay code, NPC logic and so on. We've recently added states to the Scenes and Modifiers, which means your systems and game code can easily opt into using them. If you don't use them, they don't exist (so no overhead!).

Declarative states

The style of state machine is a declarative approach using a builder/fluid style API, and supports transitions from modifier/scene tools like the per entity data, wires, time and so on.

A simple example would be a menu.scene you create, where it might have main, settings, credits states for the menu. This is what that looks like right now, in the scene script:

That’s it! The names match the variable, this is important for later as we’ll see.

Our scene or system also has the states variable, which we use to change states directly like so states.goto(scene, main). We do that inside of ready() in a scene script to set the default state. We can also add behaviour to the state, like so:

Here we have a function that’s called on entering the state, leaving the state, and what we call a transition. This transition is a function that returns true or false, and if it does, changes states to the given state (in this case, pressing escape will go back to the main state).

Nested states

A common pattern that can reduce code complexity and allow sharing more code across states, is nested states. This has different names like nested states, parent states, HFSM (hierarchical finite state machine) and such.

These states typically run at the same time as their child states, allowing the transition code to happen at the parent and be defined once only, and handle specifics in the sub state.

As an example, take an a character that has an idle state. Within our idle state, we might decide to tap our foot, look around nervously, check our watch, wave at someone, and yawn. Each of those can be viewed as a sub state of the idle state. To the ‘outside world’ we present a simplified interface, we’re in the idle state, but within that we’re doing all sorts of stuff.

Let’s see how we declare that now, and this time we’ll do it inside a modifier (per entity we’re attached to).

This API is declarative, this code doesn’t do anything per se, it just defines the state hierarchy for us! This also shows why we use the names, notice how the type of the idle variable is a known type.

That means we get nice completion on our states, like this:

Simpler states
For the simpler states like looking around or tapping a foot we can do something simple, like this:

Notice that we do it inside attach, we’re defining the idle behavior for that specific entity

Transition helpers

We’ve seen goto_after but there are a handful of other helpers.

Wires are the event system backbone for scenes and modifiers, so if we receive an event we can use that as a transition. We can also key on our Data class, listening for changes and responding to raw data changes.

Other notes

We have more transition helpers coming, as well as making it easy to add custom game specific transitions allowing expressive easy to understand declarative gameplay code in the same workflow.

You can mark a state as persistent, root.persists(true) will keep the root state active and running alongside other states. This is useful for ‘watcher’ states that handle transitions at the higher level.

You can do stuff on reenter, if for example you go from idle.yawnidle.stand, you’re staying in the idle state, so it’s not “entering” the idle state, but it does notify that it is reentering.

Visibility

The initial foundations for visibility also landed recently. For a variety of reasons we left that to user code before now but it’s now as easy as Entity.set_visible as you’d expect.

There’s also a visibility tag argument, where different ‘competing’ things controlling visibility don’t need to worry about the binary state, just their own and it’ll work.

Nothing too surprising here, it’s a simple API + a quick editor toggle. Now that the base is here we’ll answer the rest (like how saving visibility works, the relation to modifiers and how that looks is why this was a question mark for a bit - it’s a design problem we wanted to spend some dedicated time on, the code is easy).

0:00
/0:06

Other stuff

Feel free to read through the recent release notes, you'll see a lot of the above and more.

Enjoy!

And we hope to see you in the community!

Download luxe here.

We look forward to seeing what you make, what issues you find, and appreciate you jumping in during the preview to help us make the 2D ready launch really solid for everyone else.