Building extension libraries for MonoGamers

Over the last year or so I’ve built a lot of code that would be great to release as a MonoGame extension library. Unfortunately, due to the way MonoGame is structured it makes it rather difficult.

Take for example this Sprite class:

public class Sprite
{
    public TextureRegion TextureRegion { get; set; }
    public Color Color { get; set; }
    public Vector2 Origin { get; set; }
    public SpriteEffects Effect { get; set; }
    public float Depth { get; set; }
    public float Rotation { get; set; }
    public Vector2 Position { get; set; }
    public Vector2 Scale { get; set; }
}

And the extension method on sprite batch that goes with it.

    public static void Draw(this SpriteBatch spriteBatch, Sprite sprite);

The problem is that to build a reusable library with this class in it I need to reference MonoGame so I can get access to the Vector2, SpriteEffects and Color classes. This wouldn’t be a problem on it’s own, except that the library can only target a single platform meaning I have to build that library for Windows, Android, iOS, etc.

A better solution is to make this library into a Portable Class Library (PCL) but to do that I need it to reference the portable version of MonoGame.
http://www.monogame.net/2014/04/15/monogame-3-2-nuget-packages-are-go/

I’ve been doing this is my games and it works well, but since I’m targeting Android and the MonoGame portable libraries are not official and don’t have an Android project template for the NuGet yet I’m currently running my own build from source copy.

I know there’s been some discussion around how to improve the PCL version of MonoGame and I’m not sure if this has already been discussed but I wanted to propose a good first step.

I think it would be a good idea to split MonoGame up into a few different DLL’s similar to how XNA used to be structured perhaps. In particular, to get the base framework classes into a Portable Class Library (e.g. Vector2, Color, Matrix, Point, Rectangle).

Doing this would make it significantly more flexible to create new PCL’s for reuse across platforms. You could create a single compiled DLL and reference it from all of your platform projects without the need to recompile it every time.

If the MonoGame team is interested in this I’d be happy to create a fork on github and do the work to split it up. I just wanted to discuss it here first and gather thoughts on the idea.

Cheers

Sounds like a great idea to me!. I wonder if @SimonDarksideJ and @Tom have any comments on the roadmap for gettting PCL merged into develop?

1 Like

We’ve been discussing this for various needs we’ve run into. We probably won’t go with as many assemblies as XNA (they had 9 different assemblies not including the content pipeline). We will probably end up with like 3 or 4 assemblies in the end, but we’re taking it one step at a time.

If you want to take a shot on your own that is fine, but be aware this is the sort of thing that could easily be completely rejected if it wasn’t perfectly right.

Your best bet to see this happen is to collaborate with the team by adding a GitHub issue for what you’re proposing. A bunch of us will comment on it and we can form a specific plan on how to approach things and synchronize it with work others are doing.

No problem. I figured this had been discussed before, I just wasn’t sure how to get involved.

As I said, I don’t mind doing the work, but I’d rather discuss it first so we can get it right and merge it back into MonoGame. For the purpose of creating extension libraries, it won’t be worth doing if it only exists in my fork.

I’ll add the issue to GitHub shortly with a proposal for what I think should be moved first.

I’ve added a comment to the end of this issue.

@Tom I wasn’t sure if I should raise a new issue or not?

When I get a bit more time I’ll put together a clear proposal for what classes I think should go into the portable assembly. Once I’ve got that perhaps it should be in a new issue, or should we just keep discussing it in the already existing issue?

Well the first seperating lib is almost complete now, just awaiting final testing by @Tom and it should be merged.

We now have a MonoGame.Net.

Discussions will likely continue now based on the effort required to create that new lib as to how many other splits get done :smiley:

P.S.
Protobuild was a life saver for this process, if you haven’t looked at it yet I highly recommend doing so!!

Where are those discussions? I’d like to be involved if possible.

The split’s should be determined by dependencies. Each DLL should either isolate a dependency (as is the case for the MonoGame.Net library) or they should make it easier to be referenced from other dependencies (e.g. the Farseer physics library could be build again’t a MonoGame.Core library).

We keep most of the technical design discussion on GitHub.

Cool. I’m already involved in those, just wanted to make sure there wasn’t any others. Posting the links is always helpful to everyone. Thanks.

Yup. Keep an eye out, as soon as I am done documenting the latest change I’ll be starting another discussion on the GitHub site for the modularisation of MG.

Certainly going to be interesting times the next few months

Wanted to write an extension as well and bumped into this topic. Seeing as there’s no seperate assemblies yet there’s gonna be 2 options as of now:

  • The users have to swap the dependencies out themselves.
  • I’ll have to create 9 different DLLs.

This is too fundamental to start fidgeting and do a pull request myself I presume :laughing:

Maybe someone has a better way to get this to work?

@HermansGameDev Yep. So here we are more than a year after I started this topic.

I’m currently working on the MonoGame.Extended library with some other contributors. We are using Portable Class Libraries to provide support for most platforms with a single NuGet package.

What kind of extension do you want to write?

Looks nifty, might make use of that. Who doesn’t want prefab input handling. :slight_smile: How do you make it work with different platforms though? Don’t you have to reference a platform specific MonoGame DLL? That was the entire point of this thread (afaik).

A PCL is just a DLL right.

@HermansGameDev Sorry I didn’t get back to you yesterday. Pretty busy lately.

A PCL is just a DLL right.

A PCL is a DLL that’s designed to target multiple platforms. Once you have a PCL you can reference it from many different platform specific projects. There are some limitations but there’s also some clever workarounds.

PCL’s have been around for a while but it’s only recently that they’ve started to become more commonly used. Microsoft and Xamarin support them and VS2015 has some new features like Shared Projects that could make our lives a little easier. We are not currently using SP’s.

Don’t you have to reference a platform specific MonoGame DLL?

We are using a “trick” called bait-and-switch thanks to @SimonDarksideJ for his work in this area. The idea is to recompile MonoGame as a PCL by removing all of the implementation and leaving an empty shell with just the public interface. WardBenjamin wrote a document on how this all works in MonoGame.Extended. It’s pretty complicated but works nicely.

How do you make it work with different platforms though?

Once you have a PCL it’s fairly trivial to get it working on different platforms. Nothing is perfect of course, you’d still need to do some testing but overall I’m pretty happy with the experience.

Thanks for the explanation! Piranha works great and thanks to the guide it wasn’t complicated at all.

Even better I got a library to work using the compiled and chewed PCL, hooray for Piranha. As long as nothing funny happens I’m okay with this solution hehe.

Great. Glad you got it working.

I’d love to know more about your library.

Writing some extensions to System.Random for ease of use, I’ll make a public repo while I’m at it. Things like generating Vectors/Colors and choosing a random element from a list (Gamemaker style). It’s the kind of library that you probably want to NuGet into every game that uses RNG. Feeling awfully off-topic now though.

Cool. I’ll keep an eye on it

Using some generated PCL is just unnecessarily complicated. If you want multi platform library on top of MonoGame (and not using any OS specific stuff), you can just use Windows MonoGame DLL as reference and do not include it (or any dependency to MonoGame) in final NuGet or installer. That way your library will use whatever DLL is in final build.

just use Windows MonoGame DLL as reference

That doesn’t sound right. You’re library is a PCL so it can only reference other PCLs. Good thought though.