Game development tutorial: Swift and SpriteKit - Part 2 Using Sprites (and by default SKNodes)

13. June 2014

 

As you can imagine by the name “SpriteKit”, Sprites are a pretty core part of creating a game using SpriteKit.  We are going to continue building on the minimal application we created in the previous part.  I want to point out, this isn’t the recommended way of working with SpriteKit, it is instead the simplest way.  In a proper application we would be more data driven and store our data in SKS files instead of simply adding them to the project.  This is something we will cover later on.  First lets jump right in with code.

 

We are going to replace the the class GameScene we created in the last tutorial.  In SpriteKit, the fundamentals of your game are organized into SKScene objects.  For now we only have one.  Let’s look:

 

import SpriteKit

 

class GameScene: SKScene {

        let sprite = SKSpriteNode(imageNamed: "sprite1.png")

    

    override func didMoveToView(view: SKView) {

        sprite.anchorPoint = CGPoint(x:0.5,y:0.5)

        sprite.xScale = 4

        sprite.yScale = 4

        self.addChild(sprite)

    }

    

    override func mouseDown(theEvent: NSEvent!) {

        self.sprite.position = CGPoint(x:theEvent.locationInWindow.x,y:theEvent.locationInWindow.y)

    }

}

 

We add the sprite “sprite1.png” to our project directory, simply drag and drop it from Finder.  The sprite(s) ill be using are from the zip file available here.  When you run this code, click anywhere and you should see:

 

Sd1

 

Where ever you click the mouse, the sprite will be drawn.

One immediate change you will notice in this code is sprite was moved out of didMoveToView and made a member variable.  This allows us to access sprite in different functions ( although we could retrieve the sprite from the Scene, something we will see later ). In Swift there are only two main ways of declaring a variable, let and var.  var is a variable meaning it’s value can change.  Using let on the other hand you are declaring a the the value cannot change, this is the same as a const in other languages.  As we touched on briefly in the last part, a let declared value can be assigned later using the ? postfix operator.  In this case, it will have the value of nil at initialization, unless one is specifically given like in the code we just did.  One thing you may notice is, unlike C++, C# and Java, Swift currently has no access modifiers.  In other words all variables are publicly available ( there are no private, internal, protected, etc modifiers available ).  Apparently this is only temporary and will be changed in the language later.  This personally seems like a very odd thing not to have in a language from day one.

Since we set the sprite’s anchor to the middle (0.5,0.5), the sprite will be centred to your mouse cursor.  As you can see we added a mouseDown event handler.  This class is available because SKScene inherits UIResponder, this is how you handle I/O events in your scene.  The only other new aspect to this code is:

        sprite.xScale = 4

        sprite.yScale = 4

 

 

This code causes the sprite to be scaled by a factor of 4x.  We do this simply because our source sprite was only 64x64 pixels, making it really really tiny in an empty scene!  As you can see, scaling sprites in SpriteKit is extremely easy.

 

The structure of a SpriteKit game is actually quite simple.  Your SKScene contains a graph of SKNodes, of which SKSpriteNode is one.  There are others too including SKVideoNode, SKLabelNode, SKShapeNode, SKEmitterNode and SKEffectNode.  Even SKScene itself is a SKNode, which is how all the magic happens.  Let’s take a quick look at an SKLabelNode in action.

 

import SpriteKit

 

class GameScene: SKScene {

    

    override func didMoveToView(view: SKView) {

        var label = SKLabelNode();

        label.text = "Hello World"

        label.fontSize = 128

        label.position = CGPoint(x:0,y:0)

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        self.addChild(label)

    }

    

}

Which predictably enough gives you:

Sd2

 

These nodes however can be parented to make hierarchies of nodes.  Take for example a combination of the two we’ve seen, our sprite node with a text label parented to it.

import SpriteKit

 

class GameScene: SKScene {

    

    override func didMoveToView(view: SKView) {

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        

        var sprite = SKSpriteNode(imageNamed:"sprite1.png")

        sprite.position = CGPoint(x:100,y:0);

        sprite.xScale = 4.0

        sprite.yScale = 4.0

        

        var label = SKLabelNode();

        label.text = "Jet Sprite"

        label.fontSize = 12

        label.position = CGPoint(x:0,y: 15)

        label.fontColor = NSColor.redColor()

        label.alpha = 0.5

 

        

        sprite.addChild(label)

        

        self.addChild(sprite)

    }

    

}

 

