Creating an Environment with Boo

In this Tutorial, we'll go over how environments are set-up, and how to create a custom one as a Boo plugin.

Environment Rendering

Environments are represented as a series of layers that are drawn in the background of your world. These layers are divided into two groups, and each group can has custom render modes that describe how to draw the layers.

Both orbital and sky layers have a Layer flag, that tells them in which order they should be rendered.


Orbitals represent something discrete in the sky, that is, well, orbiting. These are are usually for things like Stars(Suns), and moons or planets, but aren't limited to that. They have two render modes: Billboard, and Sphere. Billboard draws a flat image in the sky, while sphere uses a texture and draws a sphere.

Sky Layer

Sky layers is something that engulfs the whole sky. There are several modes that can be implemented with these types of layers. This is, for example, starts, atmosphere colors, clouds, etc.

Creating your first Environment

Let's create a simple environment using some preset orbitals and layers from essentials.
#include "macros"
import pluginbase.Attributes
import pluginbase.Objects.World.Environment
import pluginbase.Helpers.Data
import essentials.Environment.Sky
import essentials.Environment.Fog
import essentials.Environment.Precipitation
import essentials.Environment.Filters
import essentials.Environment.Orbital
[Environment("SimpleEnvironment", Author: "Pontoon City", Description: "Simple test environment")]
class SimpleEnvironment(EnvironmentBase):
	@Declare SkyColor Rgba(0f, 0.5f, 1f, 1f)
	@Declare WorldAmbient Rgba(0.2f, 0.2f, 0.2f)
	final _orbitals = null
	final _fog = null
	def constructor():
		# We create the orbitals and fog here, because they are needed in other parts
		_orbitals = (Sun(), )
		_fog = ColorFog(Rgba(0.5f, 0.5f, 0.55f), 0.007f)
	def CreateOrbitals():
		# Return a list of orbitals
		return _orbitals
	def CreateLayers():
		# Return a list of layers to be drawn in the sky
		return (StarLayer(), CloudLayer(), AtmosphereLayer( _orbitals ), FogSkirt(_fog, 0.05f, 0.2f) )
	def CreateFog():
		# Return fog
		return _fog


Precipitation is a class that implements a combination of a particle system and sound effects to simulate some sort of precipitation. This can range from rain, to snow, to dust storms, and you can have more than one system going at a single time. To see a simple system, add this to your environment:
	def CreatePrecipitation():
		return (DustStorm(), )


Filters are something that overlay the camera on render-time. This can be a simple color filter, or dust building up on the user's visor.

To see a simple Vignette filter, add this to your environment:
	def CreateFilters():
		return (VignetteFilter(), )

Creating an orbital

There are a few convenient base-classes provided to implement orbitals. We'll be using OrbitalRevolutionBase, which helps us make an orbital that revolves around the planet.

Here's an example of a custom implemented Sun.
#include "macros"
import System
import pluginbase.Dependencies
import pluginbase.Objects.World.Environment
import pluginbase.Objects.World.Environment.Orbitals
import pluginbase.Helpers.Data
import essentials.Environment
class MySun(OrbitalRevolutionBase, IOrbitalGlow):
	@Dependency IResourceResolver _resolver
	def constructor():
		# This passes custom parameters to the OrbitalRevolutionBase that
		# describes how fast and in what position the Sun is in the sky
		super(300f, 0f, Math.PI, Math.PI / 2f)
	@Declare RenderMode OrbitalRenderMode.Billboard
	@Declare Resource _resolver.Resolve("essentials", "textures/sun.png")
	@Declare HasEmittance true
	@Declare EmittanceDiffuse Rgba(1f, 1f, 1f)
	@Declare OrbitalEmittance Rgba(1f, 1f, 1f)
	@Declare EmittanceAmbient Rgba(0.3f, 0.3f, 0.3f)
	@Declare EmittanceSpecular Rgba(1f, 0.8f, 0.7f)
	@Declare Size 1f
	@Declare GlowStrength 1f
	@Declare GlowRadius 1f
	@Declare GlowColor Rgba(0.5f, 0.2f, 0.3f)

Creating a sky layer

For the sky layer, we're going to create a simple pattern in the sky. You can download the texture I used on the right. Make sure to save this to the same directory as the rest of your environment files.

First, we will make a new descriptor class to define the sky layer.
#include "macros"
import pluginbase.Objects.World.Environment.Sky
class SkyFire(SkyLayerBase):
	@Dependency IResourceResolver _resolver
	@Declare RenderMode SkyLayerRenderMode.SphereTexture
	@Declare Resource _resolver.Resolve("environment/skyfire.png")
	@Declare Layer 9

Next, we will add SkyFire to your Environment by adding it to the sky layers. Note, that order doesn't matter here, as they are drawn by the Layer ranking, not the ordering.
	def CreateLayers():
		# Return a list of layers to be drawn in the sky
		return (StarLayer(), SkyFire(), CloudLayer(), AtmosphereLayer( _orbitals ), FogSkirt(_fog, 0.05f, 0.2f) )

If all goes well, you should get something that looks like: