Introducing the Unit Testing Context Pattern

Another pattern?

Well yes. I write unit and integration tests almost every day and along the way i learned all kinds of different tricks and gotchas on how to be more productive and how to write less fragile tests.

But one of the patterns that emerged i never saw in the code of other people so i decided to share it here since i find it very useful.

I call it Testing Context Pattern and – unlike it’s name – its very simple.

Idea is to create in your Test Fixture a private class called (you guessed it) TestContext and put all the mocks/instances needed for testing the current class and then create instance of that class we test by using those mocks and then also expose all of that as public fields of the TestContext.

That way we have all we need for testing in one place and we can start having fun!

So if we are testing class WebPageDownloader that needs two more entities to function (IUrlPermissioner and IUrlRetriever) then we create class TestContext like this:

        private class TestContext
        {
            public Mock<IUrlPermissioner> PermissionerMock;
            public Mock<IUrlRetriever> UrlRetrieverMock;
            public WebPageDownloader Downloader;
        }

Notice here that we expose the mocks of the dependencies on the context (I’m using Moq testing framework but you can choose any other you like) this is very important because later in our tests we can then give further setups/expectations to those mocks that are used inside test class.

Next we create a private method on test fixture that creates instance of context for us, initializes it with all the mocks needed for testing and the tested class instance itself and returns it (this is to avoid creating this in each test):

        private TestContext CreateContext()
        {
            var ctxt = new TestContext()
            {
                PermissionerMock = new Mock<IUrlPermissioner>(),
                UrlRetrieverMock = new Mock<IUrlRetriever>(),
            };

            ctxt.Downloader = new WebPageDownloader(ctxt.PermissionerMock.Object, ctxt.UrlRetrieverMock.Object);

            return ctxt;
        }

As you see i create all the mocks that our tested class needs, then i instantiate it by passing mocked instances into its constructor and then i save mocks and target class in the context for usage in further tests.

Testing Context in action

So now in each test i call CreateContext method to get fresh instance of TestContext and start testing my target class.
Good thing about this is that in the TestContext we have all the mocks of dependencies used to create the tested class, so we can still manipulate them, mock out some specific methods for each test, and also we can check later in the test if the mocks were used in proper way, check what methods the target class invoked on them etc.

Here is an example of test that checks if our class throws exception for URl that is not permitted by IUrlPermissioner:

        [Test]
        [ExpectedException(typeof(SecurityException))]
        public void Download_WhenNotPermitted_Throws()
        {
            var ctxt = CreateContext();

            var badUrl = "http://www.SomeBadUrl";

            // arrange
            ctxt.PermissionerMock.Setup(a => a.IsUrlAllowed(badUrl)).Returns(false);

            // act
            ctxt.Downloader.Download(badUrl);

            // assert we don't need to do since we have ExpectedException attribute
        }

As you can see in the test we just call the CreateContext method to get fresh context, then we use the mocks from the context to setup our expected calls and return values, and then we invoke actual method on the class we are testing and then we expect the exception (via ExpectedException attribute that we placed on the test method)

Here is little more complex scenario where we setup multiple mock interactions with our class and then expect return result to be correct:

        [Test]
        public void Download_WhenAllowed_ShouldReturnWebpageGotViaRetriever()
        {
            var ctxt = CreateContext();

            var OkUrl = "http://www.SomeOkUrl";
            var OkUrlContent = "Some Web Page";

            // arrange
            ctxt.PermissionerMock.Setup(a => a.IsUrlAllowed(OkUrl)).Returns(true);
            ctxt.UrlRetrieverMock.Setup(a => a.Retrieve(OkUrl)).Returns(OkUrlContent);

            // act
            var result = ctxt.Downloader.Download(OkUrl);

            // assert
            Assert.AreEqual(OkUrlContent, result);
        }

Another good thing here is that if you later refactor your target class and add/remove dependencies you can easily change TestContext and CreateContext method accordingly and none of your existing tests should fail to compile because of that, unlike the situation when you would do all this in each test.

As usually, you can download Visual Studio 2012 solution showing this in action if you are interested.

I hope this simple pattern can help someone in writing better tests.
If you have comments or if you are doing something similar in your tests leave a comment i would love to hear it.

Marbles

Video of my game Marbles for Windows 8

Hi all,

