Create My Own Color Struct?

Thumbs up to chucks suggestion.

Even if you could inherit from a struct, it would tie your Color implementation to MonoGame and you’d be unable to use it without MonoGame.
@markus and @DexterZ solution will have your color struct still depend on MonoGame.

I got two alternative to what Chuck suggested:

  1. Conditional compilation and no conversion overhead, by using explicit layout to simulate unions (like in C) and having a Microsoft.Xna.Color member field. This lets you interpret the data in your color struct as a MonoGame Color. Your struct must have the same layout as MonoGames Color struct for this to work. Here’s a Gist with an implementation: https://gist.github.com/Jjagg/9b8c7c8f90dbe936e495ce010c446f32
  2. Have extension methods in another assembly to do conversion from and to MonoGames Color struct so you don’t need conditional compilation in your main library, but can just include the conversion assembly when you use your lib with MonoGame.

@Jjagg so wait even if I include monogame in my class library I would still need to include monogame in my actual project?

You don’t need to link to MonoGame (add it as a reference), but you’ll need to provide the dll with your game so your class library can call into it. So yeah, you’ll still need to include the MonoGame dll with your game.

hmm ok I thought including it in my library would store it internally.

so I am guessing this piece of code does that?
#if MONOGAME //MonoGame stuff here? #endif

Oh, you want everything to be contained in one dll. I thought you only wanted to avoid having to reference MonoGame from your game project. There are ways to bundle multiple dll’s into one.


It’s not just MonoGame.dll though. MonoGame depends on other dll’s, just have a look at your output folder.

Why do you care so much about only having one dll? Are you planning to publish your engine and you want it to look as simple as possible?

1 Like

@markus this is what I wanted…
however I have a small problem that i don’t think needs another topic.

how do I handle hooks for monogame in a static class?

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

using Microsoft.Xna.Framework;

namespace AC.Engine
{
	public static class Program
	{

		[STAThread]
		static void Main()
		{
			AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
		}

		static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
		{
			using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MonoGame.Framework.dll"))
			{
				Byte[] assemblyData = new Byte[stream.Length];
				stream.Read(assemblyData, 0, assemblyData.Length);
				return Assembly.Load(assemblyData);
			}
		}

		private static Game game = new Game();
		static void Run()
		{
			game.Run();
		}


		//Hooks how do I run them?
		static void Init() { }
		static void Tick() { }
		static void Draw() { }

	}
}

You have to inherit from the Game class and override the Initialize, Update and Draw methods to call your static functions. I’m assuming that you can’t call the static functions directly, because they are in a different assembly, that you don’t want to reference, right? In that case you pass the static functions as delegate parameters to your game class constructor.

public class MyGame : Game
{
    Action init;

    public MyGame(Action init)
    {
        this.init = init;
    }

    protected override void Initialize()
    {
        init();
        base.Initialize();     
    }
}

and then create the game like this

MyGame game = new MyGame(Init);

Is this what you’re looking for?

1 Like

more or less I was wondering for tick and draw too

It’s the same basic concept for draw and tick.

public class MyGame : Game
{
    Action init;
    Action tick;
    Action draw;

    public MyGame(Action init, Action tick, Action draw)
    {
        this.init = init;
        this.tick= tick;
        this.draw= draw;
    }

    protected override void Initialize()
    {
        init();
        base.Initialize();     
    }

    protected override void Update(GameTime gameTime)
    {
        tick();
        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        draw();
        base.Draw(gameTime);
    }
}

// and then create the game like this
MyGame game = new MyGame(Init, Tick, Draw);
1 Like

is there a way to hide the Initialize Update and Draw methods of GameClass though?

I don’t want any confusion when using my engine.

I don’t understand enough about how your engine will be used from a user perspective. Can you explain a bit more how having those functions is ruining the user experience?

again I just want to hide monogame behind my library so the user only has what I expose to them
is no that is ruining it, I just want to do this for learning purposes.

Pretty sure that goes against the MonoGame licence… you need to be very clear of your intention there, to me it sounds like you want to hide the use of MonoGame in order to appear as an entirely new framework, this is not only possibly against the MG licence but also illegal.

You should probably show a design document for this usage.

It does not. It’s perfectly fine (legally) to use your own abstractions to hide MG stuff behind. It’s also fine to build a commercial engine on top of MonoGame. You just need to include the original license in source code distributions.

@Shadowblitz16 I don’t really get the point of what you’re trying to do though. It made sense to me when you said you wanted your engine to be usable without MonoGame, but by directly using MG classes internally that’s not going to work. There’s also no benefit in recreating MG structs and it’s a pain to do.

