Gif Maker for Monogame

I was playing around with some graphics code and wanted to share it and was tired of going through the huge convoluted process of recording my screenplay and generating a gif (or using a gif making tool). I wanted something that would be there always. Being that I could not find a solid library somewhere which takes Monogame screen data and outputs a gif, I decided to write one myself!

Monogame.ScreenTools

I created a small library which I’m calling screentools which has a few utilities for creating screenshots and generating gifs. Included in the library is a test project with example usage.

Full Source here
Test App controls: F12 for Gif (hold and release when done), F9 for screenshot, one per keypress.

I intend to improve it as needed as I wrap it back into my game code. The immediate improvements I plan to add are multi-threading and compression. Exploring the problem space made me realize that I could write a more efficient Monogame specific gif maker. For now, it uses .NET’s System.Drawing to bootstrap the process and .NET’s Gif codecs to output. That improvement would be a longer-term one unless I find that someone else has already done it.

This small library was an impulse build so.. expect bugs.

-Jonathan

Misbehaving collision and also ECS

Ah collision you naughty monkey.

On the bright side, Visual Studio 2017 performance monitoring tools are pretty cool – when they work. In this case, the tools highlighted the exact offending line of code where  the CPU is spending a comically high 50% of its time! For once, it’s not premature optimization but I was expecting this. When I hack together game engines in intense one day sessions, I tend to take brute force approaches to every solution in an effort to get something working on screen. Function that’s O(N^4) loping through every object in the game? Whatever, slap a ‘TODO’ on it and make it someone else’s problem. In this case it’s O(N^2) but what’s a power of two between friends. I first came upon the issue when I was running a test level and found an ‘AddRandomEntities()’ command in the console window mapped to F1. Curious, I kept hitting F1 until my game slowed to a craw. I looked at the dat and saw that a mere 600 collidable objects had brought the engine down.  That may seem like a lot but add a bit of bullet hell and monsters on top of more unique objects and that number comes down real quickly.

 

“A poorly coded collision function” – circa 2017

 

Fortunately, this is an easy fix in a 2D game. Subdivision of the world via a quad tree or similar structure. Really, even subdividing the screen into quadrants alone would quadruple performance. For an in-depth tutorial on build quadtrees (along with nice explanation graphics) try this. I know, I should have written something up about it here but apparently my old post was taken down from Stack Overflow for some odd reason.
Anyway, without that offending and naive collision function, the engine can render a few hundred thousand objects at 120 fps.

But while we’re talking…

Let’s talk Entity Component Systems, my new one true love. Sorry inheritance, you had your chance!  Prior to implementing one in my engine, I was hitting bottlenecks when it came to tracking, management and manipulation of traditional ‘heavy objects’. The added overhead of pulling out properties, constantly switching contexts as you attempt to navigate tree after tree of a given object was killing performance and tended to lend itself to bugs.

 

Entity Component System
“A typical ECS” – Gamasutra

 

The switch to ECS, in particular the System part came with a fairly substantial performance leap in addition to large improvements in code flow. Now instead of object hierarchies, each system is managing it’s own list of data only objects objects. Having each system iterate its list in sequence means that our current list of data being operated on is likely always hot in cache.

 

 

Each system can then operate on hundreds of thousands of data containers without a care as to who they belong to.

“They’re Everywhere!” – somedude, a prototype, 2017

For my engine, I wanted to build an ECS as opposed to an EC. There is something that is inherently elegant to me about the separation between Entity (an id), Component (data) and System (logic).
One of the tricky parts of ECS is handling cases where Systems need to operate across component types and also component lookups (which require a cast). For my approach I introduced two optimizations. First, I introduced Nodes, an idea I stole from an implementation I saw around the web. Nodes help to bridge that tiny gap between component and ‘system who needs lots of different data’. A node can hold components but also importantly, holds data which is related across all components held within. For instance here’s a simple Collision Node:
public class CollisionNode : INode
{
        public int Id { get; set; }
        public int CollidedWith { get; set; }
        public bool Checked { get; set; }
        public bool HadCollision => CollisionData.HasCollision;
        public PositionComponent Position { get; set; }
        public CollidableComponent CollisionData { get; set; }
}

The Node allows us to generate metadata about the joined objects in a lightweight way. In this way we avoid excessive lookups and lots of meta collections. We can iterate this one list and have all the info we need to take action.

To get around the casting in general that comes with ECS I opted for an enum based component type property. This isn’t the best solution, I can’t even call it an OK solution but I have yet to run into a significant issue with it. Why cast and check to ensure your casts succeeded when you can bake in the type info and grab entities matching the enumeration type. It works for me, for now.
My ECS implementation is far from the best but I’ve found that it is relatively easy to add new features and have them “just work”. After years of building inheritance hierarchies – I finally get it. If you’re not using an EC or ECS implementation in your engine, you should probably consider it!


