A look inside Unreal Engine 4: Part Two

8. April 2014

 

One of the vaunted features of Unreal Engine 4 is C++ support.  How exactly does that work?  First you need to have an external IDE installed, either Visual C++ on Windows or XCode on Mac.  The Express version will work but the helper toolbar is unavailable.  It’s mostly just a shortcut so it’s not a huge loss.  Integration is pretty solid.  In the Editor in the File menu there are a number of menu options:

 

C++ Coding

 

image

 

By selecting Add Code to Project… you can easily create a new game object using a wizard like sequence.  You select the base class:

 

image

 

Name it and you are done:

image

 

Once you click Create Class, you will be prompted to edit the code:

image

 

You will be brought to your IDE of choice.  From this point on, its just like working with any other Visual Studio or XCode C++ project.

image

 

The result of your project is a DLL file, build as per normal and your game will update in the editor.  It’s only when adding ( like we just did ) a new class do you need to restart the Unreal Engine Editor.  Otherwise a simple refresh should suffice.

 

The actual C++ libraries are fairly massive and far beyond the scope of this brief overview.

 

Building Unreal Engine from Source

 

One of the big advantages of Unreal is you have complete access to the source code.  The code is available in multiple parts, a couple of zip files with most of the external dependencies then the remaining code is available of Github.  You have to associate your Github account with your Unreal account, but the process is basically instant.

 

The GitHub repository is about what you would expect.

image

 

The actual source isn’t that big, about 120MB, while the supporting zips measure in at a couple GB, but they shouldn’t regularly change.  Unreal make a bleeding edge release available for the brave of heart.

 

The actual process is about as simple as it gets.  You do a git pull, download and extract the supporting files into the same directory, then run a script that generates the project or solution file.  Then, in the case of Windows, simply open the SLN file in Visual Studio:

 

As you can see, the solution contains full sources for every tool in the SDK:

image

 

This is nice, when they say with source code, it’s the ENTIRE source, nothing is hidden from you.  On the other hand, have some patience, the build process isn’t exactly fast.  On my machine it took about half an hour, I cant even imagine how long it would take on the MacBook Air, probably a couple of hours.  Then again, I remember the bad old days of all day builds, so this is really a first world problem.

 

Have a fair bit of drive space available too, as building from source is going to require a fair bit of space:

image

 

I’ve only scanned the code but from what I’ve seen it’s pretty clean and well commented.  For the majority of devs, you probably wont ever need to modify the code, but being able to run it in debug mode is certainly invaluable.

 

 

The Documentation

 

A project like this lives of dies on it’s documentation and I am please to say Unreal Engine is well documented.

 

First there are a series of video tutorials.  Even without a membership you can check them out.  As of right now there are 64 video tutorials available.

The documentation is broken down like so:

image

 

Under the Samples & Tutorials some are currently just placeholders.

image

 

The Programming Guide is pretty comprehensive.

image

 

Reference documentation is again detailed:

image

 

They also provide the AnswerHub, a StackOverflow like portal for asking and answering questions.    As you can see from the screenshot below, answers come very quickly and devs are very active in solving problems.  If you run into a problem, you are very well supported:

image

 

In addition to AnswerHub, there is also a full Wiki:

image

Currently it is a bit sparse, but expect it to grow over time.

 

Finally there are the forums.  One of the nice things about having to pay to be a member is it gets the signal to noise ratio way down.  This means the only people on the forums are people that are using or evaluating Unreal Engine.

image

 

The forums are also very active and developers actively participate.

 

Summary

 

This of course only scratches the surface of the functionality available.  There shader support, skeletal systems, etc… all nicely integrated in the editor.  What I will say is I am actually shocked at the level of polish of not only the Engine and supporting tools, but also the community they have fostered and the level of support they are providing.

 

When I first downloaded UDK I was actually somewhat underwhelmed with what was included.  Level level of polish present in UE4 shows they are taking this release very seriously.  Don’t get me wrong, UE is NOT a beginner friendly product, this is some seriously powerful but also sophisticated tech you are being given here.  That said, Unreal have done an amazing job making it as accessible and well supported as I could have imagined.

 