2 Likes

I forgot to mention including the MG licence, but probably because it sounded like he wanted to obscure it entirely… EDIT Which no matter what, would be wrong…

It’s a lot of work for not a lot of pay off. MonoGame itself is already an abstraction of the machines that are out there…

1 Like

well my original plan was to expose the monogame color struct as part of my engine, so that I didn’t need to include monogame itself.

for example I would only have to do this…
`
using AC.Engine.Graphics

namespace AC.Engine
{
    class Texture
    {
        list<Color> data;
	public Texture()
	{
	   data  = new list<Color>();
	}
    }
}

`

I would be fine with including the mg licence as long as I could sell my editor and runner

1 Like

MonoGame is MIT-licensed, so yes, you can sell products based on it. Doesn’t matter if they are games, engines, educational software, etc.

It is not uncommon to abstract away from a specific platform. That helps to make games portable in general. MonoGame is already portable on so many platforms, which is nice and convenient. Eventually I want to go down to lower level frameworks as time permits. For myself, while building a specific type of engine, there will probably never be a perfect framework that matches up to my work flow, or custom tool chains, hence why I like to minimize the use of the framework directly in my game. This is also why I choose not to use Unity, as I want my own APIs and work flow.

My first iteration of my current game engine, I essentially wrapped MonoGame. This left me with a very MonoGame feeling game, which is not a bad thing, just not quite where I was wanting to be. I was able to do much my work flow, but it wasn’t so clean as I would have liked.

In my second iteration, which is a work in progress now, I wanted as much of my game engine as possible to be in the work flow I wanted, and using as much .NET Standard 2.0. I also wanted to push MonoGame farther down in my library so I could really focus on my engine and less on platform and technology. I decided to go with a Domain Driven Design approach.

Without going into an excruciating explanation of DDD, I simply have 3 major tiers. Application, Domain, and Infrastructure. Each tier might be 1 library or a collection of libraries (depending on how you want to organize your code).

The Domain is the heart of the engine runtime. There is no MonoGame references in it. Matter of fact, there are no technology or infrastructure references beyond what comes in the .NET standard. When I need access to some type of “infrastructure”, which could be devices, video, sound, network, etc. I define interfaces for all of those infrastructure elements and the way I want to use them. That’s the heart of what the Domain tier tries to accomplish. Focus on solving your domain problems. This approach also allows for easier unit testing, since I can mock the infrastructure services.

The Infrastructure tier is the part that talks to any of the local hardware or network resources. I can build different infrastructure tiers, based on what platform/framework I want. The Infrastructure tier wraps the platform specific code into a class that implements the interfaces defined in my Domain. The domain does not reference the infrastructure tier, ever, rather the infrastructure tier references the Domain, and implements it’s interfaces.

I then have my Application tier, which references the Domain and the Infrastructure. This is where I do my dependency injection. When I construct my Domain Game instance, I can inject the infrastructure elements needed. The application tier actually does very little, other than subclass the Framework.Game object and instantiate my Domain.Game object. Action methods simply call the action methods in my Domain.Game, which then transforms all of that to satisfy my game’s needs.

Using this approach, you can do it sort of trial and error, but it really helps to work out how you want your Domain to function, as you might choose to go down a path that is terribly incompatible with some types of infrastructures, and the transforms might be costly (can’t imagine how I figured that out :stuck_out_tongue: ). I have spent a lot of time in just figuring out how I want to inject the infrastructure objects into my system, and how those will be referenced. So far, it has been time well spent.

If you are not familiar with Domain Driven Design, there is plenty of material that will leave you in daze. I actually follow the model Microsoft illustrates for DDD. It is in the context of micro-services, which is more attuned to what I do professionally, but it very much can be applied to game development.

I know this is off topic a bit, in the area of implementing color, I went with using .NET Standard for color in every place in my Domain. I defined an IColor interface with a ToSystemColor() method. In my Infrastructure tier, I created Color struct that implements the interface, wraps the MonoGame Color, and provides a constructor that takes a System.Drawing.Color, and implements the ToSystemColor(), returning a System.Drawing.Color.

	public Color(System.Drawing.Color c) {
		_color = new Microsoft.Xna.Framework.Color(c.R, c.G, c.B, c.A);
	}

	public System.Drawing.Color ToSystemColor() {
		return System.Drawing.Color.FromArgb(_color.A, _color.R, _color.G, _color.B);
	}

For anything MonoGame specific, I can use the Color class I created to wrap the MonoGame Color. In my Interface methods that require color, I make sure they use System.Drawing.Color.

Design a DDD-oriented microservice