2024.9.1 released! Highlights + notes

luxe 2024.9.1 is available for testing!

Use version control/backup (always) and switch your modules.lx version over to try it and let us know if you run into any issues.

Introducing Wires (not public yet!)

Please let us make a proper blog before you show this to a lot of people or in public discords!

Make a trigger. Make a door. Now… go to code and make them work. What if you could connect them directly in editor?

Switch → Light. Button → new_game() - wires are a connection between entities (via modifiers + scene scripts).

Wires are a tool we had been wanting to add for A Long Time, and we’re excited to be at the point where this is available to test.

What are wires? If you’ve used Qt or any other signal/slot UI system or event based thing before, this should be familiar.

We also think making games should be a little fun, so here’s how they look in motion:

A wire is the ability to send a message (with data) to anyone interested in listening.

There’s two sides: A sender and a receiver. They don’t know about each other, but they can be connected.

Inside a custom modifier, or a scene script, create a function like this:

#wire = 1
my_function(entity: Entity) {
  Log.print("received a call for entity %(entity)!")
}

That’s it! Wire ids are simple numbers and should be unique within your modifier/scene script.

Now your modifier can be sent a message, from any other wire (of the same type).

How about sending a message? That’s easy too. Declare a wire variable, and call

#wire = 2
var release: Wire = Wire.create()
//...
release.send(entity)

Types… data…

See below, but a wire can send a block along it.

import "data/toggle.block" for ToggleData

//...

#wire = 2
#type = "data/toggle.block"
var release: Wire = Wire.create()

Later, when you want to send it:

var toggle: ToggleData = release.prepare()
    toggle.state = true
    toggle.ratio = 0.5
release.send(entity, toggle)

On the other side:

#wire = 1
my_function(entity: Entity, toggle: ToggleData) {
  Log.print("received a call for entity %(entity) with state %(toggle.state)!")
}

Work in progress

As always, this is new, there’s rough corners but let us know!

To use it in the editor, attach a Wires modifier to an entity (usually the sender), then select it and hit Wires on the right. Then drop entities onto the Send or Receive side, to start configuring them. Any wires visible will be shown there.

Here are some other highlights!

Modifier workflow automation

Make a blank file called system/some.modifier.wren and save it, hit build, and the engine will populate the modifier with a template.

Edit that and you’re on your way! We’ll expose this in the editor soon.

Modifier change handler

With the #emit_changes on your system class, your system will notify you when a field on an entity has been modified.

This is especially useful for editor related things but of course, is needed often.

Add the import for your fields enum:

import "system/puppet/interest.modifier.api" for API, Modifier, APIGet, APISet, Fields

Add the tag to the system:

#system
#phase(on, tick)
#emit_changes
class System is Modifier {

Listen for changes

change(entity: Entity, change: ModifierChange) {
  var data = get(entity)
  if(change.field_id == Fields.my_field) {
    //respond to change
  }
}

Modifier buttons

Leveraging the change system, if you make a number field that has a #button tag,

the editor will turn it into a button. See here in the discord

#button = "add interest nearby"
var add_interest: Num = 1

Clicking the button is number += 1, so you can respond to the change via the change listener.

Modifier Object/Array values (minor breakage)

Previously when accessing a field of a modifier or asset that was a block, it would return the raw block and you’d make a wren object from it.

This isn’t the case anymore, it will act as if it was a regular wren object, allowing accessing the fields directly.

This is true for arrays, and arrays of objects. Previously adding a value to a block array was manual, now you can do:

var list = data.items
  list.add(value) //if primitive only!
  var obj = list.add() //objects
    obj.field = 3

Keep in mind, these values are a little special, so cache a local variable and reuse it.
Also try not to keep references, as they can point to dead entities or instances

Stage type

Often when working on multiple scenes, you want to open them all as one unit.
This is called a Stage, it’s a container of scenes to load.
You can do that now by creating a stage type using the editor.

These are not treated any special way, it does what you think it does, and is wip.
e.g there’s no way to unload the grouped stage, and no way to edit the asset in the UI.
You can edit the file of course, it’s a simple lx file.

Skeleton blend graphs and animation

Something we’re using in archives and other 3D users will find useful!

We’ve been adding these in the background for a while, but we now have easy to use blend graphs. This allows complex character behaviours expressed in a simple way.

Here is how you would have a walk animation, followed by a hand IK node, and a head look at IK node.

There’s Blend, Two Bone IK, Look At IK and CCDIK to start, with more to come.

Here’s how that looks:

Block types

Often you might want a block definition for your own needs (as we’ll see later).

You can now create a my_type.block.wren - with the .block.wren extension.

Here’s a toggle.block.wren type we can use later, for example.

Note these complement asset types, you don’t need to use these for custom asset types!.

#block = data
class ToggleData {
  var state: Bool = false
  var ratio: Num = 0
}

Other notes

Agent

The agent is sometimes unreliable, sometimes memory hungry and sometimes created many instances. We’ve tracked down at least a few potential causes and are continuing to make it rock solid. Let us know your experience!

Fix error about omni.wren

Was a minor nuisance but should be gone now.

Draw style helpers

Often it’s nice to reuse a path style, now you can modify some properties inline:

Draw.line(.... , style.color(Color.pink).thickness(2))
Draw.line(.... , style.color(Color.black).thickness(0.2))

Entity.name(entity)

No more %(Strings.get(Entity.get_name(entity)))!

Just Entity.name(entity) will suffice. It also handles invalid entities! Much nicer.

Transform look at inverted

When using Transform.look_at the vector was flipped (because of camera usage being a common use case).

A little oversight now fixed. If you find your look at is wrong, there is now an invert argument to use it both ways.

This is cos camera forward vector isn’t in the same direction as the look direction cos reasons.

Var explicit initialization not happening sometimes

We found a gap in the var declarations in classes when inheriting!

If you were using class vars with custom modifiers or scene scripts, and they weren’t initializing, add this:

//required atm
construct new(world: World) { super(world) }

The parent class initializes itself, but the child class isn’t given the chance.

We’ll fix that but for now you can work around it.

Other Highlights

  • IO; add Handles, this allows storing Wren objects in a numeric Handle (like luxe does), for e.g storing in a modifier field
  • String; Str.template for templating strings
  • Script; speed up wren compiling quite a bit
  • Cable; a simple 2D/3D cable simulator is luxe: cable
  • Sprite; access to the effects API from code is now on Sprite API
  • Modifiers; better error messages in cases where it’s unclear what’s going wrong
  • Modifiers; access to Thing.id e.g MyModifier.id for the type id (built in wip)
  • Modifiers; fix #phase tag, can now used as intended e.g #phase(before, tick) and #phase(after, late)
  • Block; options type would get confused about which type it was when no default was specified (arrays, usually)
  • Block; ui fields for link types allow dropping onto the array itself, much faster workflow
  • UI; Tabs; change events for tab changing
  • Assets; don’t recompile fonts + meshes every time, use the cache as intended
  • Physics; physics assets visible in new world editor

There’s a lot

Of things in there and we’ve got more landing soon, so let us know how it goes for you.

Enjoy!

5 Likes

Yoooo these are all really awesome changes!!

1 Like