Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

28. October 2015

 

So I find myself needing to create a new website and this created a world of complications with one very easy solution, which I’m assuming you can guess from the title above…

 

I started GameFromScratch.com some 5ish years ago and the state of the web has changed a great deal since then.  I had a dedicated server from other projects, so the sky was the limit when it came to choosing a server technology.  I had little idea what GFS would evolve into or how much control I would require over my CMS, so as a programmer I went with the language/technology I was most comfortable with at the time, C#/Asp.net.  Instead of doing everything myself I built the site around BlogEngine.  It’s served me well enough, but in this age of mobile, SEO and responsive design, it’s a needlessly complicated mess.

 

I did a recent redesign of the site, but in the end I want to do a clean break.  Problem is, you can’t.  I have years of Google search engine juice, thousands of in-bound links and many other things that would break if I ported to a new site.  Beyond that, ugly or not, creaky or not, GameFromScratch is still my baby and I couldn’t just put her out to pasture.

 

After some thought on the subject I figured out how to go forward.  GameFromScratch is going to continue exactly as it is.  I will continue hosting 100% of my content here, I will add new blog posts and tutorial series here just like normal.  However, “finished” tutorial series will also be available on another home.  With the exception of perhaps pissing Google off due to duplicate content, I think it’s the best of both worlds.  People can continue to enjoy GameFromScratch.com as it is today, while people using it for straight reference material can enjoy a much cleaner and hopefully faster site.  Also it gives me the opportunity to introduce a slightly shorter and more accurate URL.  Win/win for everyone I hope.

 

This however lead me to the same challenge I had years ago… choosing a technology.  Now though I have come to realize less is more.  I have no desire to use a gigantic bloated CMS like Wordpress or Drupal.  More to the point I have absolutely no desire to install another server or database technology (and potential security loophole) on my servers.  I also had, have and always will continue to have a gigantic aversion to PHP, which winnows down the field a heck of a lot.  On the other hand, I also have little desire to manually craft a site from scratch.

 

Enter Jeykll.

jekyll-logo-light-solid

Jeykll is what you could call a “Static Site Generator”.  Basically its the framework to create a site within, couple with some tools that generate the site for you.  No database, no server technology, nothing.  The end result is simply a folder full of clean, modern HTML that can be deployed however you want.  This means no added security risks, no performance overhead and extremely simple backups.  It does however provide a framework of local tools that make your development process a heck of a lot faster than just writing HTML.

 

I am still very new to Jekyll, but so far it ticks all of the boxes I need.  The only real complication in the scenario is Ruby, the language it depends on.  As a language/ecosystem, Ruby seems horrifically fragile and it’s 10x worse on Windows where it is a bit of a red headed step child.  Point blank, getting and keeping your Ruby stack running is going to be by far the most challenging part of the process.

 

Anyways, if you find yourself needing to create a website, consider checking out Jekyll, I’ve created a small video about it available here or embedded below.

 

I looked at a few other options that you might wish to be aware of and why I personally didn’t go with them.

 

  • Adobe Muse
    • It was a nice editor and with it’s themes provided a great deal of what I needed.  The resulting code though wasn’t extremely clean, it has a rather hefty pricetag, and worse of all, once you commit to Muse you have to stick to Muse to generate new versions of your website.
  • Siteleaf
    • Siteleaf is very similar in basic process to Jekyll.  With a few major differences.  First, it includes web hosting options as well as an in cloud content editor.  Second, it’s got a price tag attached.  Third, it simply didn’t work on Windows… bit of a deal breaker there.  It’s not really Siteleaf’s fault, it’s Ruby, but still a rather large deal breaker for me.
  • Dozens of other static site generators
    • You certainly aren’t starved for choice in this category.  That said, if in doubt, go with the one with the biggest community.  That’s Jekyll.  I was tempted to find one that was built on top of Node instead of Ruby for a better Windows experience, but with Jekyll releasing version 3 with less dependencies and a smoother Windows experience, this became unimportant.
  • Wordpress/BlogEngine/Drupal et al
    • What can I say, they are still an option.  Jekyll certainly isnt for everyone.  Each of these CMSs is absolutely huge, some are downright dinosaurs at this point.  On the other hand… there is no scaffolding, no hosting requirements, a huge community of people you can contract work out to, etc.  If you are not moderately tech savvy, these are still most likely your best best.  Just be aware, you pay for that convenience when something goes wrong… it goes REALLY wrong.  Then again, you can also hire someone to fix it.

