Game Configuration
Configuring your game happens in two places:
- In the game's build via the plugin (if your project uses it).
- In the game itself during boot up.
Build config
As of Indigo 0.15.0
Whether you are using Mill or sbt, you configure your game's build settings using an IndigoOptions
instance, here is an example:
IndigoOptions.defaults
.withTitle("My Game")
.withBackgroundColor("black")
.withWindowSize(800, 600)
.withAssetDirectory("assets")
The IndigoOptions
type provides a fluent API that exposes a range of configuration options that can be discovered via your IDE.
One problem that you may notice is that we set values here such as window dimension. In a moment we will see those same values being set in the GameConfig
- is there a way to keep them in sync? Yes! You can use Indigo's generators in your build definition to produce a basic GameConfig
instance for you that sync's the appropriate values from the build definition, like so:
// sbt: https://github.com/PurpleKingdomGames/pirate-demo/blob/main/build.sbt
IndigoGenerators
.sbt((Compile / sourceManaged).value, "pirate.generated")
.generateConfig("Config", pirateOptions)
// Mill: https://github.com/PurpleKingdomGames/snake-demo/blob/main/build.sc
val indigoGenerators: IndigoGenerators =
IndigoGenerators
.mill("snake.generated")
.generateConfig("SnakeConfig", indigoOptions)
GameConfig
Inside the game itself you are required to configure your game by supplying a GameConfig
instance. As usual, you and easily provide an basic instance using GameConfig.default
, and configure/explore it using it's fluent API, a typical example might be:
GameConfig.default
.withViewport(Size(800, 600))
.withMagnification(2)
Most of the config options are pretty self explanatory, but there are a couple of things to know:
Resize Policy
The resize policy controls how Indigo decides to respond to a change in window / canvas size.
For historical reasons, the default is set to ResizePolicy.Resize
, meaning that the game will fill the available space (without stretching / distorting).
Warning! This works perfectly well with the code generated by the Indigo plugins, however! If you're embedding the game yourself, in a webpage say, then you need to control the canvas a little or it will continuously try to grow the viewport size. There are two ways to do that:
- Change the resize policy:
GameConfig.default.noResize
- With CSS (as generated by the plugin):
#indigo-container {
display: flex;
align-items: center;
justify-content: center;
padding:0px;
margin:0px;
width: 100vw;
height: 100vh;
}
Frame rate
The simple advice is not to set the game's framerate at all. However...
You can set the game's framerate as follows (this is the default):
GameConfig.default.withFrameRateLimit(Option(FPS.`60`))
But what does that do, and why is it optional?!
By default you will be limited by the browser / electron typically to 60fps or the vsync rate of your monitor. The frame rate generated at that level will be smooth and accurate.
The only use of the framerate limiter in the GameConfig
is to globally prevent excessive updates. For example, by default we set a limit of 60 FPS (frames per second), because for a pixel art 2D game 60 is perfectly fine, and your monitor's vsync might try for, say, 144 FPS which means more than double the processing for no good reason.
What about that optional type?
If you disable the framerate limiter in Electron (in the Indigo plugin / build settings), and set the framerate limiter to None
, with a modern version of electron and a simple enough game, it's plausible to get > 1000 fps - at which point the browser goes a bit crazy trying to keep up and performance actually degrades. Doing this in general is bad and you should not release a game in this state, but could be handy if you are performance tuning a complicated game, perhaps.
Advanced
Most people should leave the advanced config alone, but it's there to let you tune some of the engine settings, particularly the rendering settings. Please see the scaladocs for details.