Monogame: Move away from XNA?

Created on 6 Jul 2016  路  30Comments  路  Source: MonoGame/MonoGame

Since Monogame calles itself the _spiritual successor to XNA_ and not _a Mono-compatible re-implementation of XNA_, I was wondering if there any plans to move away from the current API design to get Monogame ready for future requirements, improve components etc., essentially making it XNA-incompatible?

Amongst the things which are annoying me since the early days of XNA (and now Monogame) for example is the Game class, the _two-step-initialization_ paradigm and the references to Game all over the place. It's just bad design. Also that many components which would be helpful to re-create an own, better main Game class are internal (e.g. GamePlatform).

Take this for example:

public class MyGame : Game {
    public MyGame() {
        var graphics = new GraphicsDeviceManager(this);
    }
}

What happens here? The GraphicsDeviceManager takes the current Game instance as a parameter which is essentially used to register itself in the game service collection of the game, only to be retrieved in a service-locating manner later from the Game. This makes it not only impossible to properly test the GraphicsDeviceManager, it also isn't really obvious that the game requires an instance of the type (otherwise it crashes). Not very nice.

I know it's not you guys fault, it's just how XNA was designed. Hence I'm asking - are there any plans to drop the design alltogether in favor of modern standards, extensibility and more cleaner seperation of components?

Most helpful comment

wondering if there any plans to move away from the current API design

Yes... we do want to evolve MonoGame towards the future. That includes depreciating bad parts of the old XNA API as well as adding new parts to the API.

Mainly the concern has been around the new graphics APIs, but I agree that there are some other bad parts that could be improved as well.

The hard part is deciding when to start breaking compatibility. We can start with adding alternative APIs and marking old ones as depreciated this way old XNA ports work and new projects can take advantage of the improvements.

All 30 comments

wondering if there any plans to move away from the current API design

Yes... we do want to evolve MonoGame towards the future. That includes depreciating bad parts of the old XNA API as well as adding new parts to the API.

Mainly the concern has been around the new graphics APIs, but I agree that there are some other bad parts that could be improved as well.

The hard part is deciding when to start breaking compatibility. We can start with adding alternative APIs and marking old ones as depreciated this way old XNA ports work and new projects can take advantage of the improvements.

Also keep in mind that not all new methodologies are good candidates for
games. Many of them are designed for business or commercial development,
where correctness and verification are rated higher than performance or
memory use. I'm using such methodologies in my day job at the moment and I
would debate their merits in any of those fronts.

Not saying they're all bad. They just have to provide some tangible benefit
to game development.

@KonajuGames I agree that certain patterns are not suitable for games, but I don't like being forced into a specific one either, which is currently the case with certain APIs of Monogame. If all individual components would be completely separated based on their concern, one can compose or wrap them in a way suitable for the requirements of its game. For instance, I've got 2 projects going on currently where on one I weight correctness and modularity more than performance, so I'd like to use stuff like IoC through DI, on the other one I need certain logic blocks to be processed as fast as possible, so I keep all stuff tightly coupled with static accessors and what not. What I'm saying is both should be possible - with the current state of Monogame, all the paradigms and methologies of an OOP language don't make much sense, because everything could be put in "Game".

@tomspilman Since the current Monogame is neither complete nor 'stable' (there is a huge load of issues or PRs), it would make sense to break compatibility all at once by starting of with a new Monogame branch. Then, to ensure the 'Write once, play everywhere' aspect of Monogame, all components should be analyzed of whether they are a core part of the framework (which would end up in a package 'MonoGame.Core') or either device, technology and/or platform specific (for example a 'MonoGame.Devices.Mouse' package only available for the desktop, so stuff like 'IsMouseVisible' can be removed from the 'Game'). Packages like 'MonoGame.DesktopGL' could simply serve as meta-packages to simplify MonoGame integration. Game-specific parts ('Game', the whole game loop, interfaces like 'IUpdateable' etc.) could also be separated in a package like 'MonoGame.Games', so the framework could also be used for graphics programming etc. What I am describing is essentially how it's being done in engines like Xenko (formerly Paradox3D) where it's up to the developer what platform he wants to support and how the game is being composed.

Additionally, platform-specific stuff should be abstracted away through contracts, not inheritance, so that the inplementations could be easily switched out when needed. Finally, we could end up with a single package 'MonoGame' which wires everything needed through bait-and-switch.

I know it does sound way simpler than it actually is and I'd need to get through the source myself in-depth to make specific suggestions, but I guess it could be helpful to just switch the mindset of the devs from making a mono-based XNA re-implementation to a brand new framework with the spirit of the Mono project as a start.

I have perhaps a slightly different opinion on this. I am not an XNA developer nor a C# developer. My projects are green field and not ports of existing XNA projects. That said (and read beyond this statement), I think there is huge value in maintaining the XNA interface. There are probably projects out there that are still XNA based. There are many books about XNA (for cheap). There are hundreds of example and tutorial projects for XNA, with over 100 on Microsoft's site alone. There are not nearly that number of MonoGame specific examples or tutorials.

Right now, I think of MonoGame as a Facade over XNA. I can use XNA stuff, with some MonoGame enhancements, i.e. Pipeline, and get the platform portability I desire and leverage the educational resources available. I would also like in the future to use new features or even a new paradigm that may not be XNA like at all.

I would suggest instead you create a XNA Facade over MonoGame. This would support moving MonoGame into its own namespace as well as doing interface breaking changes. The XNA Facade would maintain (as much as possible) the XNA interface/contract. Those porting or trying to leverage existing knowledge or examples can use the XNA Facade. If the XNA Facade was just directly calling the MonoGame implementation, the cost is a slight performance hit for having to make an extra method call. Perhaps the compiler even sees this and embeds or optimizes it away. Then as projects needed more performance or more functionality than is offered by XNA implementation currently, they can gradually move to using a MonoGame API.

I am in favor of moving beyond XNA. I think it would be more successful if it was done incrementally and if it could be used incrementally. If you want XNA compatibility for whatever reason, then you need to include XYZ blob of code (XNA Facade over MonoGame API) to be compatible even if you do not use it all. If you are able to utilize a more robust framework and perhaps more bleeding edge using the "lower level" MonoGame API directly is for you. You even have ready made "conversion" implementations by looking at what the XNA Facade code does to utilize MonoGame. Not that it would be a good example, but I think having something that works is a better starting point than having something written correctly but doesn't work.

with the current state of Monogame, all the paradigms and methologies of an OOP language don't make much sense, because everything could be put in "Game".

I really disagree here. You can use all the patterns you want without bothering with the internals of MonoGame. To me your statement sounds like "because the framework allows bad design I'm forced to use bad design".

From the start XNA compatibility has been a goal of MG and if you take a look at the forum, you'll see there are still a lot of people that are switching their XNA game to MG. You can't just start over and drop the XNA API because it has some flaws.

In theory what you said is really nice and all, but starting from scratch would require huge effort from everyone involved, it would mean no more easy portability for all XNA devs and the community would have to learn to use the new API. I think that would be the end of MonoGame.

There is something awkward about graphicsdevicemanager. I've just treated it as a glorified 'GraphicsDeviceInitializerArguments' object that is only ever used for the short moment in time between the game starting and the graphics device being allocated.

@artganify:

device, technology and/or platform specific (for example a 'MonoGame.Devices.Mouse' package only available for the desktop, so stuff like 'IsMouseVisible' can be removed from the 'Game')

Don't "fall into the hole" of you very own need/knowledge/other stuff should be applied to everyone and everything !
No offence, I mean, consoles can also have mouse device, and as devices manufacturers are sometimes creative, there is so much stuff, ie: keyboard are also available for tablet for instance, removing all keyboard stuff for tablet platforms would be very bad.

Best would be to have a pluggable design, with platform specific code.
So on Playstation or WII, we could have a MG.Device.Mouse and kind of pragma in MG itself "usemouse" or something which allow people making game for these platforms to deal with mouse input if it's applicable to the game and devs want to add it.

But, such design looks complicated and issues prone, maybe best is to have everything by default with empty methods, dummy properties if not applicable at all (mouse related methods for phone, unless finger can be considered as a mouse device in some case). So
isMouseVisible would be either always true or false on phones.

@kennethsuda Those are very interesting points. I've got to admit that I didn't thought about the huge amount of already existing resources (tuts, samples) for XNA. MonoGame, especially its users can highly benefit from those.

I'd be really interested in the performance or development costs of such a fa莽ade. If the MonoGame devs come up with a brand new API that requires the XNA fa莽ade to be awkwardly twisted in order to work properly, I doubt it's worth the time.

@Jjagg

You can use all the patterns you want without bothering with the internals of MonoGame.