Totally Off Topic ,

26. October 2015

 

In the previous tutorial we look at the process of using sprites in SFML.  Today we are going to look instead at using a sprite sheet or texture atlas.  The process is very similar to working with a normal sprite, except that you have multiple sprites on a single texture.  Loading and swapping textures in memory is an expensive operation, so holding multiple sprites together can greatly improve the speed of your game.

 

As always there is an HD video version of this tutorial available here.

 

Many game engines have implicit support for spritesheets and sprite animation, however SFML does not.  There are however libraries built on top of SFML that provide this functionality or you can roll the required functionality yourself with relative ease.  Before we can continue we need a sprite sheet, which is simply one or more images with multiple frames of animation.  This is the one I am using:

dragonFrames

 

This isn’t the full sized image however.  The source file is actually 900x1200 pixels in size.  It should be noted that this size isn’t actually ideal.  Power of two texture dimensions should be preferred ( such as 512x256, 1024x1024, 2048x2048, etc. ).  In earlier version of OpenGL including OpenGL ES 1.x, a power of two texture was actually required.  These days, it is no longer a requirement, but a PoT texture generally will perform better.  As to file dimensions, you can fairly safely go up to 2048x2048 and support even rudimentary GPU’s like the Intel HD3000 series, but sizes of 4096x4096 are generally possible on most modern desktop and mobile GPUs.   You can notice from this image that it contains 12 textures, each 300x400 pixels in size.

 

Now we need code to extract a single frame from the texture and as you will see, it’s actually remarkably easy:

// Demonstrate creating a spritesheet
#include "SFML/Graphics.hpp"

int main(int argc, char ** argv){
  sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Demo Game");

  sf::Event event;
  sf::Texture texture;
  texture.loadFromFile("images/dragonFrames.png");

  sf::Sprite sprite(texture,sf::IntRect(0,0,300,400));


  while (renderWindow.isOpen()){
    while (renderWindow.pollEvent(event)){
      if (event.type == sf::Event::EventType::Closed)
        renderWindow.close();
    }

    renderWindow.clear();
    renderWindow.draw(sprite);
    renderWindow.display();
  }
}

 

This will draw just a small rectangular portion of our source texture, representing the first frame, like so:

image

 

Really that’s all that there is to it.  To add animation, we simply change the rectangular source after the fact, like so:

// Demonstrate creating a spritesheet
#include "SFML/Graphics.hpp"

int main(int argc, char ** argv){
  sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Demo Game");

  sf::Event event;
  sf::Texture texture;
  texture.loadFromFile("images/dragonFrames.png");

  sf::IntRect rectSourceSprite(300, 0, 300, 400);
  sf::Sprite sprite(texture,rectSourceSprite);
  sf::Clock clock;

  while (renderWindow.isOpen()){
    while (renderWindow.pollEvent(event)){
      if (event.type == sf::Event::EventType::Closed)
        renderWindow.close();
    }

    if (clock.getElapsedTime().asSeconds() > 1.0f){
      if (rectSourceSprite.left == 600)
        rectSourceSprite.left = 0;
      else
        rectSourceSprite.left += 300;

      sprite.setTextureRect(rectSourceSprite);
      clock.restart();
    }

    
    renderWindow.clear();
    renderWindow.draw(sprite);
    renderWindow.display();
  }
}

 

And when run:

GIF

 

