Indigo

Indigo

  • GitHub
  • Docs
  • Tools

›Organising your game

Indigo

  • Indigo's Development Status

Getting started

  • Setup & Configuration
  • Hello, Indigo!
  • Examples
  • Mill & SBT Game Templates

Organising your game

  • Boot & Start Up
  • Game Entry Points
  • Scenes & Scene Management
  • SubSystems

The game loop

  • Events
  • Frame context
  • Outcome Type

Presentation

  • Animation
  • Audio
  • Depth & Layers
  • Effects
  • Lighting
  • Materials
  • Primitives & Building Blocks
  • SceneUpdateFragment Type
  • Text & Fonts
  • UI Components

Working with Time

  • Signals & Signal Functions
  • Time Varying Values

Platform & Publishing

  • Assets & Asset Loading
  • Cross Platform Publishing
  • File Format Importers
  • User Input Handling
  • Loading & Saving Data
  • Logging
  • Networking

Other information

  • Alternatives to Indigo
  • Glossary
  • Key Concepts
  • Model, ViewModel, & View
  • Motivation & Constraints
  • Performance
  • Prior Art
  • Rendering Technology

Boot & Start Up

Please note that the terms "start up" and "setup" are used interchangeably here. "Startup" is the name of the data type, while "setup" is the name of the method. This naming should probably be revisited...

In order to get your game up and running, it needs to go through an initialization sequence comprised of two stages:

  1. Boot - which only ever happens once;
  2. Start up - which occurs on first run, and then whenever new assets are loaded dynamically.

A lot of what this process relates to is the loading and processing of assets, so it's worth reading up on that too.

Booting your game

During your game's initial boot, you must specify all the things your game needs to get up and running.

At minimum, this is a GameConfig definition, but can also include assets, subsystems, animations, fonts and some custom data that you'd like to make available to the rest of the game.

Sandbox games

Sandbox games (that implement IndigoSandbox) have a different boot sequence than other games, or rather they don't have a boot sequence. The main facilities of the boot process have been broken out onto the trait for you to populate. This is an intentional limitation that keeps the Sandbox simple.

Games & Demos

IndigoGame's and IndigoDemos have a boot method such as this one, where "BootData" is some user defined type:

def boot(flags: Map[String, String]): Outcome[BootResult[BootData]]

Flags

Flags are an opportunity to change your games settings based on the environment in which it is being run.

Running a game though one of the provided run methods, via the indigoBuild or indigoRun commands, is fine during general development, but at some point you're going to want to run your game in a real environment. Maybe it's going onto a game portal site, maybe its your own web site, maybe it's a desktop game. Whatever it is, those platforms come with practical problems to over come.

By default Indigo will provide a width and height flag in the standard integration code (that you can choose to use or not) so that you can start your game at the size of the window.

Let's look at the Snake game on our website as a simple example. When running locally, the assets are marshaled into a nice consistent folder called assets in the same directory as our index.html page. However, on the real site the assets are served statically from a different location! How do we reconcile these two worlds?

Well we use a flag, like this:

  def boot(flags: Map[String, String]): Outcome[BootResult[GameViewport]] = {
    val assetPath: String =
      flags.getOrElse("baseUrl", "")

      //???
  }

As long as the games assets are always in the same folder name, we can now just pre-pend the provided assetPath to change the location of that folder.

Flags are just a JavaScript object of key value pairs that must be Strings (like command line arguments), which can be injected into the game when it is embedded on the page, like this:

var flags = {
  "baseUrl": "/my/websites/assets/folder/path/"
};

IndigoGame.launch(flags);

Flags can represent anything you like. In the Snake example we are providing the url to the assets folder, but you could do browser detection in the page and use your findings to instruct Indigo to specifically use WebGL 1.0 or 2.0, or to change the magnification setting, or starting view port size, or background color, or any number of other things.

The main limitation on flags is that they are typed to Map[String, String], which is bothersome if you're trying to supply a number for instance. Perhaps the best way to use more sophisticated data at start up would be to supply JSON by setting a data flag, e.g. { data = '{width: 10, height: 10}' }, and then pulling out the data flag at boot time and parsing the JSON string.

BootResult[_]

Here is the definition of the BootResult type, which is the return type of the boot function:

final class BootResult[A](
    val gameConfig: GameConfig,     // Minimum requirement, however BootResult.default initialises with GameConfig.default
    val bootData: A,                // A boot up payload. Defaults to `Unit`
    val animations: Set[Animation], // A set of initial animations. Defaults to an empty `Set()`
    val assets: Set[AssetType],     // A set of initial assets. Defaults to an empty `Set()`
    val fonts: Set[FontInfo],       // A set of initial fonts. Defaults to an empty `Set()`
    val subSystems: Set[SubSystem]  // A set of initial subsystems. Defaults to an empty `Set()`
)

Note: You can add more animations, fonts, and assets at a later stage, but subsystems must be declared upfront or inside a Scene definition.

In a simple game, all of your animations, fonts, subsystems and assets can be declared here. This is what IndigoSandbox does behind the scenes. For more complex games, such as ones that have a pre-loader, you should only include the elements you need for the preloader scene here.

Start up / Setup

After booting up, you hit the start up function (called setup). Why are boot and start up separate functions? ..and what is start up for?

If "boot" is for marshaling your foundation game settings, then start up is for pre-processing data and assets. Since assets can be loaded on first run, but also added dynamically during the game (and you might want to do something with them), the start up or setup operation may be invoked more than once. For example:

  1. During the first run you load a JSON definition of a animation and it's sprite sheet, which are processed during start up to create a Sprite and Animation you can render.
  2. You use that to present a loading screen (preloader) while the rest of the games assets are loaded.
  3. Once the other assets are loaded, setup is called again and you can now process the new / remaining asset data for future use.

The setup function signature looks like this:

def setup(bootData: BootData, assetCollection: AssetCollection, dice: Dice): Outcome[Startup[StartUpData]]

Important! The StartUpData type corresponds to one of the type parameters in IndigoSandbox, IndigoDemo, and IndigoGame.

Special note on text assets

Unlike image and sound assets which are referenced directly in the presentation logic of your game. Text assets are only available for use during start up. The idea is that text is most likely not plain text, but actually string encoded data like JSON or perhaps a CSV. You can get hold of their data via the AssetCollection during start up / setup.

The Startup Data Type

If your setup function has succeeded:

// This is a nonsense user defined type that represents some result of the Startup process
final case class MyStartUpData(maxParticles: Int)

Startup.Success(MyStartUpData(maxParticles = 256))
  .addAnimations(..) // Optional: New animations you created during startup
  .additionalFonts(..) // Optional: Font data you created during start up
  .startUpEvents(..) // Optional: Any `GlobalEvent`s you would like to emit

If you don't need say anything other than "success", you can just say Startup.Success(()).

Should your setup function has fail, you should report errors like this:

Startup.Failure(
  "error message 1",
  "error message 2",
  "error message 3"
)

If your set up function fails, the game will halt and the errors will be written to the console. The assumption is that a failure is unrecoverable.

← Mill & SBT Game TemplatesGame Entry Points →
  • Booting your game
    • Sandbox games
    • Games & Demos
  • Start up / Setup
    • Special note on text assets
    • The Startup Data Type
Indigo
Getting Started
Setup & Configuration Guide"Hello, Indigo!" TutorialLinks to examplesProject templates
Community
DiscordGitHub DiscussonsTwitter
Sponsor us!
GitHub SponsorsPatreon
Copyright © 2021 Purple Kingdom Games Limited