Sort of. Of course I can abstract away MonoGame in a way that I don't have to bother about its APIs anymore, but then I'm just creating an abstraction for the sake of having abstraction, which increases complexity and hurts performance. Certain patterns are also extremely awkward to implement, because MonoGame not only allows 'bad design', but sometimes makes it really difficult to use something different than intended.

Of course I can abstract away MonoGame in a way that I don't have to bother about its APIs anymore

That's not what I meant, I was just responding to your statement I quoted in my comment

I've got 2 projects going on currently where on one I weight correctness and modularity more than performance, so I'd like to use stuff like IoC through DI, on the other one I need certain logic blocks to be processed as fast as possible, so I keep all stuff tightly coupled with static accessors and what not. What I'm saying is both should be possible - with the current state of Monogame, all the paradigms and methologies of an OOP language don't make much sense, because everything could be put in "Game".

This is about game logic, not the MG API. How does MG limit you/force you in a certain direction? Again, I commented mostly because I heavily disagree with that last sentence.

Certain patterns are also extremely awkward to implement, because MonoGame not only allows 'bad design', but sometimes makes it really difficult to use something different than intended.

Can you give an example of this, because I don't understand. MG just gives you the API and you build your game on top with all the patterns and stuff you want. How does the MG API affect your design? And how could that be improved then?

I don't really know how the Content manager thing work on MonoGame
But when i was using MonoGame it was just an annoying thing that i avoided like the plague

If you plan to rethink MonoGame, please take into account the people who want to manage the content as they want

Also it would be great to see TTF font support, better audio support (OGG, MP3) and GLSL shaders

Just my 2cents

@scellow It's been a while, but I'm still going to respond to this.

I don't really know how the Content manager thing work on MonoGame
But when i was using MonoGame it was just an annoying thing that i avoided like the plague.

You think it's annoying without trying to understand how to use it? The way I understand it you're essentially saying "I don't know how it works and didn't want to learn how it works, but I think you shouldn't do it that way." Something won't be changed because someone who does not understand it thinks it isn't right.

I'm not sure about all content types, but at least textures can be directly loaded from file without using a Content Manager.

There's a good reason for building content and using a Content Manager though, there's an open issue for writing something about this in the docs #4600. For now you can read a write-up on dellis' blog (http://www.infinitespace-studios.co.uk/general/monogame-content-pipeline-why/).

By the way, if you want to handle content your own way, no one is stopping you from writing classes to do this.

Also it would be great to see TTF font support, better audio support (OGG, MP3) and GLSL shaders

You probably mean directly using ttf fonts, there's an open PR for directly importing/processing fonts rather than using the SpriteFont Description method (which works with TTF fonts). ogg and mp3 are supported. The only thing I really agree with in your post is that last thing. Yes, 2MGFX should be able to build glsl too! This will not affect API however so it's not really relevant in this thread :p

@Jjagg i phrased it wrongly i think

The thing i hate about the content pipeline is i have to use it whenever i have to edit, import new asset, while prototyping, or even for modding it is just a pain and counter productive to use

Sure it makes sense if your game is ready for release, and don't support mods, but it is just a PITA during dev process, or if you only target desktop

I would have preferred a post build command so i can implement it in my workflow, but having to use a specific program just irritates me, but anyways, as you say nothing stops me from writing the classes i want, but if i'm looking for, let's say monogame, it's because it is a ready to use game framework, if i start to implement things on my side, then better to go raw opengl

The thing i hate about the content pipeline is i have to use it whenever i have to edit, import new asset, while prototyping, or even for modding it is just a pain and counter productive to use

Ah, I understand better now. Yes, you have a point. I can help lighten the process though :)

It's true that you have to add content to the mgcb with the pipeline tool. You don't have to explicitly build content though. If you start from a template, you'll see the Content.mgcb build action (which is a build hook like you say) is set to MonoGameContentReference. That means that when you build your project it will attempt to build your .mgcb file and copy over the xnb's to your output folder. The build action is defined in the .targets file here: https://github.com/MonoGame/MonoGame/blob/develop/MonoGame.Framework.Content.Pipeline/MonoGame.Content.Builder.targets in case you're interested in how to do this.