And when you run it:

Sd3

 

There are a few things to notice here.  Each Node get’s its default coordinates from it’s parents.  Since the jet sprite is parented to the scene and the scene’s anchor is set to the middle of the screen, when we position the screen 100 pixels to the right, that’s 100 pixels to the right of the centre of the screen.  Additionally, the text label is positioned relative to the sprite, so it’s positioning is relative to the sprite.  Another thing you might notice is the text is blurry as hell.  That is because the label is inheriting the scaling from it’s parent, the sprite.  As you can see you compose your scene by creating a hierarchy of various types of nodes.  Now if we were to transform the parent sprite, all the transformations will apply to the child nodes.

 

The following example shows how transforming a parent node effects all child nodes.  Spoilers, it also shows you how to Update a Scene… we will cover this in more detail later, so don’t pay too much attention to the man behind the curtain.

import SpriteKit

 

class GameScene: SKScene {

    

    var sprite = SKSpriteNode(imageNamed:"sprite1.png")

    override func didMoveToView(view: SKView) {

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        

        sprite.position = CGPoint(x:0,y:0);

        sprite.xScale = 8.0

        sprite.yScale = 8.0

        

        var label = SKLabelNode();

        label.text = "Jet Sprite"

        label.fontSize = 12

        label.position = CGPoint(x:0,y: 15)

        label.fontColor = NSColor.redColor()

        label.alpha = 0.5

 

        

        sprite.addChild(label)

        

        self.addChild(sprite)

    }

    

    override func update(currentTime: NSTimeInterval) {

        if(sprite.yScale > 0) {

            sprite.yScale -= 0.1

            sprite.xScale -= 0.1

        }

        else {

            sprite.xScale = 8.0

            sprite.yScale = 8.0

        }

    }

    

}

 

Now if we run this code:

 

 

Each time update() is called, the sprite is reduced in scaling until it disappears, at which point it’s zoomed back to 8x scaling.  As you can see, the child labelNode is scaled as well automatically.

 

Notice how until this point if we wanted to access our sprite across functions we had to make it a member variable?  As I said earlier, there is another option here, you name your nodes and retrieve them later using that name.  Like so:

 

import SpriteKit

 

class GameScene: SKScene {

    

 

    override func didMoveToView(view: SKView) {

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        var sprite = SKSpriteNode(imageNamed:"sprite1.png")

        

        sprite.name = "MyJetSprite"

        sprite.position = CGPoint(x:0,y:0);

        sprite.xScale = 4.0

        sprite.yScale = 4.0

        

        self.addChild(sprite)

    }

    

    override func update(currentTime: NSTimeInterval) {

        var sprite = self.childNodeWithName("MyJetSprite");

        if(sprite != nil){

            if(sprite.yScale > 0) {

                sprite.yScale -= 0.1

                sprite.xScale -= 0.1

            }

            else {

                sprite.xScale = 8.0

                sprite.yScale = 8.0

            }

        }

    }

    

}

You can perform some pretty advanced searches, such as searching recursively through the tree by prefixing your name with “//“.  You can also search for patterns and receive multiple results.  We will look at this in more details later.

 

This part is starting to get a bit long so I am going to stop now.  The next part will look at more efficient ways of using Sprites, such as using an Atlas, as well as look at basic animation and whatever else I think to cover!

 

Continue to Part 3

,




CocoonJS 2.0.1 released

13. June 2014

CocoonJS just released a new version.  CocoonJS is a technology that allows you to bundle HTML applications into a native application for mobile app store deployment.  This release contains:

 

Canvas+

  • Canvas+ now handles correctly HTML5/Web exportations from Construct 2. Get more infohere.
  • Added implementation for the FontFace CSS style. Fonts can now be downloaded from a remote URL defined in the FontFace attribute. Get more info here.
  • Improvements in DOM support
    • Make the window.document readOnly.
    • Added window.pageXOffset and window.pageYOffset properties.
    • Added document.defaultView property.
  • XHR Improvements
    • Make "text/plain;charset=UTF-8" the default content-type.
    • Allow XHR responses to be saved to disk a new cocoonSetOutputFile extension. Get more info here.
  • Page pageLoaded / pageFailed are correctly called now.
  • Fixed Audio System deadlock when alcOpenDevice fails.
  • New (and correct) device orientation handling. Get more info here.