-Jonathan

Serializing Game Settings

Today I began the work of migrating my C# Monogame Game Engine (code named Rogue Squad) from a DirectX/Windows codebase to the Windows 10 Universal Windows Platform.  I expected there to be rather large changes required in the refactoring but thus far I’ve only ran into two. I’ll detail the second minor change and why it matters, at the end.

First I started with a straight forward DataContract to hold the fairly basic settings for the game. The annotations allow the DataContract serializer to easily read/write from file in a type-safe way.

[DataContract]
public class GameSettings : IGameSerializableObject
{
    [DataMember]
    public int GlobalVolume { get; set; }
    [DataMember]
    public int FxVolume { get; set; }
    [DataMember]
    public int MusicVolume { get; set; }
    [DataMember]
    public int SpeechVolume { get; set; }
    [DataMember]
    public int ResolutionH { get; set; }
    [DataMember]
    public int ResolutionW { get; set; }
    [DataMember]
    public bool EnableFullScreen { get; set; }
    [DataMember]
    public bool UseVsync { get; set; }

    public static GameSettings Default =>  new GameSettings{ GlobalVolume=100, FxVolume = 100, MusicVolume=100, SpeechVolume=100, ResolutionH=800, ResolutionW=600, EnableFullScreen = false, UseVsync=false };
}

In the DX/Windows app, the serialization is equally straightforward. We simply create or open the file and stream it in, casting the JSON to our GameSettings.

public class AppSettings
   {
      
       public const string GAME_SETTINGS = "gameSettings.json";
       DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(GameSettings));

       public GameSettings LoadSettings()
       {
           if (!File.Exists(GAME_SETTINGS)) return GameSettings.Default;
           
           using (FileStream stream = new FileStream(GAME_SETTINGS, FileMode.Open))
           {
               return (GameSettings)serializer.ReadObject(stream);
           }
       }

       public void SaveSettings(GameSettings settings)
       {
           using (FileStream stream = new FileStream(GAME_SETTINGS, FileMode.Create))
           {
               serializer.WriteObject(stream, settings);
           }
       }       
       
       
   }

Unfortunately, UWP’s sandboxed environment means that any sort of direct file writes are out of the question. This also applies to asset loading. On the one hand, this API style has been around a little while – having made its splash with the Windows Phone 7 and the initial WinRT iteration of the Microsoft App Store – so most issues should be long since resolved. Our main problem is, the ‘all async all the time’ API design doesn’t quite mesh well with the ‘loop it baby’ noticeably non-async nature of most game APIs. While this is changing, as of the time of this writing Monogame 3.6 does not make much use of async APIs. We can’t really fault it though, it started as a re-implementation of the defunct XNA library for the XBOX 360. While its codebase has evolved to support everything from PS4 to Xbox One and the Nintendo Switch, it’s design is decidedly stuck in late 2009. That’s not necessarily a bad thing. If it ain’t broke..

using Windows.Storage;

public class AppSettings
    {
  
        public const string GAME_SETTINGS = "gameSettings.json";
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(GameSettings));
        StorageFolder localFolder;
        public AppSettings()
        {
            localFolder = ApplicationData.Current.LocalFolder;
        }
        public async Task<GameSettings> LoadSettings()
        {
            if (!File.Exists(GAME_SETTINGS)) return GameSettings.Default;
                       
            var file = await localFolder.GetFileAsync(GAME_SETTINGS);
            using (var stream = await file.OpenStreamForReadAsync())
            {
                return (GameSettings)serializer.ReadObject(stream);
            }
        }

        public async Task SaveSettings(GameSettings settings)
        {
            var fileExist = await localFolder.TryGetItemAsync(GAME_SETTINGS);
            if (fileExist == null)
            {
                await localFolder.CreateFileAsync(GAME_SETTINGS);
            }

            var file = await localFolder.GetFileAsync(GAME_SETTINGS);
            using (var stream = await file.OpenStreamForWriteAsync())
            {
                serializer.WriteObject(stream, settings);
            }                        
        }                       
    }

The new version is fairly straightforward and technically “cross-platform” compatible back to Windows 8. The keys changes are the switch to the StorageFolder and StorageFile abstractions as well as the usage of a variety of Async functions.

On the engine side where you’ll eventually consume these settings you’ll either have to tag your methods as async, wrap them in a Task<T>, or call the dreaded .result() method. I was fortunate enough that this code was only being called from the Options Screen in the UI. I was able to mark the event handlers async and called it a day like so..

