Loading Ogmo Editor Levels

This example currently requires the "dev" branch of Otter to function properly.

Otter has built in support for Ogmo Editor projects and levels for loading data into your games. Of course any sort of level format is possible, but Otter has done a lot of the grunt work for loading Ogmo Editor data already.  Let's go through an example of making a level with Ogmo Editor and loading it with Otter.

Here's an example of a level created using Ogmo Editor:

This example will not be covering how to use Ogmo Editor.  For details on how to use Ogmo Editor check out the tutorials here.

For this example to work you're going to need the following three things:

Ogmo Project File

Ogmo Level File

Tiles:

Now that you have those, you're ready to run the example code to see it in action.

using Otter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OgmoEditorStuff {
  class Program {
    static void Main(string[] args) {

      // Create a new Game.
      var game = new Game("Ogmo Editor Example");
      // Set the background color to see stuff a little better.
      game.Color = Color.Cyan;

      // Create a new Scene to use for the Ogmo data.
      var scene = new Scene();

      // The path to the level to be loaded.
      var pathLevel = "Level.oel";
      // The path to the Ogmo Project to use when loading the level.
      var pathProject = "OgmoProject.oep";

      // Create a new OgmoProject using the .oep file.
      var OgmoProject = new OgmoProject(pathProject);

      // Ensure that the grid layer named "Solids" gets the Solid collision tag when loading.
      OgmoProject.RegisterTag(Tags.Solid, "Solids");

      // Load the level into the Scene.
      OgmoProject.LoadLevelFromFile(pathLevel, scene);

      // Start the game using the Scene with the loaded Ogmo Level.
      game.Start(scene);
    }
  }

  // Collision tags to use in the game.
  enum Tags {
    Solid,
    Player,
    Coin,
    Exit
  }

  // A Player Entity to match the Entity in the Ogmo Project.
  class Player : Entity {
    public Player(float x, float y) : base(x, y) {
      var img = Image.CreateRectangle(32, 32, Color.Red);
      AddGraphic(img);
      SetHitbox(32, 32, Tags.Player);
    }
  }
  
  // A Coin Entity to match the Coin in the Ogmo Project.
  class Coin : Entity {
    public Coin(float x, float y) : base(x, y) {
      var img = Image.CreateRectangle(16, 16, Color.Yellow);
      AddGraphic(img);
      SetHitbox(16, 16, Tags.Coin);

      // Adjust the position here because of the Origin in the Ogmo Project.
      X += 8;
      Y += 8;
    }
  }
  
  // An Exit Entity to match the Exit in the Ogmo Project.
  class Exit : Entity {
    public Exit(float x, float y) : base(x, y) {
      var img = Image.CreateRectangle(64, 64, Color.Magenta);
      AddGraphic(img);
      SetHitbox(64, 64, Tags.Exit);
    }
  }
}

One important question to answer is how does the Ogmo Project know to create the right Entities when loading the level?  The simple answer is reflection!

When loading a level the OgmoProject class will seek out types that match the name of the Entity it's trying to load.  When it finds one it will try to create one using a constructor that takes in two floats: x, and y.  So in this case it is very important that our Entities have a constructor that takes two floats to determine its position, and it's important that the class name of your Entity matches the name of the Entity in your Ogmo Project.

What about loading Entities with more data than just x, and y though?  Here's a quick example of something you could do that involves a little bit more than just x, an y.

  // An Entity that uses some more Ogmo data.
  class AdvancedCoin : Entity {
    // The value of the coin when picked up.
    public int Value = 1;

    // If the coin is visible or not.
    public bool Invisible = false;

    public AdvancedCoin(float x, float y, OgmoData data) : base(x, y) {
      var img = Image.CreateRectangle(16, 16, Color.Yellow);
      AddGraphic(img);
      SetHitbox(16, 16, Tags.Coin);

      // Get the data from the Ogmo data.
      Value = data.GetInt("Value", 1);
      Invisible = data.GetBool("Invisible", false);

      // Set the Entity's visibility based off the data.
      if (Invisible) {
        Visible = false;
      }

      // Adjust the position here because of the Origin in the Ogmo Project.
      X += 8;
      Y += 8;
    }
  }

In that example an AdvancedCoin can have a different value when collected, and can also be invisible.  These are Values that the Entity would have in the Ogmo Project.  The OgmoProject class will include all of the Entity's extra data in an OgmoData object when created with a constructor that takes two floats and an OgmoData type.

That covers the basics of using Ogmo Editor to load levels into Otter.  Make sure to explore the documentation and the source code to see what else is possible using the OgmoProject class.

Examples