Is it worth 19$ a month?  Most certainly, if only just for the learning experience it represents.

Programming , ,




LINQ for C++ with cpplinq

4. April 2014

 

When it comes to programming languages, I literally use dozens, but when it comes down to an all other things being equal decision my go to language of choice tends to be C#.  One of the big plus sides of C# is the wonderful LINQ ( Language Integrated Query ).  LINQ makes heavy use of lambda (closures) a feature lacking until recently in C++.  Now with lambda expressions part of the C++ language LINQ for C++ is now a possibility.  It exists as a single hpp file you add to your project.

 

If you aren’t already familiar with LINQ, here is a simple example in C#.  It’s a simple scoreboard that sorts the results by name, then by score, then totals and averages all of the scores.  As you can see, it’s a very compact and clean way to access data.

 

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

namespace ConsoleApplication1
{
    class Entry
    {
        public Entry(string name, int score)
        {
            this.name = name; 
            this.score = score;
        }

        public string name { get; set; }
        public int score { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Entry> scoreEntries = new List<Entry>();
            scoreEntries.Add(new Entry("mike", 42));
            scoreEntries.Add(new Entry("bob", 99));
            scoreEntries.Add(new Entry("doug", 99));
            scoreEntries.Add(new Entry("steve", 12));

            var sortedByName = scoreEntries.OrderBy(item => item.name).ToList();
            Console.WriteLine("Sorted by score");
            sortedByName.ForEach(item => { Console.WriteLine(item.name + " " + item.score); });

            Console.WriteLine("\nSorted by name");
            var sortedByScore = scoreEntries.OrderBy(item => item.score).ToList();
            sortedByScore.ForEach(item => { Console.WriteLine(item.name + " " + item.score); });

            var totalOfScores = scoreEntries.Where(item => item.score > 0)
                .Sum(item => item.score);

            var averageScore = scoreEntries.Average(item => item.score);
            Console.WriteLine("\nTotal of scores == " + totalOfScores + " Average Score == " + averageScore);

            
        }
    }
}

 

Now let's take a look at the C++ version using cpplinq:

#include <string>
#include <list>
#include "cpplinq.hpp"
#include <iostream>


class Entry{
    public:
        Entry::Entry(std::string name, int score){
            this->name = name;
            this->score = score;
        }

        std::string name;
        int score;
};


int main(int argc, char **argv)
{
    std::list<Entry> scoreEntries;
    scoreEntries.push_back(Entry("mike", 42));
    scoreEntries.push_back(Entry("bob", 99));
    scoreEntries.push_back(Entry("doug", 99));
    scoreEntries.push_back(Entry("steve", 12));

    using namespace cpplinq;
    
    auto sortedByName = from(scoreEntries)
        >> orderby_ascending([](const Entry & entry){ return entry.name;  })
        >> to_vector();
        
    auto sortedByScore = from(scoreEntries)
        >> orderby_descending([](const Entry & entry){ return entry.score;  })
        >> to_vector();

    std::cout << "Sorted by name" << std::endl;
    from(sortedByName)
        >> for_each([](const Entry & entry){ std::cout << entry.name << " " << entry.score << std::endl; });

    std::cout << std::endl << "Sorted by score" << std::endl;
    from(sortedByScore)
        >> for_each([](const Entry & entry){ std::cout << entry.name << " " << entry.score << std::endl; });

    auto totalOfScores = from(scoreEntries)
        >> select([](const Entry & entry){ return entry.score; })
        >> sum();

    auto averageScore = from(scoreEntries)
        >> select([](const Entry & entry){ return entry.score; })
        >> avg();

    std::cout << std::endl << "Total of scores == " << totalOfScores << " average score == " << averageScore << std::endl;
    return 0;
}

 