private async void Back_Resolution_Selected(object sender, PlayerIndexEventArgs e)
{
    //save res settings
    gameSettings.ResolutionH = Engine.Instance.ScreenHeight;
    gameSettings.ResolutionW = Engine.Instance.ScreenWidth;
    await settings.SaveSettings(gameSettings);
   
}

Over the next few weeks I will be posting key challenges and solutions as I continue porting my engine to UWP. Ultimately, the goal is to get everything running on the Xbox One and pick up development from there. It may be a while…

 

Until next time, cheers!

-Jonathan

 

Ludum Dare 39!

Tomorrow is the start of Ludum dare 39 and I am super excited to get started! For the past few months I’ve been hard at work on a few different web development projects but my a game idea for a remake of Sega’s Shadowrun RPG has been on the back of my mind.

When I was in high school, back in the early 90s, I wrote a game called Digital Reset, which was a cyberpunk RPG. Last month I started laying down plans for a remake of the RPG. At the time when I wrote it, it had to be technically simple (28kb). The game was largely text and menu driven with graphics for each location and occasionally when encountering a new story element. Given the massive leap forward in technology, I’m hoping I can remake the game (or some semblance of it) along the lines of Shadowrun, in 48hrs. Before you laugh, realize that I wrote the original in an api where you had to command individual pixels on and off in order to draw! Who know’s, it’ll probably end up being a blank map with a stickman walking around but it’ll be fun either way.

I plan to knock out a prototype using Monogame and the excellent Monogame.Extended library. Having used C# for the better part of 15 years in Software Dev, I’ve always found that I’m much faster knocking out code in C#/Monogame than any other platform (sniff, one day I will get around to seriously trying out Love2D ). You may ask, why not use Unity 3d? My answer is simple, I know Monogame. I wrote my first XNA game on day one when it was released for the XBOX 360. Writing simple engine code comes naturally and it’s what I’ve always done while I was heading up the Baltimore Indie Game Developers Group. I think I was the only non-unity developer come to think of it…

In any case, I look forward to seeing what my rusty code fingers can accomplish in 48hrs. I will be posting my code on GitHub and also linking here.

Happy Coding.

3 Things I wish I knew about F# before I started that big project

Hey everyone, today I wanted to share some insights I’ve gained while learning F# over the past few weeks/months/years (it’s been an on-again, off-again relationship). I love F# but coming from a land of large C# projects, there are some edge cases where you may find yourself tripped up if you’re relatively new to F#.

Bitshift enumerations are not supported

Coming from C#, more than a few of my enumerations followed the pattern of:

enum myEnum = 
   a = 1 << 0,
   b = 1 << 1,
   c = 1 << 2,
   d = 1 << 3

Unfortunately, using bitshift operators within a union/enumeration declaration in F# is not supported. You can however accomplish the same thing using a manually generated bit field as shown below. Easy, but slightly less maintainable.

Type myEnum = 
   a = 0b00001
   b = 0b00010
   c = 0b00100
   d = 0b01000

Null Refs will still plague you

One of the things that quickly becomes apparent when integrating your F# app into a C# ecosystem is that while F# does have a native NULL type, it will still crash spectacularly when dealing with null C# types. Consider the following:

match SomeObj.Prop with  //nullref
   | condition A -> ...
   | condition B -> ... 

Solution? Wrap your questionable calls to C# objects in a ‘toOption’ call

let toOption = function
   | null -> None
   | object -> Some

then you can use it like so..

let myVal = toOption Someobj.Prop
match myVal with
    | Some -> ...
    | None -> ...

Presto! No more null-ref worries in your elegant F# code. Also, you avoid the need for constant “if x <> null then …”.

Serialization…

One of the great things about F# is the ease of record creation. Dreams of serializing these records and sending them across the wire to your web apis can quickly be shattered when you notice all your JSON objects serialized with @suffixes. What gives? F# record members are treated like C# Fields. Their underlying fieldname is serialized by most default .NET serializers resulting in something like the following..

type myRecord {
   Name : string;
   Age:  int;
   Exp:  int;
}

being serialized as:

{ "Name@":"Gandolf", "Age@":"225", "Exp@":"15" }

Fortunately,there’s JSON.NET to the rescue! No, you won’t have to re-write your serialization logic or anything. Simply add the following attributes to your type and you’re done! The rest will be handled auto-magically.

[<CLIMutable>]
[<JsonObject(MemberSerialization=MemberSerialization.OptOut)>]

That’s all for now folks but stop by in the future as I slowly begin to wake from my stupor and flesh out this blog/site.

Cheers