Rendering

  • Ensure the renderer is always resumed after loading a url.
  • Improved WebGL compatibility with renderTargets.
  • Fixed some problems in renderbufferStorage arguments, which caused an incomplete framebuffer status.

Extensions

App

  • Added new methods:
    • onSuspended: notification when the application is suspended.
    • existsPath: checking if a file exists in the filesystem.
    • setTextCacheSize: text rendering is cached inside CocoonJS. This method controls the size of that cache.

Ads

  • Fixed problem with iOS 6 and iAd interstitials

WebView+

  • Added check to avoid null pointer exceptions when destroying the webview
  • Implemented webView setNetworkAvailable method, which triggers 'online' event on the JavaScript side
  • Fixed viewport size problem which happened in some devices
  • Fixed some missing resources bugs

Cloud Compiler

  • Added support for Cordova 3.3 and 3.4.

Launcher

  • Some small improvements to the Android launcher UI.
  • Improve download/unzip times in Android launcher.
  • Make orientation handling behave the same as in the browser. Some existing games that depend on gyroscope/orientation might need some tweaking because of this.
  • Fixed crash if device orientation changes during game launch.

Known Bugs

  • Ads with admob and mopub aren't handled correctly, and may not appear. If more ad networks are configured in mopub, those will be served.  
  • Samsung Galaxy Tab devices crash due to SIGILL. We have already found the issue related to V8 and this specific hardware/processor and are working hard to try to solve it asap.

We are working on all of these bugs in order to solve them and create a new release asap. Sorry for the inconveniences.

Important: You can always revert the version of the launcher and the compiler you're using. Get more info here.

 

If you think Cocoon sounds a heck of a lot like PhoneGAP/Cordova, well, it is.  Cocoon have put together this comparison guide.  Basically the biggest difference is speed.




Swift with SpriteKit problems on Mac OS 10.9 and an easy fix.

10. June 2014

 

When I did the first ( and currently only ) part of my Swift with SpriteKit tutorial series I ran into a crash problem with the default game template.  In Googling around and looking at the Mac password protected developer forums, I notice I am by no means alone.  Even a comment in the earlier tutorial part mentioned encountering the problem and said it was tied to Mac OS 10.9.  I can confirm on my 10.10 install, everything works correctly, for me it is only in 10.9 that I have a problem.

 

It’s pretty simple to re-create, when running Mac OS 10.9, create a simple project using the game template and Swift as your language ( the Objective-C template works just fine ), like this one:

 

BOOM

 

Then when you run it:

BOOM2

 

EXC_BAD_ACCESS Code=1 address=0x10.  

 

Fortunately I have discovered a very simple fix.  In Xcode, open up the generated sks file, GameScene.sks:

Boom3

 

Make sure the Utilities panel is visible:

BOOM4

 

Now from the Object library, drag an Empty Node to the editor window, like so:

BOOM5

 

And now, if you run the game it should work:

BOOM6

 

My guess is the scene file included in the Swift Spritekit template is corrupted.  By adding a node and saving it, it seems to fix the corruption.  By the way, you can delete the empty node now and it will continue to work.

 

Hope that helps some of you, at least till Apple fix the bug.

 

 

 

 

 




Adventures in Phaser with TypeScript–Graphics Time!

9. June 2014

 

 

I’ve done a number of these walk through type tutorials using many different languages/libraries and there is one common traffic trend.  People LOVE reading about graphics.  In every single example the post I do about graphics always seems to draw the most traffic.  I guess we just love drawing stuff on screen.  Now for the good part, Phaser is good at it and makes it really all quite easy.

 

Loading and adding a sprite

 

Back in the previous post I actually jumped the gun a bit and showed preloading and rendering sprites.  Since so many people jump ahead straight to the graphics post, I’ll review the process.

 

/// <reference path="phaser.d.ts"/>
class SimpleGame {
    game: Phaser.Game;
    titleScreenImage: Phaser.Sprite;