That leaves adding content to the .mgcb. It's definitely easiest to do that through the pipeline tool. I think it wouldn't be too hard to write a script for this though. If you open the .mgcb file with a text editor you can see the format. You could write a script to sync all files in your content folder to the mgcb with default settings for quick prototyping. I'm not sure it's as easy as that, but it would surely be doable. A script like that would be quite nice to have actually. I might attempt this at some point :) You can then modify the MonoGameContentReference build action so it executes your script first.

If you're setup like that, you can just drop raw files in the Content folder of your game, build it and at runtime load it with a ContentManager. What happened automatically:

  • Added the files to the .mgcb (the syncing script)
  • Built the .mgcb when you built your project (MonoGameContentReference)
  • Copied over the output to the bin folder of your project (MonoGameContentReference)

Note that there is no information on MonoGameContentReference in the documentation yet, but I have an open PR for adding it.

even for modding it is just a pain and counter productive to use

I replied to a topic on the community forums about modding. I said this

Anyone can install MonoGame so it's possible for modders to use the pipeline tool to build xnb's (though not very convenient that they'd have to go and get MonoGame). You could also allow other formats and try to build the xnb's yourself, though the builds could fail of course. Or you could supply the pipeline tool or some custom tool that builds content specifically for your game with the game itself. The last option is probably most convenient for modders.

So yes, that's not the most convenient thing about the way the Content Pipeline works. You could attempt to build the raw content users add with default settings, but that might not always be what you want. Still, IMO if you look at the whole picture the pros outweigh the cons. Dellis' post linked in my previous comment talks about the pros.

but if i'm looking for, let's say monogame, it's because it is a ready to use game framework, if i start to implement things on my side, then better to go raw opengl

To sum up what dellis' says in his blog post: The Pipeline Tool is how MG can abstract away differences in required content formats for different platforms, so it's essential in being cross-platform.
So MG is a ready to use cross-platform game framework, but to be cross-platform in terms of content it uses the Content Pipeline system. So writing your own abstractions to handle content, while the import/build process might be easier for desktop OpenGL targets, it will only be for that. I think for handling cross-platform content and allowing settings in the build process the Content Pipeline Tool is as simple as can be.

I hope that cleared up some stuff and made the Content Pipeline system more acceptable :)

I'm not a fan of this process anyways, i like to work with raw assets when i develop something

The fact that i have to use a separate tool makes it annoying, no offence, i can understand that some people needs it but i come from libGDX, and i can clearly see the advantage of using raw asset, it makes everything smooth, you don't need to compile something to load your stuff, you don't have to depend on extra tools, you put your assets in the asset folder and that's it, you give the game to the artist and he edit/draw/add assets without having to worry about technical stuff, or having to install something

you don't have to depend on extra tools, you put your assets in the asset folder and that's it,

There is already an api for loading an asset into a pre-existing object - ie, don't allocate a new texture, load the new data into an existing one. The part that is missing, is to watch the source asset location for file changes, trigger building of xnbs that depend on the changed asset, (and then load it into the existing content item).

I implemented a version of this myself at one point, but it would be convenient for a lot of people if this was a feature of monogame itself.

Why building xnb, i don't want to manipulate multiple files for a single asset, there should be an option to just put raw asset in a folder, and content.Load<Model>("myModel.obj"); or just new Model(path, config); or even var modelLoader = new ModelLoader(config); myModel = modelLoader.Load(path); should be able to load it, without creating xnb or other junk, that's it, forcing me to do something else is non productive and annoying

just put raw asset in a folder, and content.Load<Model>("myModel.obj"); should be able to load it, without creating xnb or other junk, that's it, forcing me to do something else is non productive and annoying

We would then have to include all model format loaders into the runtime library, process the model on load (flipping axes, scaling, etc), process textures that may be embedded in the model, generate vertex buffers and index buffers... all of which takes time and memory, slowing down your asset loading. It also increases the size of the runtime to accommodate the extra code for loading the various model formats and performing the processing.

This loading of various formats and processing into a format that is easily and quickly loaded directly into GPU memory is performed at build time _without any additional effort on your part_ by the content build pipeline as part of the solution build in Visual Studio or Xamarin Studio.

If you simply drop a bunch of raw assets into a folder, how do you set build properties for them? This textures needs to be compressed, but this texture should not be compressed. This model needs extra custom processing (build a bounding box for collision rather than a bounding sphere), but this other model should retain the bounding sphere. These WAVs should be compressed to ADPCM, but this WAV should be compressed to M4A for streaming music.

