Subscribe

luxe alpha-2.0+0010 recap

Menu

This alpha was named after 0010 games, and they have been earning it (a joke). Since the initial post, they have taken the game to GDC, PAX, gotten coverage in multiple print magazines in different countries as well as numerous online articles, all of which you find on their twitter profile.

The game is coming along in strides, and I can't wait to play it properly myself. This is from their twitter, a WIP trailer:

For this focus sheet,

I had a lot more deliberating and distractions than I imagined. I covered a lot of the stuff that I was thinking over in the dev logs and ended up on a few different places than I suggested previously - I'll go over those later but let's have a look at what happened in alpha-2.0.

noteable new features

While a lot of the stuff in alpha-2.0 was specifically resolving issues and problems with the code, there were still some nice new things along the way.

cross platform key:value store

Implemented in snow and exposed via Luxe.io.string_save(key, value, slot=0) and Luxe.io.string_load('key', slot=0). These do what you'd expect, and they save the data in a platform consistent way (web using local storage, etc).

They use your package id (com.luxeengine.blah) - so follow the general “Reverse DNS” naming conventions. They are stored with relatively useful obfuscation - which prevents the most basic abuse of the save data by the largest majority of users. You can always pass already encoded/encrypted/whatever strings, if you feel the need.

This is a decent solution for save games, preferences and more, so use it as you see fit. The slots aren't a limited number they just append an integer to the end of your id's, so you could even use the slots as a subset of data. i.e inventory is slot 0, message history in slot 1. It's up to you.

asset reloading and such

While there are not automatic systems handling this for you, you can now at any time grab a Resource and call reload. This only applies if the resource actually comes from a reloadable source, like a file based id. If you create a Texture from pixels and call reload, it's going to give you trouble because it would be doing what you told it to, but you would be making an error.

Future additions will compliment this system nicely, and flow sync command was added already to keep your assets synced from your project folder (i.e /assets) to your output folder (i.e /bin/target/assets). Try it out by running flow run --sync on a native build, and modify the source asset. It will pull the changes as soon as it sees them into the running folder, so the game can see it. It doesn't prompt btw, so be wary that it does things you tell it to as well.

Since snow already supports file change notifications on native desktop platforms, you could easily hook the 3 together, to have automatically reloading assets while you work. Even though this API and that API aren't 100% complete, you can still really easily use them. Here's a simple example:

Actually...

Writing out all the changes this way will take forever. Take a look at the list of changes in the most recent commit for alpha-2.0 below.

Only some of these are aligned with the actual task list : which has it's own 25 tasks that were almost all done (some were moved forward, with reasons logged on each issue). That doesn't even cover all the stuff that was fixed or added for LD (mentioned further below). There's a whole lot of commits in between all that, which you can always view here. There's a bunch of things like accelerometer fixes, and all sorts.

I'll try to get into more detail in the dev logs, but there's a lot to cover so I may gloss over a few lesser notes.
Even the resource stats view got a nice clean up in passing!

Parcel:

new Parcel implementation

update options and creation options for all new resource types and settings

initial work toward parcel diff loading

add parcel event endpoints, for progress, complete, failed events

added ParcelChange type for information on progress or failure events

added length properties for counting resources

added state, for unloadedloadingloaded

added listed which returns an array of resource id's in the parcel

added loaded which returns an array of resource id's that are loaded by this parcel

when submitting, compressedTexImage2D would be used instead of texImage2D

Screen:

changed w and h to Int type

added width and height to Float if needed

removed redundant cache values and error prone sync code

added bounds getter, returns a luxe.Rectangle for convenience

clarified that mid, size, bounds will return new instances

this is because cached values get modified by user code

immutability is in the new vector code for later alpha

Shaders:

implement new resource api

reload() / clear()

only set uniforms that are found (not all 8 for no reason)

added luxe_no_shader_prefix define short term

you don't need to define this unless you need to

clone requires an id for the clone (see below)

removed all inconsistent verbose flags and fixed error logging to be more logical

unified naming of vert_id and frag_id

gave a proper resource id, must be unique like all resource id's

that means the | combined stop gap is gone

when creating or specifying for loading, vertid, fragid and id are required

move to be explicit for usage code clarity

in the cases where you left one out:

use 'default' for vert_id

use 'default' for untextured and 'textured' otherwise

BitmapFont:

implement new resource api

reload() / clear()

remove from_string and other static api's

use new BitmapFont({ id:, pages:[], font_data:string });

moved parser and types into luxe/importers/

RenderState:

add bindTexture( type, tex ) abstraction

add bindTexture2D/bindTextureCube implementation

add ResourceState.boundtexture2D/boundtexturecube

for cases where the currently bound TextureID may be useful

Deliberating

A lot of the time spent on this alpha was mostly implementing things and seeing that the ideas weren't lining up, or that the implementation was backwards and inflexible, but the outcomes are good.

I felt a little unsure at times, about what road would be best for things like the load/fetch changes to the resources but once I had it working and the code became much more explicit and clear and the concept of “You must have a resource in order to use it” just makes things a heck of a lot cleaner and simpler all round.

In the end, I am quite happy with where all the changes landed, and I have already tested a couple of the new features in a few projects already, most of which are already rolling on cubemaps and live reloading and the works.

There are still a few things to be done, that's for sure, but the direction is a good one, and I feel confident that when the last of the resource management features like tagging and parcel diff system (unload unused, load new, keep shared) come into play, and the parcel backgrounding and streaming facilitation these efforts are going to work out great.

Distractions..?

Distractions is an odd word, it sounds quite negative, probably because it is a ... let's use “detours”.

Ludumdare 32

This last ludumdare was really fun, there was a lot of interesting bug fixes, and a lot of interesting games to come of it. A special thanks to all that participated, files reports, and those that supported others on the chat during the jam. All of you made it excellent.

1.2.0 update of differ includes lots of ray casting features like intersection points and ray vs ray intersections and more, view the demo here but the luxe local version (tests/features/collision) is a little ahead thanks to bug sleuthing by NicoM and bug fixes and test additions by joeld42

lots of api refactoring and clean up

Ahead!

This post is already over 2000 words, and there is still a dev log and an alpha-3.0 sample + post incoming. I'm excited to share some stuff that I've worked on over ludumdare weekend as well, so let's keep this one on point.

So keep an eye on snowkit.org or twitter, or repos. I'll be posting alpha-3.0 tasks and milestone, so we can forge on ahead.

Onward we go! If you have issues, questions or feedback don't hesistate.