    constructor() {
        this.game = new Phaser.Game(800, 600, Phaser.AUTO, 'content', { create: this.create, preload: this.preload });
    }
    preload() {
        this.game.load.image("title", "TitleScreen.png");
    }
    create() {
        this.titleScreenImage = this.game.add.sprite(0, 0, "title");
    }
}

window.onload = () => {
    var game = new SimpleGame();
};

 

The key concepts to be aware of here is preloading assets using game.load methods, where you pass in the filename as well as a unique string key that you will use to access the asset.  Then in create you can see this in action, where we add a sprite to the game using game.add.sprite, using the key “title” to access it.  In this case our “sprite” was a full screen image.  Now let’s look at how you can work with a sprite, this time using a slightly smaller image.

Working with sprites

 

For this section I am going to work with this sprite ( created in this tutorial series ):

jet

 

Add it to your project’s root directory.  In my case I’ve called it jet.png.  Using the above code, simply replace “TitleScreen.png” with “jet.png” and “title” with “jet” and you should see:

 

image

 

 

As you can see, our sprite is drawn at the top left corner of the screen.  That is because the value (0,0) in Phaser refers to the top left corner of the screen by default.  Let’s instead center our sprite using the following code:

 

/// <reference path="phaser.d.ts"/>
class SimpleGame {
    game: Phaser.Game;
    jetSprite: Phaser.Sprite;

    constructor() {
        this.game = new Phaser.Game(800, 600, Phaser.AUTO, 'content', { create: this.create, preload: this.preload });
    }
    preload() {
        var loader = this.game.load.image("jet", "jet.png");
    }
    create() {
        var image = <Phaser.Image>this.game.cache.getImage("jet");
        
        this.jetSprite = this.game.add.sprite(
            this.game.width / 2 - image.width / 2,
            this.game.height / 2 - image.height / 2,
            "jet");
    }
}

window.onload = () => {
    var game = new SimpleGame();
};

 

Run this code and:

image

 

We are now nicely centered, both to the window and sprite.

We have one major challenge with centering the image.  Until the sprite is created, it doesn’t have a width or height.  However, when you create the sprite you can set it’s position.  Of course it would be possible to create then move the sprite but that is hackish and could have unintended graphical problems.  Instead we can get the image we loaded using this.game.cache.getImage() then access the images dimensions.  One line of code might stand out for you here:

 

var image = <Phaser.Image>this.game.cache.getImage("jet");

 

This is TypeScript’s way of typecasting.  If you’ve worked in Java, C# or C++ you’ve no doubt encountered typescasting.  If your experience was mostly in JavaScript ( a mostly typeless language ), this might be new to you.  Basically what you are saying is “we promise the value returned by getImage() is of the type <Phaser.Image>, so make image a Phaser.Image”.  If you try to access a value or method in image that doesn’t exist in Phaser.Image, TypeScript will give you an error.

 

Positioning items in Phaser

 

When using a sprite, by default, transformations happen relative to the top left corner of the sprite.  This is why we had to subtract half to the width and height of the sprite when positioning it in the center of the screen.  Otherwise the top left corner of the sprite would be centered to the screen like this:

image

 

Sometimes however you would rather transform the sprite relative to a different point, commonly the very middle or occasionally the bottom left corner.   Fortunately there is an option for this, the anchor.  The anchor tells Phaser where to draw your Sprite relative to.  Here we set the anchor to the center of the sprite then draw it at (0,0) like so:

 

    create() {
        var image = <Phaser.Image>this.game.cache.getImage("jet");
        
        this.jetSprite = this.game.add.sprite(
            this.game.width / 2 - image.width / 2,
            this.game.height / 2 - image.height / 2,
            "jet");

        this.jetSprite.anchor.set(0.5,0.0)
        this.jetSprite.position.x = this.jetSprite.position.y = 0.0;
    }

 

And the result:

image

As you can see, draw calls for the sprite now position relative to it’s center.  Positioning sprites relative to their center is incredibly handy when it comes to rotation, while anchoring at the bottom is useful for platformers where you are aligning the sprite’s feet to the ground.  What you chose is entirely up to you.  The values passed in to anchor might be a bit confusing, as they are normalized, meaning they go from 0 to 1.  The values are all relative to the sprite itself, while (0,0) is the top left corner of the sprite, while (1,1) is the bottom right corner.  (1,0) would be the bottom left, while (0,1) would be the top right.

 