A few obvious differences.  Cpplinq statements start with the from methods defining the type of data source to perform on.  In this case I used the default from() which takes a standard C++ STL type.  There are also from__array() and from_range() for working with arrays and iterators respectively.  Next the . (dot) operator has been replaced with the >> operator.  Of course the lambda syntax is different as well ( C++’s is much uglier ), otherwise at the end of the day, it is very similar to LINQ in both look and execution.

 

If you are new to C++ and are struggling to wrap your head around the uses for lambdas, give cpplinq a shot and you will quickly see their value!

Programming




Troubleshooting IntelliJ/LibGDX/RoboVM/Gradle issues on Mac OS

3. April 2014

The move to Gradle has been for the most part a positive experience for me, except when it comes to IntelliJ on Mac OS.  There I ran into a few problems and figured I would share the troubleshooting I took.  Fortunately there was a happy ending for me.

 

The main problem I had was this:

NewImage

 

Before we continue much further, you will need to have a few things installed on your machine.

  • Java 7 JDK
  • Recent ( post April 2014 ) LibGDX nightly
  • IntelliJ 13.1 or higher

If you don’t, please install and configure them now.  Also make sure to set your JAVA_HOME variable after you install the JDK.

 

This error occurred when importing the gradle project into IntelliJ as described in this post.  Generally the most common cause of this error is a lack of Java 7, which RoboVM requires.  It’s important to note, this is the version of Java that IntelliJ needs to run using.  You can check the Java version of IntelliJ via the menu IntelliJ IDEA->About IntelliJ IDEA.  Like so:

IntelliJ About Dialog

 

As you can see, I am running JVM 1.7.0.51, but there is a very good chance that you aren’t even if you have it installed.  JetBrains currently have this to say on the subject:

At the moment all our products require Apple JDK 1.6 to be installed in order to run on Mac. JDK 1.7 from Oracle is not officially supported yet and has known problems that stop us from using it by default. Oracle JDK 1.7.0_40 has added support for Retina and works much better than previous versions on Mac. You are welcome to give it a try in case you have any problems with Apple JDK.

To force running under JDK 1.7 edit /Applications/<Product>.app/Contents/Info.plist file, change JVMVersion from 1.6* to 1.7*

 

So, your first step is to enable Java 1.7 ( Java 7 == Java 1.7, Java 6 == Java 1.6 BTW ). If you are unsure how to access the plist file, in Finder open Applications, locate IntelliJ, right click and select Show Package Contents. If you have Xcode install, you can simply double click the pList file. Edit it like so:

PListEditing

 

Now restart IntelliJ and check the about dialog, you should now be running Java 7.

 

Still not working?  Here are a few quick things to check.

Make sure your JDK is configured correctly.  In a terminal window type:

java -version

The results should look like:

NewImage

If you java version is showing as 1.6, but you’ve installed Java 1.7, chances are your JAVA_HOME variable isn’t set correctly.

 

Next check what gradle sees, change into your project root directory and type:

gradlew -version

The results should look like:

NewImage

Once again, verify that gradle is using the proper JVM.  Once again, I believe this value is driven by JAVA_HOME, but I could be wrong.

 

Finally ( and this was the ultimate problem for me ).  Load IntelliJ and make sure there are no Java 1.6 SDKs defined.  Warning, this will break any old projects that require Java 6 as this is a global setting.

 

In IntelliJ with a Project loaded, right click the project and select Open Module Settings

NewImage

 

First verify that the project SDK is set to 1.7 and then select SDKs from the side bar.

NewImage

 

If a 1.6 SDK exists.  Select it the click the - button.

NewImage

 

Now try the import again and IntelliJ should work just fine.

 

If it still doesn’t work, try running gradle from the command line.  If you get errors there, it’s not an IntelliJ error.   Also, it’s beyond my ability to help you, as troubleshooting Gradle problems is beyond my abilities ( or more accurately desires ).

 

So if you ran into problems getting RoboVM to work with IntelliJ, hopefully this guide proved of some help.

 

 

 




LOVE 0.9.1 released

2. April 2014

Well, technically make that LÖVE, I don’t believe umlauts and URLs mix well.

NewImage

 

