This release brings Indigo up to Scala 3.4.1 and Scala.js to 1.16.0. You will need to upgrade your projects to at least these version numbers.
As always, a big thank you to all those who contributed to this release in any capacity.
Give it a try, and please report any issues!
Notable changes
Many of these changes represent breaking changes to Indigo's APIs.
Physics iterative solver
Indigo's physics solution continues to be crude and naive, but now includes a simple iterative solver. This provides more accurate results by solving for up to a configurable maximum number of attempts per frame, or until a stable solution is found.
SubSystems have read-only access to the game model
Previously, sub-systems where kept strictly separate from the main game. They were mini-games unto themselves, and could only communicate via events. This worked well, but could be a little cumbersome.
The SubSystem
definition now includes a reference
method, that you must implement:
type ReferenceData
def reference(model: Model): ReferenceData = ???
This allows you to extract information from your game's model that the sub-system would like access to. Access is provided in the SubSystemFrameContext
under a new reference
field.
This means that you no longer need to tediously pass model data to sub-systems via events, should the sub-system's logic require state information from the game in order to do it's job.
Layer improvements
Prior to this release, a SceneUpdateFragment
held a Batch
(a list) of layers, and those layers could be given keys (identifiers) to help you manage the order - particularly when merging scene fragments.
That approach has served us well until now ...but what if you want to dynamically create N layers and have them positioned in a known place in the tree, without interfering with something else? You could try and wrangle a pool of keys, but a much simpler solution is to allow layers to be nested.
Solving that problem creates another, because keys suddenly become difficult to manage. The solution is to move the keys out of the layer, like this:
Original:
Layer(key, ...)
Now:
LayerEntry(key, Layer(...))
Which for convenience, you can construct like this:
SceneUpdateFragment(
key1 -> layer1,
key2 -> layer2
)
So far, all we've done is rearrange things a bit, but what about the nesting? Layer
is now an ADT formed of Layer.Content
which is the equivalent of the old Layer format (all the old constructors assume a content layer, to make migration/upgrading easier), and Layer.Stack
, allowing you to create a tree of layers and assign it to a single key. Stacks are flattened during the rendering process, so they are a purely organisational device.
Finally, Layer
s (that is, content layers: Layer.Content
) have gotten a little cleverer, and can now hold CloneBlank
s - which could previously only be done by SceneUpdateFragment
s. This makes sense, as layers are all about organising elements to be rendered, and some of them will need clone blanks.
Plugin: Font generator
Another exciting improvement (prompted by @mprevel): The plugin generators have a new addition! You can now generate font sheets and FontInfo
instances from font files! This makes it much, much easier to work with font's and Text
instances. No doubt, there is further room for improvement, but it's a great step forward.
Example:
val options: FontOptions =
FontOptions("my font", 16, CharSet.Alphanumeric)
.withColor(RGB.Green)
.withMaxCharactersPerLine(16)
.noAntiAliasing
val files =
IndigoGenerators("com.example.test")
.embedFont("MyFont", sourceFontTTF, options, targetDir / Generators.OutputDirName / "images")
.toSourcePaths(targetDir)
Generates this font sheet:
And this FontInfo
code:
package com.example.test
import indigo.*
// DO NOT EDIT: Generated by Indigo.
object MyFont {
val fontKey: FontKey = FontKey("my font")
val fontInfo: FontInfo =
FontInfo(
fontKey,
151,
68,
FontChar(" ", 129, 51, 9, 17)
).isCaseSensitive
.addChars(
Batch(
FontChar("a", 0, 0, 9, 17),
FontChar("b", 9, 0, 9, 17),
FontChar("c", 18, 0, 9, 17),
FontChar("d", 27, 0, 9, 17),
FontChar("e", 36, 0, 9, 17),
FontChar("f", 45, 0, 9, 17),
FontChar("g", 54, 0, 9, 17),
...
FontChar("9", 120, 51, 9, 17),
FontChar(" ", 129, 51, 9, 17)
)
)
}
Custom HTML templates
Finally, a long requested improvement (ok, mostly by @hobnob 😄): You can now provide your own HTML templates for your games, rather than being stuck with the defaults we generate. This mechanism isn't clever, we assume you know what you're doing!
To use this feature, you can modify your build's IndigoOptions
as follows:
Default
// Set up your game options with the default template, meaning Indigo will generate the template as normal.
val indigoOptions =
IndigoOptions.defaults
.withAssets(indigoAssets)
.useDefaultTemplate // You can set this explicitly, but it is the default.
Custom
// Set up your game options with a custom template
val indigoOptions =
IndigoOptions.defaults
.withAssets(indigoAssets)
.useCustomTemplate(
IndigoTemplate.Inputs(os.pwd / "test-custom-template"), // A directory containing you template files
IndigoTemplate.Outputs(
os.rel / "custom-assets-directory", // The name of the assets directory in your output directory
os.rel / "custom-scripts-directory" // The name of the assets directory in your output directory
)
)
Other Improvements
*.eot
added to list of supported font typesCamera.topLeft
can take a Size param- New options to get a Camera's bounds/frustum
SceneEvent
First
andLast
events addedSceneEvent
LoopNext
andLoopPrevious
events added
Additional bug fixes
ConfigGen
takes mixed case hex values (#688)- SceneFinder: Jump to index is clamped
Further generated notes:
What's Changed
- Mouse button filter was incorrect by @hobnob in #682
- Ensures fonts are auto-generated correctly by @hobnob in #686
- Physics iterations by @davesmith00000 in #694
- Updates the Mouse Wheel to allow for more than 1 axis by @hobnob in #696
- Improving camera frustum methods by @davesmith00000 in #701
- Fixed #698: mod operator for Point-like types by @davesmith00000 in #702
- Update sbt to 1.9.9 by @davesmith00000 in #700
- Fixed #707: Xbox One Controller not working on FF/Chrome by @bilki in #708
- Fixed #706: Expand/contract BoundingBox/Rectangle by Size/Vec2 by @davesmith00000 in #717
- Fixed #705: Circles and Rectangles agree on overlap by @davesmith00000 in #721
- Fixed #713: SubSystemFrame/SceneContext have toFrameContext method by @davesmith00000 in #719
- Scene event improvements by @davesmith00000 in #718
- Fixed #715: SubSystems have read-only access to the model by @davesmith00000 in #716
- Upgrade Scala.js to 1.16.0 by @davesmith00000 in #723
- Upgrade to Scala 3.4.1 by @davesmith00000 in #724
- Issue #714: Nested layers by @davesmith00000 in #727
- Fixed #709: Random basic data types by @davesmith00000 in #728
- Fixed #695: Allow custom HTML templates by @davesmith00000 in #729
- Issue #726: Adding a Font generator to the plugin by @davesmith00000 in #731
- Fixed #732: Content Layers support clone blanks by @davesmith00000 in #734
Full Changelog: v0.16.0...v0.17.0