There is one important thing to be aware of here.  Anchor works relative to the source image, not the sprite itself.  Therefore if you intend to scale your sprites, instead of using anchor, you are going to want to use pivot instead.  (Until recently pivot was broken, but it appears to work now).  Pivot sets the center point of the sprite, not the image that composes the sprite.  Setting the pivot looks like this:

        this.jetSprite.pivot.x = this.jetSprite.width / 2;
        this.jetSprite.pivot.y = this.jetSprite.height / 2;

 

Again, you don’t have to set the anchor at all, but it can be useful.  Unlike anchor, pivot uses relative pixel coordinates within the sprite itself.  Therefore the mid-point is at (width/2,height/2).  Once again, (0,0) is the top left corner.

 

Simple Graphics

 

Sometimes you just want to draw primitive graphics on screen… lines, circles, boxes, that kind of stuff.  Fortunately Phaser has that built in as well in the form of the Graphics object.

 

/// <reference path="phaser.d.ts"/>
class SimpleGame {
    game: Phaser.Game;
    jetSprite: Phaser.Sprite;

    constructor() {
        this.game = new Phaser.Game(800, 600, Phaser.AUTO, 'content', { create: this.create, preload: this.preload });
    }
    preload() {
        var loader = this.game.load.image("jet", "jet.png");
    }
    create() {
        // Add a graphics object to our game
        var graphics = this.game.add.graphics(0, 0);

        // Create an array to hold the points that make up our triangle
        var points: Phaser.Point[] = [];
        // Add 4 Point objects to it
        points.push(new Phaser.Point());
        points.push(new Phaser.Point());
        points.push(new Phaser.Point());

        // Position one top left, top right and botto mmiddle
        points[0].x = 0;
        points[0].y = 0;

        points[1].x = this.game.width;
        points[1].y = 0;

        points[2].x = this.game.width/2;
        points[2].y = this.game.height;

        // set fill color to red in HEX form.  The following is equal to 256 red, 0 green and 0 blue.  
        // Do at 50 % alpha, meaning half transparent
        graphics.beginFill(0xff0000, 0.5);
        
        // Finally draw the triangle, false indicates not to cull ( remove unseen values )
        graphics.drawTriangle(points, false);

        // Now change colour to green and 100% opacity/alpha
        graphics.beginFill(0x00ff00, 1.0);

        // Draw circle about screen's center, with 200 pixels radius
        graphics.drawCircle(this.game.width / 2, this.game.height / 2, 200);
        
    }
}

window.onload = () => {
    var game = new SimpleGame();
};

 

The code is pretty heavily commented so should be self explanatory.  When you run it you should see:

image

 

 

A look behind the scenes

 

Let’s take a quick look at how graphics drawing works in Phaser.  That involves going back to this line:

this.game = new Phaser.Game(800, 600, Phaser.AUTO, 'content', {});

Here you are passing in a lot of important information.  First (and second) are the resolution of your game.  Next is the type of Renderer that Phaser should use.  We mentioned this briefly in the prior tutorial.  You have the option of WEBGL or Canvas rendering ( or headless, which means no rendering at all and is used for server side programming ).  Which you chose depends heavily on the device you are supporting.  For example, currently no iOS devices support WebGL and only the most recent version of Internet Explorer work.  By selecting AUTO you let Phaser decide based on the device you are running on.  Finally ‘content’ is the HTML ID of the DIV to render our game in.

 

You may notice scattered throughout Phaser’s code/documentation are references to PIXI.  Pixi.js is a popular WebGL 2D renderer that is able to fallback on Canvas rendering when WebGL is unavailable.  Pixi is the renderer that Phaser uses, so you will occasionally see Pixi classes inside Phaser code.

 

There is one final thing to cover about graphics before moving on, full screen and handling multiple resolutions.

 

Going Full Screen

 

Now let’s take a look at an application that can go full screen:

 

/// <reference path="phaser.d.ts"/>
class SimpleGame {
    game: Phaser.Game;
    jetSprite: Phaser.Sprite;

    constructor() {
        this.game = new Phaser.Game(640, 480, Phaser.AUTO, 'content', { create: this.create, preload: this.preload });
    }
    preload() {
        var loader = this.game.load.image("jet", "jet.png");
    }