here is 1 minute video of my game Marbles for Windows 8. Its recorded on my desktop machine and played using a mouse,

but it works also with touch based devices, and you can even play with multiple hands at the same time, which opens some interesting

multiplayer possibilities…

Let me know if you have some ideas how to improve the gameplay, what power-ups i could add etc…

Solving Resolution Independent Rendering And 2D Camera Using Monogame

As i promised in my previous post where i announced my Windows 8 game Marbles, i will try to tackle some of the common problems that beginner game developers encounter.

In this post i will jump ahead a little and talk about Resolution Independent Rendering using Monogame.

What the heck is Resolution Independent Rendering?

Well its fancy name for finding ways to not care about resolution during your game development.
Idea is that you render always using fixed (internal) virtual resolution you choose and then simply stretch or shrink all that for the real resolution of the current device you are using to display the game.
Sounds simple right?

Why solving Resolution Independent Rendering?

Because of multiple reasons:

  • First of all its very important and difficult subject. You don’t want to care about resolution on which you are displaying your game. Game developer has enough problems to solve even without this.
  • Every game developer that is targeting multiple devices/platforms has to solve this in one way or another
  • I struggled until i found a solution for this and want to share it with the community
  • many people lately asked me to share code for this and i kept sending them same email with zipped source code for this so it seems like a good idea for blog post :)

How are we going to solve it?

Firstly, we will decide on the internal resolution for our game, lets say 1366×768.

Then we will determine what is the real screen resolution of the device/monitor where we are rendering our game.

Then we will determine what is the best fit rectangle that we can get on this real screen that matches our virtual resolution (but always maintaining aspect ratio of the Virtual Resolution we decided so we don’t have stretching/shrinking artefacts).

For example if real screen resolution is bigger then our internal virtual resolution, we will create a best fit ‘viewport’ inside of that larger resolution by maintaining aspect ratio but stretching our viewport – therefore our game screens will be stretched and rendered inside this bigger viewport on the screen.

For smaller screen we will do the opposite – shrink the viewport and maintain aspect ratio of our virtual resolution – therefore our game gfx will first shrink to fit into the smaller viewport and then be rendered on the screen.

Since the viewport we decide on will often not fill the real screen around it we will fill it with some color – effect known in film industry as Letterboxing.

Once we know that centered viewport rectangle where we will render our stretched/shrinked screen we then create transformation matrix that we will use in all the rendering calls (by passing it to the SpriteBatch.Begin method).

Also we need to set the Mogame/XNA ViewPort property to that same viewport to limit rendering only to this region on the real screen.

To be honest, I’m not the one who invented this technique, first time i saw someone using GraphicDevice Viewport for this is David Amadors blog post on same subject where he shares example on how to achieve resolution independence with XNA.

But this was not enough for me i wanted to have also a Camera on top of that so that i can rotate zoom etc.

So i included camera that builds up on this resolution transformation matrix of the Resolution Renderer and creates its own view matrix (rotated, zoomed, translated etc).

Where is the code???

In the sample visual studio 2012 solution  you can see this in action where we are rendering a fixed image of 1366×768 to any screen you try it on, stretching and shrinking it accordingly without any changes in the code. Also you can use keyboard + and – to control camera zoom and Shift + and Shift – to rotate it.

And the screenshots?

Here are the screenshots of the sample code running on 3 different screens/devices:

1680×1050 monitor: image is stretched with little orange bar above

1680x1050

1280×1024: image is shrinked and we have strong pillarboxing effect

1280x1024

1024×768 – image is shrinked with some pillarboxing

1024x768

Note: this orange color is just for the demo, code allows you to easily set what color will the Pillarbox be.
In the sample Visual Studio 2012 solution for Monogame 3.0.1 you will want to check out two important classes:

1. ResolutionIndependentRenderer – this class handles everything about resolutions and creates viewport transformation matrix for resolution independence

2. Camera2D – this class usess ResolutionIndependentRenderer and its matrix and creates final camera view matrix you should use for SpriteBatch and allows you to set camera position, zoom, rotate etc

