Skip to content

v0.17.0

Latest
Compare
Choose a tag to compare
@davesmith00000 davesmith00000 released this 30 Apr 19:09
· 91 commits to main since this release

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, Layers (that is, content layers: Layer.Content) have gotten a little cleverer, and can now hold CloneBlanks - which could previously only be done by SceneUpdateFragments. 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:

image

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 types
  • Camera.topLeft can take a Size param
  • New options to get a Camera's bounds/frustum
  • SceneEvent First and Last events added
  • SceneEvent LoopNext and LoopPrevious events added

Additional bug fixes

  • ConfigGen takes mixed case hex values (#688)
  • SceneFinder: Jump to index is clamped

Further generated notes:

What's Changed

Full Changelog: v0.16.0...v0.17.0