    // This function is called when a full screen request comes in
    onGoFullScreen() {
        // tell Phaser how you want it to handle scaling when you go full screen
        this.game.scale.fullScreenScaleMode = Phaser.ScaleManager.EXACT_FIT;
        // and this causes it to actually do it
        this.game.scale.refresh();
    }
    goFullScreen() {

    }
    create() {
        var image = <Phaser.Image>this.game.cache.getImage("jet");

        // Draw the jet image centered to the screen
        this.jetSprite = this.game.add.sprite(
            this.game.width / 2 - image.width / 2,
            this.game.height / 2 - image.height / 2,
            "jet");

        // Set background to white to make effect clearer
        this.game.stage.backgroundColor = 0xffffff;

        // Add a function that will get called when the game goes fullscreen
        this.game.scale.enterFullScreen.add(SimpleGame.prototype.onGoFullScreen, this);

        // Now add a function that will get called when user taps screen.
        // Function declared inline using arrow (=>) function expression
        // Simply calls startFullScreen().  True specifies you want anti aliasing.
        // Unfortunately you can only make full screen requests in desktop browsers in event handlers
        this.game.input.onTap.add(
            () => { this.game.scale.startFullScreen(true); },
            this);
    }

}

window.onload = () => {
    var game = new SimpleGame();
};

 

The comments cover most of what’s going on, but I thought I would touch on a couple things in the above example.  First you cant simply request to go fullScreen in Desktop browsers for security reasons.  This means your game can’t simply start in full screen, you need to make the call to startFullScreen() inside an event handler.  Most commonly this will be in the form of a “Click here for FullScreen” button or link.

 