You may notice right away that animation doesn’t look right and that’s a keen eye you’ve got there.  In this example we are simply going across the top three frames of animation from left to right.  The proper animation should actually be 0,1,2,1,0 not 0,1,2,0,1,2.  That said, in a proper game you would either roll your own animation class or use an existing one.  When we get to the process of creating a complete game, we will cover this process in detail.

 

In the above example we change frames of animation by changing the sprites source texture rect with a call to setTextureRect().  As I mentioned in the previous tutorial you could actually generate a new sprite per frame if preferred, as the sf::Sprite class is very light weight.

 

The Video

Programming , , ,

25. October 2015

 

In this Closer Look At we are going to be taking a closer look at the Otter2D game engine.  The Closer Look At series is a combination of an introduction, overview and getting started tutorial that is designed to help you quickly decide if a game engine/framework/library is right for you.  Otter2D is an open sourceotterlogo C# based open source game engine built over top of the SFML framework.  Otter2D provides essentially all of the functionality of SFML as well as higher level game engine features like animations, collisions, sessions and components.

 

As always there is an HD video version of this guide available here.

 

Doing what I do for a living I generally am surprised by a game engine or tool.  If I haven’t used it personally I have at least heard of it.  Otter on the other hand took me completely by surprise and for the most part it’s been a fun (and quick!) journey.  There isn’t a ton to Otter2D, it’s a code only framework built over a framework I am already familiar with.  If you have prior SFML experience, Otter2D will come quickly to you.  Due to the composition of Otter2D, this closer look is going to lean much more toward the code/tutorial side.  Let’s jump in.

 

Getting Started

 

Otter2D is available as a zip file (direct download link) or you can build from current source on Bitbucket.  The code is distributed under this license, excerpted below:

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

In case you are wondering, there are no conditions after the colon.  So basically it’s a license that lets you do pretty much whatever you want so long as you keep the license intact.

Getting set up is easy but could be better.  Unfortunately Otter2D is not configured to be used as an external library which is a bit of an odd choice.  Instead you add the Otter2D project to your solution and link to it as a dependency in your project, like so:

image

Full instructions on getting started Visual Studio are available here.

 

Your First Application

 

Now that you’ve got Otter downloaded and configured, let’s create our first application.

using Otter;