Anyways, LÖVE 0.9.1 was released today.  LÖVE is an easy to use Lua game library I featured in my Lua Game Engine Roundup a couple years back.  Details of this release are:

 

0.9.1's API is fully backward compatible with existing 0.9.0 games. Most of the changes are bug fixes, internal code improvements, and some API additions and updates to flesh out LÖVE's features, especially in the love.graphics module.


Here are some of the more interesting changes:


• Canvases can now be used with SpriteBatches, ParticleSystems, and Meshes. Canvases and Images are now both sub-types of the new Texture type, which those three things accept. SpriteBatch:setTexture (etc.) have been added, and SpriteBatch:setImage (etc.) is now deprecated, but not removed yet.


• Better support for retina displays in OS X has been added. To take advantage of it, you will need to enable the new "highdpi" window flag in either love.conf or love.window.setMode. When this is done on a compatible computer, the pixel resolution of the window will be double what the requested window size is. You will almost certainly need to adjust your code if you want to use this properly! The new function love.window.getPixelScale can help immensely.


• Canvases now have antialiasing support. You will need to request it when creating the Canvas, with the new function variant love.graphics.newCanvas(width, height, texturetype, fsaa).


• A new function Source:clone has been added. This lets you create multiple static Sources which play the same sound much more efficiently (in terms of loading time, memory usage, and code duplication.)


• Some nasty bugs have been fixed, including an off-by-one issue in Joystick:isDown, love.graphics.setCanvas breaking everything when love.graphics.setScissor is used sometimes, and 8-bit SoundData sounding completely wrong when loaded into a Source.

 

You can read the full release notes here

You can download love here.




HOLY CRAP! MOAI isn’t dead! In fact, they just released v1.5

27. March 2014

 

Wow, I gotta say this announcement pretty much broadsided me.  I wrote Moai off for dead, which was a huge shame, as I did a tutorial series on the subject, and frankly found MOAI to be some of the cleanest C++ code I had ever read.  So to hear of a new release certainly makes me happy.

image

So then, what’s new?

 

Feature merge from Zipline:

  • Massive rework of the garbage collection system to simplify object tracking
  • Reworking of the AKU Modules API
  • New SDL host to complement the GLUT host
  • A flag to MOAIAction to disable auto-stop on no children

A New Build System:

  • The CMake build system that was in place for the linux and blackberry hosts was extened to include all hosts
  • Luajit support was added to all platforms (via cmake scripts)
  • create-project-* scripts were created that allows you to generate vs2008->vs2013 and xcode project files.
  • Changes to a project can be recorded once in the relevant cmake script and all platforms should work instead of maintaining 6+ build configs
  • Plugin support was added for installing modules which are outside the moai sdk (other repos) [More]
  • Custom host support was added for compiling a host outside of the repo [More]
  • Support for compiling with Ming-w64 for a completely open source experience on Windows (no more vcruntime to distribute)

Additional Features:

  • Vector Pathfinding (MOAIVecPathGraph)
  • Box2D Closest Raycast Exposure
  • Twitter support in android
  • MOAIShader was enhanced with the 4x4 matrix and given access to UNIFORM_WORLD_VIEW
  • A faster and smoother android host with working keyboard support.
  • MOAISafariIOS is now MOAIBrowserIOS and MOAIBrowserAndroid added
  • Visibility can now be inherited!
  • Google Play Services
  • Updated Tapjoy and Vungle
  • MOAISim showCursor and hideCursor support
  • Documentation improvements
  • Chartboost for IOS and android
  • You can now EnqueueJoystickEvent from the host.
  • New HTML/JS host based on emscripten

Fixes:

  • Android logging support repaired
  • VFS works correctly on all platforms
  • A heap of lua stack overflows
  • Fixes to JSON parser and encoder
  • Textbox string bounds calculations fixed
  • PVR support working now

 

Certainly some nice new features in there, and hopefully this new release will breath renewed life into this project that frankly always deserved a better fate.

 

You can access the MOAI source code here.

You can read a more complete release notes here.

News, Programming ,