Here is the code for ResolutionIndependentRenderer:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Roboblob.XNA.WinRT.ResolutionIndependence
{
    public class ResolutionIndependentRenderer
    {
        private readonly Game _game;
        private Viewport _viewport;
        private float _ratioX;
        private float _ratioY;
        private Vector2 _virtualMousePosition = new Vector2();

        public Color BackgroundColor = Color.Orange;

        public ResolutionIndependentRenderer(Game game)
        {
            _game = game;
            VirtualWidth = 1366;
            VirtualHeight = 768;

            ScreenWidth = 1024;
            ScreenHeight = 768;
        }

        public int VirtualHeight;

        public int VirtualWidth;

        public int ScreenWidth;
        public int ScreenHeight;

        public void Initialize()
        {
            SetupVirtualScreenViewport();

            _ratioX = (float)_viewport.Width / VirtualWidth;
            _ratioY = (float)_viewport.Height / VirtualHeight;

            _dirtyMatrix = true;
        }

        public void SetupFullViewport()
        {
            var vp = new Viewport();
            vp.X = vp.Y = 0;
            vp.Width = ScreenWidth;
            vp.Height = ScreenHeight;
            _game.GraphicsDevice.Viewport = vp;
            _dirtyMatrix = true;
        }

        public void BeginDraw()
        {
            // Start by reseting viewport to (0,0,1,1)
            SetupFullViewport();
            // Clear to Black
            _game.GraphicsDevice.Clear(BackgroundColor);
            // Calculate Proper Viewport according to Aspect Ratio
            SetupVirtualScreenViewport();
            // and clear that
            // This way we are gonna have black bars if aspect ratio requires it and
            // the clear color on the rest
        }

        public bool RenderingToScreenIsFinished;
        private static Matrix _scaleMatrix;
        private bool _dirtyMatrix = true;

        public Matrix GetTransformationMatrix()
        {
            if (_dirtyMatrix)
                RecreateScaleMatrix();

            return _scaleMatrix;
        }

        private void RecreateScaleMatrix()
        {
            Matrix.CreateScale((float)ScreenWidth / VirtualWidth, (float)ScreenWidth / VirtualWidth, 1f, out _scaleMatrix);
            _dirtyMatrix = false;
        }

        public Vector2 ScaleMouseToScreenCoordinates(Vector2 screenPosition)
        {
            var realX = screenPosition.X - _viewport.X;
            var realY = screenPosition.Y - _viewport.Y;

            _virtualMousePosition.X = realX / _ratioX;
            _virtualMousePosition.Y = realY / _ratioY;

            return _virtualMousePosition;
        }

        public void SetupVirtualScreenViewport()
        {
            var targetAspectRatio = VirtualWidth / (float) VirtualHeight;
            // figure out the largest area that fits in this resolution at the desired aspect ratio
            var width = ScreenWidth;
            var height = (int)(width / targetAspectRatio + .5f);

            if (height > ScreenHeight)
            {
                height = ScreenHeight;
                // PillarBox
                width = (int)(height * targetAspectRatio + .5f);
            }

            // set up the new viewport centered in the backbuffer
            _viewport = new Viewport
                            {
                                X = (ScreenWidth / 2) - (width / 2),
                                Y = (ScreenHeight / 2) - (height / 2),
                                Width = width,
                                Height = height
                            };

            _game.GraphicsDevice.Viewport = _viewport;
        }
    }
}

And then there is Camera2D that has all the usual camera properties that you can use to move it around and zoom rotate etc.

Here is the code for camera:

using Microsoft.Xna.Framework;
using Roboblob.XNA.WinRT.ResolutionIndependence;

namespace Roboblob.XNA.WinRT.Camera
{
    public class Camera2D
    {
        private float _zoom;
        private float _rotation;
        private Vector2 _position;
        private Matrix _transform = Matrix.Identity;
        private bool _isViewTransformationDirty = true;
        private Matrix _camTranslationMatrix = Matrix.Identity;
        private Matrix _camRotationMatrix = Matrix.Identity;
        private Matrix _camScaleMatrix = Matrix.Identity;
        private Matrix _resTranslationMatrix = Matrix.Identity;

        protected ResolutionIndependentRenderer ResolutionIndependentRenderer;
        private Vector3 _camTranslationVector = Vector3.Zero;
        private Vector3 _camScaleVector = Vector3.Zero;
        private Vector3 _resTranslationVector = Vector3.Zero;

        public Camera2D(ResolutionIndependentRenderer resolutionIndependence)
        {
            ResolutionIndependentRenderer = resolutionIndependence;

            _zoom = 0.1f;
            _rotation = 0.0f;
            _position = Vector2.Zero;
        }

