Skip to content

v0.30.0-M6

Latest

Choose a tag to compare

@davesmith00000 davesmith00000 released this 30 Aug 22:48
· 1 commit to main since this release
Immutable release. Only release title and notes can be modified.

Summary

Rendering and performance improvements

In the process of upgrading an internal game project to the latest series of Indigo, a number of performance gaps and rendering issues were identified, particularly on Windows using hardware we don't test on very often. This work effort was primarily about resolving those issues.

On one test rig, our game has gone from ~30 FPS to >200 FPS with these rendering pipeline changes. With this kind of work it is always a possibility that we'll introduce regressions, please report if you see anything anomalous.

New Primitive: Quad

How do you draw a box and fill it with a colour?

Well, until now, the answer has been to use Shape.Box. The problem with using a Shape is that all of the shapes share a common drawing method (in order to keep them all looking stylistically the same) called SDFs, and the problem with SDF's is that they are subject to floating point rounding errors.

The other way to do it was with a BlankEntity and a custom shader - but that seems like rather hard work for such a simple task!

Quad is a new primitive that allows you to draw pixel perfect boxes (handy for progress bars and the like). You can fill a quad with a solid colour, or a linear or radial gradient. You can also specific the radius of each corner, if you like.

Improved Aseprite importing

We've had support for importing Aseprite for many years, but only in a particular and limited format. An attempt has been made a better support Aseprite's two JSON formats.

Bug fixes

FrameRatePolicy

There was a nasty bug where setting the FrameRatePolicy actually affected the frame rate. i.e. setting an unlimited frame rate policy on a 60Hz monitor would give you 60 FPS, but setting a frame rate policy of 60 FPS exactly on the same system might result in a lower actual rate.

This happened during the work of moving control over frame rates from Indigo to Tyrian, and has now been resolved, or at least, greatly improved.

Clip rounding errors

Under certain circumstances, and on particular GPU hardware where underlying implementations of certain functions differ, Clip shaders would suffer a rounding error resulting in a bad modulo function. This has been resolved.

In addition, Ultraviolet will now error if you try and use invalid modulo operation argument type combinations, and correctly renders modulo operations for different flavours of GLSL.

Breaking changes

BlankEntity constructors

There was previously a constructor for BlankEntity that allowed you to make one in an invalid state (size = 0,0), which has now been removed. You must now provide a size for your entity, so if you choose to set it to zero, that's on you!

FPSCounter constructors

FPSCounter had some work done to it in the last release, and here the work continues. In the process of fixing a bug, the main constructor which used to take an AssetName, now requires a function where you explain how to make the material for the Text instance RGBA => Material. While I was there, I also re-ordered the arguments to make them more sensible. They'd evolved organically for a few years and since I was breaking the API anyway, now seemed the time to rationalise.

If you really want the old behaviour, there is an FPSCounter.tinted(..) constructor you can use.

Actor's now have View types

Note that this change does not affect Performers, the opinionated cousins of Actors.

Previously, an Actor's present function always returned Outcome[Batch[SceneNode]]. This worked ok for simple use cases, but Actors often benefit from being rendered via clones, and this type signature doesn't permit that or any other more advanced rendering strategy.

Actors now return an Outcome[ViewType] where ViewType is parameterised and can be literally anything, such as CloneBatchData. The only hard requirement to make this work is that ActorPool now cannot be constructed 'empty' anymore. You must always at minimum provide a function of Batch[ViewType] => SceneUpdateFragment.

If you want the old behaviour, all you have to do is set the ViewType to be Batch[SceneNode], and provide a function Batch[Batch[SceneNode]] => SceneUpdateFragment, something like:

actors => SceneUpdateFragment(
  LayerKey("layer a") -> Layer.Content(actors.flatten)
)

What's Changed

Full Changelog: v0.30.0-M5-PREVIEW...v0.30.0-M6