MonoGame introduction

By Joshua Holden

A little bit of history

 
On the 14th of March 2006 Microsoft released XNA intending to provide a set of tools running under the .NET framework to allow game developers to write games targeting Xbox, Windows phones, Zune (now discontinued Mp3 player) and Microsoft Windows, it allowed developers to compose games using DirectX without worrying about a lot of the complexities of doing so.
 
Unfortunately despite many developers using the platform to create games, it was, after several updates discontinued in 2013, fortunately however in 2009 a project to port XNA to Mono (an open-source, cross-platform implementation of the Microsoft .Net Framework) began which now is fully functional replicating all of the available features in XNA at the point of being discontinued. Furthermore, MonoGame can target OpenGL, OpenGL ES, or DirectX to power the graphics as well as being able to publish games to IOS, Android, macOS, tvOS, Linux, Playstation, Xbox One, and the Nintendo Switch.

Who is it targeted at?

MonoGame is pretty much the reverse of any other commonly used game development platform such as Unity, Unreal engine, GODOT, etc in that there is no UI, no dragging characters onto the screen and assigning code and behaviors to objects in a visible environment if you want to see your game you are going to need to build and run the code, and writing tests, well... good luck!  If you want to add UI elements or text onto the screen or even a physics engine, well... You are going to need to write the code (or use an external library such as farseer for physics).
 
Why, you might say, would I want to use it then when there are alternatives available that are so much quicker to get up and running with and you would have a good question, the answer, however, is simple, MonoGame allows you to get much closer to the metal and write code without having to worry about all the things you ain't gonna need, for example, Unreal engine is designed with first-person shooters in mind and you will be fighting against that paradigm whilst trying to code your game, great if your game is going to be a first-person shooter, not so much if it isn't.
 
Monogame, assuming you have a medium to a good level of knowledge of C# is also pretty easy to pick up and run with, as it provides a lot of high-level functionality for accessing input from controllers, keyboards and much more, you can kick out a simple pong type game in a couple of hours no problem and it's fun to work with, easy to do basics abstracting away the complexities of calling OpenGL API's to make draw calls, but powerful enough to be able to write your shaders and create vertexes, particles, and primitives on the fly.
 
So to summarise, if you enjoy a code-first approach to game development, don't like paying royalties on your games, and a basic to a good understanding of c# and like to learn then MonoGame is for you.
 

The fundamentals

The architecture of a Monogame solution is quite simple it comprises of 4 methods: Initialize, LoadContent, UnloadContent, Update and Draw(). When the game first loads the initialize metod is called first shown below:

/// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }​
 As shown in the comments, the initialize method is called to load up any services or non-graphic content prior to the LoadContent method shown below:/
/// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
        }
In the load content method you are going to be pulling in assets from the content pipeline (discussed briefly below) and initialising them, this could be sounds, 3d models, spritesheets or any other asset your games needs while running, this method is only called once when the game first loads.

Once the Initialize and LoadContent code has ran, the engine now begins a game loop  calling Update, and then Draw many times per second.
 /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }​
Shown above, the update method is called once each time the game loops, usually this is 60 times per second (unless the update and draw methods start taking more time to run than 1/60th of a second) and is used to calculate movement, input and other changing variables such as physics, immidiately after the engine then calls the Draw method:
 /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }​

Once the update method has finished running, the Draw method fires and is used to draw on the screen all of the assets that have changed during the update run.

Finally, in order to free up any memory allocated to assets in the game, all of the assets loaded in the LoadContent method should be deallocated in the unload content method shown below:
 protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }​
 
 This above 5 methods represent the entire lifecycle of a MonoGame game, however, it would be remiss to end this summary without first briefly mentioning the content pipeline shown below:

cpl.png
 
The content pipeline is an external executable that allows you to import and compile  assets into a single .mgcb  file to quickly access during the runtime of the game, usually you would load assets from the content pipeline during the LoadContent method call as shown below (note that the.jpg extension is ommitted):

protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Texture2D image = Content.Load<Texture2D>("pexels-photo-2101187");           
        }
This concludes the summary of MonoGame and topics covered will be expanded on in future posts.

Comments


Comments are closed