We would then have to include all model format loaders into the runtime library, process the model on load (flipping axes, scaling, etc), process textures that may be embedded in the model, generate vertex buffers and index buffers... all of which takes time and memory, slowing down your asset loading. It also increases the size of the runtime to accommodate the extra code for loading the various model formats and performing the processing

I never had these issues with libGDX, i only had to convert my FBX with animations to their specific format, but that's it

I'm not saying that should be like that and nothing else, just it being an option

If you simply drop a bunch of raw assets into a folder, how do you set build properties for them?

You handle that in your code, since it's flexible

It looks like that i'm the only one who have that issue with the Content Pipeline, probably because of my project (Data Oriented)

This is the way MG works and I doubt it will change in the near future because this is fine for most people and a new content system takes a lot of effort to implement and maintain. If you really want it to work the way you describe it, I suggest you build a layer on top of the Content Pipeline, fork MG and modify it, use the stuff ProtoGame offers for this or check out another framework/engine.

Sometimes monogame wants to be a simple framework, but then you start to force stuff, isn't that the job of the engine to handle the content? So to make an engine i have to stick with how you handle the content, and use your tool, or i have to rewrite everything from scratch? That's is why i think raw data should be supported too

So to make an engine i have to stick with how you handle the content, and use your tool, or i have to rewrite everything from scratch?

You can surely leverage the existing importers and processors if you'd like. The Content Pipeline Tool is just a GUI for mgcb, so another option is using mgcb through scripts like I said before. You can automate this to the point were it seems like you can load raw assets or you can wrap methods like Texture2D.FromStream in a raw asset loader class if you want. You can argue that this is not what _you_ prefer, but MG is open source, so you're free to modify it as you see fit. We need to maintain the content pipeline as is with all the options and seperation of assets and code for easy collaboration between artists and devs for production games. It works as is and there are things that take higher priority than expanding it the way you want. If you want to load raw assets for quick prototyping or any other reason, try one of the solutions I mentioned previously.

Sometimes monogame wants to be a simple framework, but then you start to force stuff, isn't that the job of the engine to handle the content?

In the first place MonoGame attempts to offer what XNA does. The content building system is similar to that of XNA. Also, without the options of the content system it would be a lot harder to release production games for MG users.

@Scellow, you can always do what Protogame does here, which is to link the content pipeline against the desktop versions of your game (or in our case, the desktop versions of the library). The engine then just calls the content pipeline APIs internally when it observes the raw assets in the folder, and compiles the content on-the-fly.

One of the nice things about having this content compilation abstracted underneath is that if you're developing on mobile, you can do useful things like having a content compilation server running on your desktop pointing at the raw assets, and have the game running natively on the mobile device loading and reloading assets from the remote server (where it can compile it on demand).

Correct me if I'm wrong, but didn't XNA offer the ability to load some resources directly from unprocessed files? Things like Texture2D.FromStream and the SoundEffect constructors taking a byte array come to mind. So the problem of having to process content at build time with the pipeline is only a partial one, mostly related to, I believe, models and fonts.

Correct me if I'm wrong, but didn't XNA offer the ability to load some resources directly from unprocessed files?

That is correct, and we provide the same. Providing support for loading from common 3D model formats at runtime is a much more complex task, and is not something that MonoGame will provide as a standard feature.

@KonajuGames ah, I see. Maybe an idea for when MonoGame and XNA diverge further; provide an API that allows the consumer to supply the model data as vertices etc, and let the developer worry about turning their model files into the required data format. This way, guys like @Scellow can get their desired flexibility, and you guys won't have to provide all kinds of format loaders, since any developer wishing to do this will have to supply their own.

The Model class in XNA/MonoGame is really intended as a starting point for developers to make their own model class that best suits their needs and requirements. The Model class is essentially just a hierarchical collection of vertex and index buffers with related materials. Fairly easy to write your own and supply it with whatever data you want.

Maybe an idea for when MonoGame and XNA diverge further; provide an API that allows the consumer to supply the model data as vertices etc, and let the developer worry about turning their model files into the required data format.

XNB is an open format, you can write your own Model/XNB.
Or you can write your data in any format you like and load them onto a VertexBuffer.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

monsieurmax picture monsieurmax  路  5Comments

Legendree picture Legendree  路  3Comments

dazinator picture dazinator  路  5Comments

tomspilman picture tomspilman  路  4Comments

Halofreak1990 picture Halofreak1990  路  4Comments