namespace OtterScratchPad
{
    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new Entity();
            entity1.AddGraphic(Image.CreateCircle(90,Color.Red));
            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

 

When you run this example you get:

image

 

Otter2D code is very similar to a traditional Entity Component System (ECS) in it’s approach.  Game is the heart of your application, while scene represents your game world.  The scene itself is composed of entities, which in turn contain defined components like Graphic we used above, or actual components, which we will see later.  A more common approach to the above solution is to derive your game objects from Entity instead, like so:

 

using Otter;

namespace OtterScratchPad
{
    class Player : Entity
    {
        public Player(float x, float y) : base(x, y)
        {
            this.AddGraphic(Image.CreateCircle(120, Color.Red));
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new Player(0,0);
            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

 

Those two examples are functionally equivalent.  As you can see in the second example when we pass coordinates to our Player Entity the origin by default is the top left corner, both of the screen as well as the sprite.  We will look at changing this shortly.  Congratulations however, you just created your first successful Otter2D application.  Easy eh?  Let’s move on and add some sophistication.

 

Input and Image Loading

 

In our next example, instead of creating a graphic procedurally, we are instead going to load a sprite.  For the source images, I am using the freely available sprites announced here.  Specifically I am using this sprite of a B17 bomber. 

 1

Obviously you can use whatever image you wish, so long as the file format is supported.  Keep in mind, Otter2D is built over SFML so it has the same graphics support as SFML which means your sprite can be in bmp, hdr, gif, jpg, png, pic, psd, tga formats.  Additionally in this example we are going to look at handling keyboard input to move our image left and right in response to key presses.  Alright, on to the code:

using Otter;

namespace OtterScratchPad
{
    class PlayerImage : Entity
    {
        public PlayerImage(float x, float y) : base(x, y)
        {
            this.AddGraphic(new Image("1.png"));
        }
        public override void Update()
        {
            if (Input.KeyDown(Key.Right))
            {
                this.X++;
            }
            if (Input.KeyDown(Key.Left))
            {
                this.X--;
            }

            base.Update();
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new PlayerImage(0,0);
            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

 

And when you run it:

example1

 

Note when you launch an Otter2D application, it doesn’t have focus and thus wont receive keyboard events.  This seems to be a bug in the underlying SFML libraries.  I spent a few minutes trying to fix it and sadly couldn’t.  Shouldn’t be a big deal as a production game wont use a console window to construct the main window, so this shouldn’t occur.  As you can see from this example, loading sprites and polling input are both trivial exercises, so let’s move on to animations.

 

Sprite Animations

 

In this example I’ve taken the three different frames of the B17 bomber and created a single 3x1 768x256 using ImageMagick.  The end result was:

ss

 

Not very exciting an animation, but each frame the propeller has turned slightly.  Let’s look at the process in Otter2D of using an animated sprite from a single sheet.  In this example we also show how to move the sprites origin or pivot point to it’s middle.

using Otter;

namespace OtterScratchPad
{
    class PlayerSpriteMap : Entity
    {
        enum Animations { Idle };
        Spritemap<Animations> spriteMap = new Spritemap<Animations>("ss.png", 256, 256);

        public PlayerSpriteMap(float x, float y) : base(x, y)
        {
            this.AddGraphic(spriteMap);
            spriteMap.CenterOrigin();
            spriteMap.Add(Animations.Idle, new int[] { 0, 1, 2 }, new float[] { 9.0f, 4.0f, 10.0f });
            spriteMap.Play(Animations.Idle);
        }
        public override void Update()
        {

            if (Input.KeyDown(Key.Right))
            {
                this.X += 300f * this.Game.RealDeltaTime / 1000;
            }
            if (Input.KeyDown(Key.Left))
            {
                this.X -= 300f * this.Game.RealDeltaTime / 1000;
            }

            base.Update();
        }

    }


    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new PlayerSpriteMap(game.HalfWidth,game.HalfHeight);
            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

 

Run it and:

 

example2

 

You may have to squint to see it, but that is certainly an animated sprite.  Instead of using Image we instead use a SpriteMap which takes the individual sprite dimensions as well as the spritesheet file name in it’s constructor.  The entity is then centered with a call to CenterOrigin().  Animations is simply a user defined enum that is used as the key within the sprite map.  When the map is added we pass in an array of ints or strings representing the frames offset within the source image as well as the duration for each frame of animation.

 

Collisions

 

Next we will modify the earlier example so we now have two airplane sprites that can collide with each other.  In addition to adding two sprites to the world, the example has also been changed so you can create both a player and non-player sprite, so only one responds to keyboard input.  Additionally instead of simply moving via X++, we change it so we move at a fixed frame rate depending on the elapsed time since the last frame.

using Otter;

namespace OtterScratchPad
{
    class PlayerSpriteMapWithCollisions : Entity
    {
        enum Animations { Idle };
        Spritemap<Animations> spriteMap = new Spritemap<Animations>("ss.png", 256, 256);

        enum ColliderTypes { Planes };
        bool isPlayer;
        public PlayerSpriteMapWithCollisions(float x, float y, bool player) : base(x, y)
        {
            isPlayer = player;
            this.AddGraphic(spriteMap);
            spriteMap.CenterOrigin();
            spriteMap.Add(Animations.Idle, new int[] { 0, 1, 2 }, new float[] { 9.0f, 4.0f, 10.0f });
            spriteMap.Play(Animations.Idle);

            this.AddCollider(new BoxCollider(256, 256, ColliderTypes.Planes));
            this.Collider.CenterOrigin();
        }

        public override void Update()
        {
            if (isPlayer)
            {
                if (Input.KeyDown(Key.Right))
                {
                    this.X += 100f * this.Game.RealDeltaTime / 1000;
                }
                if (Input.KeyDown(Key.Left))
                {
                    this.X -= 100f * this.Game.RealDeltaTime / 1000;
                }

                // Check for collisions
                if (this.Collider.Overlap(X, Y, ColliderTypes.Planes))
                    this.X = 0f;
            }
            base.Update();
        }

    }


    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new PlayerSpriteMapWithCollisions(0,game.HalfHeight,true);
            Entity entity2 = new PlayerSpriteMapWithCollisions(game.Width - 128, game.HalfHeight, false);

            scene.Add(entity1);
            scene.Add(entity2);

            game.Start(scene);
        }
    }
}

 

And run it:

example3

 

You may notice the collision isn’t amazingly accurate.  This is because in this example we used a box collider but there is some dead pixel space between our wing and the end of the image.  If you require increased accuracy you could instead us a pixel collider, but it will have a profound effect on performance.

 

Sound and Music

 

Next lets look at adding audio support to our game.  Let’s start by adding some sound effects to our player:

    class PlayerImageWithSound : Entity
    {
        // 30 cal burst:: http://www.freesound.org/people/Hamp999/sounds/151620/
        Sound sound1 = new Sound("sound1.wav");

        // Bomb drop http://www.freesound.org/people/sunch/sounds/274090/
        Sound sound2 = new Sound("sound2.wav");

        public PlayerImageWithSound(float x, float y) : base(x, y)
        {
            this.AddGraphic(new Image("1.png"));

            //Center within and without
            this.Graphic.CenterOrigin();
        }
        public override void Update()
        {
            if (Input.KeyDown(Key.Num1))
            {
                sound1.Play();
            }
            if (Input.KeyDown(Key.Num2))
            {
                sound2.Play();
            }

            base.Update();
        }
    }

 

When you hit the 1 key a certain sound effect plays, hit the 2 key a different sound effect plays.  There are two important things to note with audio in Otter2D.  Once again, it depends on SFML for the audio code so Otter supports the file formats that SFML supports ( which are too many to list ).  Additionally playing a sound halts earlier versions of that sound, so if you want multiple concurrent plays of the same sound, you need to create multiple instances.

 

Now let’s take a look at a music example.  Instead of extending another Entity, we will be creating our own Scene this time.

using Otter;

namespace OtterScratchPad
{
    class PlayerImageWithSound : Entity
    {
        // 30 cal burst:: http://www.freesound.org/people/Hamp999/sounds/151620/
        Sound sound1 = new Sound("sound1.wav");

        // Bomb drop http://www.freesound.org/people/sunch/sounds/274090/
        Sound sound2 = new Sound("sound2.wav");

        public PlayerImageWithSound(float x, float y) : base(x, y)
        {
            this.AddGraphic(new Image("1.png"));

            //Center within and without
            this.Graphic.CenterOrigin();
        }
        public override void Update()
        {
            if (Input.KeyDown(Key.Num1))
            {
                sound1.Play();
            }
            if (Input.KeyDown(Key.Num2))
            {
                sound2.Play();
            }

            base.Update();
        }
    }

    class SceneWithMusic : Scene
    {
        // Sound file is http://www.freesound.org/people/Diboz/sounds/216071/
        // Play, not looping
        public Music song = new Music("music.ogg", false);

        public SceneWithMusic() : base()
        {
            song.Play();
        }

        public override void Update()
        {
            base.Update();

            if (Input.MouseButtonPressed(MouseButton.Left))
                Music.GlobalVolume -= 0.1f;
            if (Input.MouseButtonPressed(MouseButton.Right))
                Music.GlobalVolume += 0.1f;

            if (Input.KeyPressed(Key.Space))
            {
                // Fast forward 10 seconds on spacebar if 10 seconds remain in play time
                if ((song.Offset + 10000) < song.Duration)
                    song.Offset += 10000;
            }
            if (!song.IsPlaying)
            {
                System.Console.WriteLine("Music stopped");
                Game.Close();
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new SceneWithMusic();

            Entity entity1 = new PlayerImageWithSound(0,game.HalfHeight);


            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

In this example there is now music playing when you start your game and you can fast forward the song by pressing the space bar.  Additionally global (all sound effects and music ) volume can be increased and decreased using the left and right mouse button, also illustrating how easy it is to poll the mouse for input as well. 

 

Components

 

I mentioned earlier that Otter2D has component support?  Well we saw a bit of it in action with the addition of Graphic objects to our Entity.  In this case though we are going to drop in slightly more advanced components, as well as create one of our own.

    class CustomComponent : Component
    {
        public override void Update()
        {
            base.Update();
            float alpha = Entity.GetGraphic<Image>().Alpha;
            alpha -= 0.005f;
            if (alpha <= 0.0f)
                alpha = 1.0f;
            Entity.GetGraphic<Image>().Alpha = alpha;
        }
    }
    // A Player Entity with components attached
    class PlayerWithComponents : Entity
    {
        public PlayerWithComponents(float x, float y) : base(x, y)
        {
            this.AddGraphic(new Image("1.png"));

            Axis axis = Axis.CreateWASD();
            BasicMovement movement = new BasicMovement(100, 100, 20);
            movement.Axis = axis;
            AddComponents(
                axis,
                movement,
                new CustomComponent()
                );
            this.Graphic.CenterOrigin();
        }
    }

 

And when you run it:

example4

 

Here we’ve used a set of built in keys, one for applying movement to your entity.  The parameters passed in limit x and y velocity as well as the rate of acceleration.  Then we create another component that maps the WASD keys to an axis, which can be used to drive our movement component.  Finally we create a custom component that changes our alpha over time.

 

Documentation and Community

 

Otter2D’s documentation consists of a collection of examples here and a generated reference manual available here.  It’s not a huge body of work however Otter2D is extremely simple to use so doesn’t really need much more.  Additionally it is built on top of SFML, so that underlying documentation and community are also available.  That said, it is built on the C# bindings of SFML and that community is much smaller than the main SFML community.

 

In terms of community there is a small forum available here.  It’s not extremely active but it is a place to get your questions answered.  There are a handful of tutorials on the web but not a huge amount by any definition of the word.

 

Conclusion

 

Otter2D is a pretty solid 2D game engine built over top of a well established framework.  It was extremely easy to learn and use, the design is clean enough you can intuit most of the process.   On major flaw I never discussed was the support for the Ogmo level editor, which IMHO was a very bad choice.  First off, it simply doesn't work, loaded levels are mangled.  Worse though, Ogmo itself was a frustrating mess to work with… every single change to the map (adding a layer, changing size, tile format, etc. ), completely destroyed everything you had done up to that point.  Adding support for a better editor such as Tiled would be relatively short work, but this was by far the most frustrating part of working with Otter2D.

 

Otherwise it is exactly what it is.  A clean, easy to use, fairly full featured 2D C# game engine.  As it is built over SFML and in C# deploying to platforms such as Android or iOS is most likely going to be painful ( no documentation exists ) and will most certainly require a Xamarin license.  For a 2D desktop title or as a learning game engine however, Otter2D would be a very solid choice.  As odd as it sounds, Otter2D was simply fun to work with, somewhat like Love2D, especially after dealing with much more complex engines or even SFML itself.

 

The Video

Programming , ,

23. October 2015

 

In a past life in which I sat in a cubicle and someone actually gave me a pay check every week I was a huge fan of Xamarin products.  They do very a good job of enabling .NET developers to leverage their skill across many platforms.  In fact, they are the technology that Unity is built on top off.  That said, I became increasingly less of a fan when the checks stopped and expenses came out of my own pocket!

 

There are many people out there that view making money from software as somehow evil.  I am certainly not one of those people.  In that corporate environment, where developers are paid salaries, rent is paid for office space, taxes are paid, etc…  the price of a software tool like Xamarin is trivial to justify.  In the world of indie game development though, this is often simply not the case.

 

Thing is, Xamarin has become a necessary evil for so many C# based game engines ( MonoGame, WaveEngine, Duality, Paradox, etc ) if you want to port to iOS or Android.  Many of these developers will never see a dime from their efforts, while a select few will become massively rich and a certain middle ground will eek out a living doing what they love.  It’s the later two groups that keep companies like Unity and Unreal afloat, and those two groups don’t come into being without the former group.

 

The challenge with Xamarin has always been their license structure has always been pretty awful for amateur developers.  How many people have chosenn not to work in C# simply because their is a price tag attached?  After years of awaiting a newer friendlier license structure (or Microsoft buyout), hope is on the horizon.

 

Today, in response to Xamarin’s recent acquisition of RoboVM, I ended up in this Twitter conversation with Nat Friedman, CEO of Xamarin:

 

First, in regard to the acquisition of RoboVM and how long the free for LibGDX developers offer will be extended:

image

 

Then more on the indie friendly nature of Xamarin, or lack thereof:

image

(Portion excerpted, Twitter message threading is bizarre)

image

image

 

This is news I am certain many C# game developers and tool providers are going to be delighted to hear.  Hopefully something happens fairly soon, as I’ve been waiting about 6 years and counting at this point! ;)

Programming, News , ,

23. October 2015

 

If you are a LibGDX developer or even a Java developer hoping to target iOS some pretty big news just happened.  In a nutshell Xamarin acquired RoboVM (more details here).  If both of those names are meaningless to you, here’s a quick rundown.

 

Xamarin are ultimately the company formed around Mono, which is the open source cross platform version of Microsoft’s .NET framework.  That’s actually simplifying their history a fair bit.  Many years ago they were a company called Ximian, and their big push was trying to make Linux on the desktop happen and part of that process was the Mono project.  In between they were purchased by Novell, Novell blew up in spectacular fashion and from the ashes Xamarin was born.  Of perhaps most interest to game developers, Xamarin developed the technology that Unity is built on top of.  In fact, if you are working in a C# based game engine ( MonoGame, WaveEngine, Paradox, etc ) chances are it requires a Xamarin license to target iOS or Android.

 

RoboVM on the other hand are a much smaller developer that provide a very similar product, just targeting Java instead of .NET.  Basically RoboVM provide an iOS runtime for Java applications, enabling you to run Java apps pretty much unchanged on iOS.

 

So, why do we care?

 

Well first off, RoboVM is the technology that LibGDX depends on for iOS deployment, ironically chosen while moving away from Xamarin years ago.  In many ways, RoboVM owes it’s success and existence to the libGDX community.  In fact, the LibGDX founder Mario Zechner started working for RoboVM about a year ago.  Note, working for…  it isn’t his company, something far too many people seem to miss these days.

 

Fast forward to recent history…

  • RoboVM is now owned by Xamarin
  • the core of RoboVM, the Ahead of Time (AoT) VM is no longer open source
  • the pricing is much less indie friendly

 

So basically a core component that LibGDX depends on to support iOS just became closed, more expensive and owned by a company that doesn’t really seem to get game developers.  This all in a world where people don’t expect to ever pay for anything… although that’s certainly a conversation for a different day.

 

To Mario/RoboVM’s credit, they have offered a free license option for LibGDX developers.  You need to apply for the license, have a development team limit of 3 developers and need to activate the license on your build machines with a machine count limit attached to the license.  Of course it also adds the pain of dealing with a license were there previously was none.  The one silver lining in all of this is you get debugging support including in this license, something that was previously a paid feature.

 

At the end of the day, what exactly does this mean for LibGDX developers?  Well you are now basically in the same boat as C# developers.  To support certain targets you now have a pay wall in front of you.  Of course the current license offer will mitigate that for many existing LibGDX developers but how that actually turns out is yet to be seen.  With that license offer in place, LibGDX devs are still in a better place than most MonoGame/Paradox/et al developers out there, to say nothing of the fact there is no added cost to support Android.  They are however certainly in a worse place then they were before.

 

I’m not going to lie and say this development is great news, it certainly isn’t.  It however isn’t the end of the world scenario many are making it out to be.  If enough community demand exists, they can pick up the code for RoboVM and run with it.  Or port to another Java on iOS solution such as Codename One or Avian.  Or explore a different approach entirely like Unity are moving toward.  Of course they could also take the path of least resistance and keep working with RoboVM.

 

There are however two meta-points I want to mention here.

 

First off, no matter how much this affects you personally, some of the reactions I have seen to this have been downright off putting.  The amount of heat Mario has taken over something that is basically beyond his control is just sickening.  It really makes one wonder why people would even contribute to an open source project in the first place.   Now caustic end users in an open source is nothing new, but it’s always disgusting to witness.  Now Mario is a big boy and is handling fine so far as I can tell, but really ask yourself… if you had to put up with this crap, would you bother donating your time anymore?

 

Second, Xamarin, if anyone from that company happens to be reading this, I hope the entire experience is an eye opener.  When the entire indie game development industry looks at you at best as a necessary evil, at worst as the devil, it’s time for some introspection.  Part of that relates to the above paragraph… people are horrifically over entitled these days and the thought of having to pay for anything is galling.  Ignore this crowd, there isn’t much you can or should do.

 

On the other hand, with a more reasonable licensing, you would have a much larger community of advocates and I have to assume greater profits.  Your legacy as a tool vendor to corporations really shows in your pricing model.   Heck, look at LibGDX for example… they were using RoboVM in the first place to avoid you!  If you followed the Unity or Unreal model of geared to income licensing then suddenly your products would become much more appealing to a much larger segment of the population.  Your license fees are a bitter pill to swallow for a hobbyist looking to release a free title, while someone who was commercially successful would probably be willing to pay a greater amount.

 

At the end of the day this isn’t a story that is going to play out in a single day.  There is an active discussion and more information on the LibGDX forums that I think is the ideal place to discuss things.  Just keep the personal insults out of it.

 

EDIT: One major concern people had with the license granted for LibGDX developers was how long it would be valid.  I just had the following conversation with Nat Friedman (CEO of Xamarin) on Twitter:

temp

 

Other very interesting things related to Xamarin licensing were discussed, which I will be putting in a separate post.  This announcement is very relevant to LibGDX developers however.

News ,

Month List

Popular Comments

Krita Launch 2016 Kickstarter Campaign To Improve Text And Vector Capabilities
Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


9. May 2016

 

Krita is a powerful open source 2D graphics package that’s targeted at digital painting instead of image manipulation.  They have just launched another Kickstarter campaign looking to raise funds to improve vector and text capabilities.  From the announcement:

Now is the time to join us and make it possible to create an awesome text tool, one that is really suitable to what you need text for in Krita: real typographic and artistic control, support for various languages, for translations, for scripts from all over the world. One integrated text tool that is easy to use, puts you in control and can be extended over the years with new features.

The second topic is vector graphics. It’s related to the text tool, since both are vector layer features. Currently, our vector graphics are defined in the OpenDocument Graphics format, which is fine for office applications, but not great for artwork. There’s already a start for supporting the SVG standard instead, and now’s the time to finish the job! And once we’re SVG to the core, we can start improving the usability of the vector tools themselves, which also suffer from having been designed to work in a word processor, spreadsheet or presentation application. Now that Krita is no longer part of a suite of office applications, we can really focus on making all the tools suitable for artists! Let’s make working with vector art great!

 

The pitch video for 2016 is available below

GameDev News

blog comments powered by Disqus

Month List

Popular Comments