Next is the ()=> syntax, known in TypeScript as an arrow function expression (if you’ve used C#, this syntax is going to look awfully familiar to you!) and is something that should be coming in the next JavaScript version (ECMAScript 6).  It is simply a more compact form of a function expression ( no need for the word function ) that is automatically scoped to “this”.  You could have created a function like onGoFullScreen like we did for enterFullScreen.  ( Coincidentally we could have also handled enterFullScreen using an arrow function.

 

The last thing to look at is the scale mode.  In this example we used Phaser.ScaleManager.EXACT_FIT, which scales the scene up to match your resolution.  There are two other options, SHOW_ALL and NO_SCALE.  Here is the result of running the code above using each setting:

 

Phaser.ScaleManager.EXACT_FIT

EXACT_FIT

 

Phaser.ScaleManager.NO_SCALE

NO_SCALE

 

Phaser.ScaleManager.SHOW_ALL 

SHOW_ALL

 

If you have an HDTV, you can think about them this way.  EXACT_FIT is the same as Stretch mode.  It scales the scene to use as much of the screen as possible, but can result in some distortion.  NO_SCALE does nothing, it simply shows the scene un-altered, centered to the screen.  SHOW_ALL is about the equivalent of Letterbox.  Basically it fits as well as it can while maintaining the aspect ration of your original scene. 

 

Don’t worry, that’s not it for graphics, we have all kinds of things coming up…  spritesheets, effects, particles, animation, etc…  That’s just it for the foundations.

 

Programming , , , ,




Autodesk enters the 3D Engine market with purchase of BitSquid

9. June 2014

 

I just received the following email from Autodesk:

 

SAN FRANCISCO, June 9, 2014 -- Autodesk, Inc. (Nasdaq: ADSK) has acquired Stockholm-based Bitsquid AB, the creator of the Bitsquid game engine. The acquisition brings to Autodesk expertise in 3D game development and proven technology that will enable Autodesk to supercharge its portfolio of tools for game makers through the development of a new 3D game engine. Multiple game developers have used the modern and flexible Bitsquid engine to create 3D games for next-generation consoles and PCs, and Autodesk will continue to work with many of these companies to develop the new 3D game engine. Terms of the acquisition were not disclosed.

"Bitsquid has been a key success factor for Fatshark, as we’ve been able to produce high quality games with short development times,” said Martin Wahlund, CEO, Fatshark. "We are excited to see how Bitsquid evolves now that it is part of Autodesk.”

In addition to acquiring the Bitsquid game engine, the acquisition of the Bitsquid team and technology will enable Autodesk to create new tools that push the limits of real-time 3D visualization for architects and designers, many of whom face challenges placing design data into real world contexts. The new technology will also be incorporated into solutions for customers outside of the games industry, including architecture, manufacturing, construction, and film. Autodesk plans to create new types of design exploration tools that allow visualization and contextualization of designs using the same fluid control and immediate feedback that exist today in modern console and PC games.

"Autodesk's acquisition of Bitsquid will revolutionize real-time exploration of complex data. Imagine being able to walk through and explore any type of design, from buildings to cars, with the same freedom you experience in the open world of a next-generation console game. Game engine technologies will be an increasingly critical part of the workflow, not only for creating games, but also for designing buildings or solving complex urban infrastructure challenges," said Chris Bradshaw, senior vice president, Autodesk Media & Entertainment. "The Bitsquid acquisition brings to Autodesk both the expertise and the technology that will enable us to deliver a groundbreaking new approach to 3D design animation tools, and we welcome the team and community to Autodesk."

Additional information on the new Autodesk 3D game engine, which will compliment Autodesk's industry leading games portfolio of middleware tools and 3D animation software including Autodesk Maya LT, Autodesk Maya and Autodesk 3ds Max, will be available later this year.

 

In that press release, it sounds like a relatively minor acquisition, they could simply be rolling the technology in to one of their existing products.  However, if you read this site, they obviously have bigger plans:

 

More than just games – This is going to be BIG

With the acquisition of Bitsquid, Autodesk is bringing expertise in 3D game development and proven game engine technology in house. We are significantly expanding our portfolio of game making tools, complementing our middleware and 3D animation tools: Autodesk® 3ds Max®, Autodesk® Maya®, and Autodesk® Maya LT™ software. Across Autodesk, this technology will fuel new product development in our Media & Entertainment business, and enable a new class of design animation tools.

Tools for Game Makers

Later this year, Autodesk will introduce a modern and flexible 3D game engine based on the Bitsquid engine. By introducing a game engine, Autodesk can offer game makers a more complete game creation workflow from concept to release.

A New Era in Design Animation

Many of our manufacturing, architecture, building, and construction customers are also excited about game engine technology– but not because they are making games. Instead, they are looking for new ways to visualize and interact with design data with the same level of control and feedback of modern console or PC games. With the acquisition of Bitsquid, Autodesk will begin exploring the creation of a new interactive design exploration platform, integrated with our design tools, which will help designers contextualize their ideas.

In Film and Television

Autodesk will also be looking at how Bitsquid technology may be applied to workflows such as pre-vizualization and interactive compositing.

 

Bolded portion mine.  So Autodesk is clearly entering the game engine space and building it around BitSquid.  Ever heard of it?  Yeah, me neither.  It is however the engine powering Magicka:Wizard Wars:

2.jpg (1920×1080)

 

Their site is fairly minimal, but describes the BitSquid engine as:

 

Fast

Bitsquid is a new high-end game engine, built from the ground up to focus on excellent multicore performance, cache friendly data layouts and advanced rendering techniques.

Dynamic

Bitsquid supports immediate reload of all resources, both scripts and content. You can also test run levels instantly, on PCs, consoles, phones and tablets.

Flexible

The engine is completely data driven, making it easy to create a highly scalable rendering pipe that shines on both the latest DX11 GPU and mobile devices, just by changing configuration files. And any game or simulation can be authored using just Lua and visual scripting. Of course you can use C as well, where you need the speed.

Lightweight

Written with a minimalistic modular design philosophy the entire engine is less than 200 KLOC and easy to modify.

 

The technical blog however makes for an interesting read.

 

Autodesk entering the game space isn’t really a huge shock.  They actually dipped their toe in the pond when they released Scaleform as an Indie game engine.  Considering their heavy role in the game development pipeline ( due mostly to Max and Maya ), this move does make sense.  The question is, will this alienate their existing partners?

 

EDIT: One thing I didn’t mention in the original post.  Autodesk also announced the lowering of the monthly cost of Maya LT from $50 a month to $30 a month.  Additionally they have made Mudbox available for $10 a month.  This seems like a much better price point to me.  You can now get Photoshop ($30), Maya LT ($30) and Unreal (19$), a complete game development package for less than $80 a month.  Compare that to prices a few years ago and it is simply mind blowing!

 

Additionally, Develop have published an interview with Autodesk’s Frank Delise discussing the acquisition. 

News