        public Vector2 Position
        {
            get { return _position; }
            set
            {
                _position = value;
                _isViewTransformationDirty = true;
            }
        }

        public void Move(Vector2 amount)
        {
            Position += amount;
        }

        public void SetPosition(Vector2 position)
        {
            Position = position;
        }

        public float Zoom
        {
            get { return _zoom; }
            set
            {
                _zoom = value;
                if (_zoom < 0.1f)
                {
                    _zoom = 0.1f;
                }
                _isViewTransformationDirty = true;
            }
        }

        public float Rotation
        {
            get
            {
                return _rotation;
            }
            set
            {
                _rotation = value;
                _isViewTransformationDirty = true;
            }
        }

        public Matrix GetViewTransformationMatrix()
        {
            if (_isViewTransformationDirty)
            {
                _camTranslationVector.X = -_position.X;
                _camTranslationVector.Y = -_position.Y;

                Matrix.CreateTranslation(ref _camTranslationVector, out _camTranslationMatrix);
                Matrix.CreateRotationZ(_rotation, out _camRotationMatrix);

                _camScaleVector.X = _zoom;
                _camScaleVector.Y = _zoom;
                _camScaleVector.Z = 1;

                Matrix.CreateScale(ref _camScaleVector, out _camScaleMatrix);

                _resTranslationVector.X = ResolutionIndependentRenderer.VirtualWidth*0.5f;
                _resTranslationVector.Y = ResolutionIndependentRenderer.VirtualHeight * 0.5f;
                _resTranslationVector.Z = 0;

                Matrix.CreateTranslation(ref _resTranslationVector, out _resTranslationMatrix);

                _transform = _camTranslationMatrix *
                             _camRotationMatrix *
                             _camScaleMatrix *
                             _resTranslationMatrix *
                             ResolutionIndependentRenderer.GetTransformationMatrix();

                _isViewTransformationDirty = false;
            }

            return _transform;
        }

        public void RecalculateTransformationMatrices()
        {
            _isViewTransformationDirty = true;
        }
    }
}

How to use all this???

Its simple :)

In your Game create instance of ResolutionIndependentRenderer and SimpleCamera2D.

Camera accepts the instance of ResolutionIndependentRenderer in the constructor cause it uses its resolution Matrix to calculate its own view Matrix.

On start of your game (or whenever your real screen resolution changes) – user rotates the device, or moves the game to another monitor on desktop PC etc. – you must initialize the

ResolutionIndependentRenderer like this and also invalidate the camera matrix:

        private void InitializeResolutionIndependence(int realScreenWidth, int realScreenHeight)
        {
            _resolutionIndependence.VirtualWidth = 1366;
            _resolutionIndependence.VirtualHeight = 768;
            _resolutionIndependence.ScreenWidth = realScreenWidth;
            _resolutionIndependence.ScreenHeight = realScreenHeight;
            _resolutionIndependence.Initialize();

            _camera.RecalculateTransformationMatrices();
        }

As you see above we are passing to the ResolutionIndependentRenderer virtual resolution we want to use internally and the real resolution of the screen, and then we recalculate matrices in the camera. From that point we can use the same cached camera matrix until we change position or zoom etc (this is handled internally in the camera code).

Here exceptionally we manually have to notify the Camera class that we changed the ResolutionIndependentRenderer matrix so it can recalculate its own matrix.

Next stop is our Draw method of the game:

        protected override void Draw(GameTime gameTime)
        {
            _resolutionIndependence.BeginDraw();
            _spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap, DepthStencilState.None, RasterizerState.CullNone, null, _camera.GetViewTransformationMatrix());
            _spriteBatch.Draw(_bkg, _bkgPos, Color.White);
            _spriteBatch.DrawString(_debugFont, string.Format("Translated Mouse Pos: x:{0:0}  y:{1:0}",_screenMousePos.X,_screenMousePos.Y), _mouseDrawPos, Color.Yellow);
            _spriteBatch.DrawString(_debugFont, _instructions, _instructionsDrawPos, Color.Yellow);
            _spriteBatch.End();

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }

Calling the BeginDraw method on ResolutionIndependentRenderer internally first sets the viewport to full screen, clear it with color that is set in its Background property and then sets the virtual resolution viewport to our virtual resolution so whatever we draw its drawn in the correct centered rectangle.

That way we get that color fill around our game.

Another thing to notice there is that we are passing a camera view matrix to the SpriteBatch.Begin call:


            _spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap, DepthStencilState.None, RasterizerState.CullNone,
                null, _camera.GetViewTransformationMatrix());

This is very important cause if you don’t do this, you will still be drawing to the full screen and we don’t want that.
By passing the Matrix from our camera to the SpriteBatch we tell it to rotate, zoom and translate all our draws to the correct place

Benefit of all this is that we can setup camera and zoom and rotate our screen and move camera around.
At start of the sample code i center the camera to the middle of the virtual screen and set zoom to 1.0 but you can change/animate those values and have some nice effects.

Here is how the camera initialization code looks like:


            _camera = new Camera2D(_resolutionIndependence);
            _camera.Zoom = 1f;
            _camera.Position = new Vector2(_resolutionIndependence.VirtualWidth / 2, _resolutionIndependence.VirtualHeight / 2);

Download the sample visual studio 2012 solution and play with it.

Try to run it on multiple screen resolutions, it should always adapt as best possible and maintain aspect ratio of virtual resolution when stretching/shrinking it to the real screen.

Another cool feature of the ResolutionIndependentRenderer is the ability to convert our real screen mouse position to the virtual mouse position:

            _screenMousePos = _resolutionIndependence.ScaleMouseToScreenCoordinates(_inputHelper.MousePosition);

This is needed because our mouse events are happening in the real screen resolution and we need to convert (translate) them to the correct position in our virtual resolution space which is usually shifted (unless your screen is same size as your virtual resolution) so this method allows you to do that easily.

I hope this code will be of help to all the aspiring XNA/Monogame developers out there!

Check out the sample and let me know if it helps you!

Marbles

Marbles game for Windows 8

Finally my first Windows 8 game called Marbles is finished and available in the Windows Store!

That partially explains why i did not wrote any posts on this blog for almost a year :)

It’s been emotional!

Seriously, it has been quite a journey.

First i was learning XNA, then Monogame, and then game development in general.

I always wanted to write a game (aren’t we all?) so finally i decided to really do it!

At first i started very enthusiastically and tried building a 2d platformer game, and after solving most of technical problems like character and level rendering and physics i sadly realized that there is no way i will be able to complete it alone without help of level designer and gfx artist, sfx artist etc.

Since i was a one man band that meant this game is not gonna happen…

Just for the record, here is the video of that unfinished game – be warned it was just a early prototype.

So eventually after months of work i got real and abandoned that idea and started from scratch.

I realized that if i want to get anything done i need to start small and build simple game and this is how idea for Marbles was born.

Along the way I discovered that developing games is very much unlike writing other software applications.

When you are running at 60 FPS then every byte counts, every loop is considered not necessary until proven otherwise and every operation needs to be fast or its out!

But writing games is very fun so i enjoyed (almost) every moment of it :)

Monogame is for real!

I must say that guys from Monogame team did excellent job and gave XNA another life.

Once you get past initial problems like how to setup environment or how to make the Content Pipeline working you are already making games and Monogame tries to help without getting in your way – just as i expected it.

Forums on the Monogame Codeplex site are very helpful and if you post your questions there you are almost sure to get some answer.

Forget Class Inheritance!

Another interesting thing i discovered on this bumpy road is the Entity Component System pattern.

After struggling some time with class inheritance for the game, i realized that there has to be better way so i started researching and found out that many people are writing games using Entity Component Systems.

I wrote small Entity Component System framework for my game and it worked much better then deep class inheritance approach so i definitely recommend it to any aspiring game dev out there.

If you want to see how real world Entity Component System for game development looks like check out for example Artemis its quite stable framework.

To the future… And beyond!

So now that i wrote a game, i can proceed to my next task – learn how to play drums!

Ok seriously, whats next?

Probably i will soon write some Monogame tutorials on this blog to help beginners that are struggling with typical problems that every game has to solve.

Especially on how to setup Content Pipeline and how to easily do Resolution Independence – the holy grail of Game Programming :)

So what else can i say then – stay tuned and in the meantime check out my game and send some criticism or at least few bug reports ;)