Monday, April 25, 2011

Simple Entity Engine

What

EntityEngine is a nice pattern for externalizing the different components (logic) of an entity (object). And particularly effective in games, where features of an object is shared among many different types. This way the behavior of the object is put into separate components. The idea is that an entity is pretty much just an ID, and the components are referenced via. the entity ID.
$engine = new EntityEngine();
$entity = new SimpleEntity($engine);
$entity->setComponent(new DialogComponent());
$entity->getComponent('Dialog')->talk();
Alternative:
$engine->getComponent($entity, 'Dialog')->talk();

Why

Entity engines works very well as an alternative (and improvement) to deep inheritance trees. Inheritance can fall short when, for example you want a Rock to be able to speak (wouldn't want a Rock to inherit from Human, right?).
Another advantage is that the engine, keep the components in an array based on their type. This means that we can fetch all components of a given type, without knowing (or caring) which entities own them.
$engine = new EntityEngine();
$entity = new SimpleEntity($engine);
$entity->setComponent(new CollisionComponent());
foreach($engine->getAll('Collision') as $comp) {
    $comp->update();
}
Note: The only reason these examples are in PHP is for prototyping.

EntityEngine Interfaces and Implementation

class EntityEngine
{
    private $components = array();
    
    /**
     * @param Entity $entity
     * @param string $componentName
     * @return Component
     */
    public function getComponent(Entity $entity, $componentName)
    {
        if($this->hasComponent($entity, $componentName)) {
            return $this->components[$componentName][$entity->getId()];
        }
        
        return null;
    }
    
    /**
     * @param Entity $entity
     * @param string $componentName
     * @return boolean
     */
    public function hasComponent(Entity $entity, $componentName)
    {
        return isset($this->components[$componentName][$entity->getId()]);
    }
    
    /**
     * @param Entity $entity
     * @param Component $component 
     */
    public function setComponent(Entity $entity, Component $component)
    {
        $this->components[$component->getName()][$entity->getId()] = $component;
    }
    
    /**
     * @param string $componentName
     * @return array of Component
     */
    public function getAll($componentName)
    {
        if(! isset($this->components[$componentName])) {
            return array();
        }
        
        return $this->components[$componentName];
    }
}

interface Entity
{
    /**
     * @return unique identifier for this instance
     */
    public function getId();
    
    /**
     * @param string $component
     * @return Component
     */
    public function getComponent($componentName);
    
    /**
     * @param Component $component
     */
    public function setComponent(Component $component);
}

abstract class SimpleEntity implements Entity
{
    private $engine;
    
    /**
     * @param EntityEngine $engine 
     */
    public function __construct(EntityEngine $engine)
    {
        $this->engine = $engine;
    }
    
    public function getId()
    {
        return spl_object_hash($this);
    }
    
    public function getComponent($componentName)
    {
        return $this->engine->getComponent($this, $componentName);
    }
    
    public function setComponent(Component $component)
    {
        $this->engine->setComponent($this, $component);
    }
}

interface Component
{
    public function getName();
}

Component Implementations of the Examples

class DialogComponent implements Component
{
    public function getName() 
    {
        return "Dialog";
    }
    
    public function moveRight();
}

class CollisionComponent implements Component
{
    public function getName() 
    {
        return "Collision";
    }

    public function update();
}

Tuesday, April 19, 2011

Ogre3d in Netbeans 7

Recently me and a friend of mine started talking about creating a game using C++. After a little looking around, we decided on the OGRE game engine as the framework of choice and me being a fan of Netbeans, we choose that as IDE. Here comes a little guide to setting up an OGRE 1.7.2 project in Netbeans 7 RC using MinGW on Windows 7.

Netbeans
Install Netbeans IDE 7 RC remember to select the all inclusive or c++ versions.

MinGW
Install MinGW using the mingw-get-inst installer. For this guide we install it at the default location (C:\MinGW).

During installation you should select the C++ component, as well as the two MSYS components.

After installation you need to add C:\MinGW\bin to your system Path.

Now you should be able to load up Netbeans:
  1. Select Tools -> Options -> C/C++ Tab.
  2. Press "Add..."
  3. Now select your base directory C:\MinGW\bin (same as Path), the rest should be auto-detected.
Create a new project, choose Samples -> C/C++ -> Welcome and try to build (you should succeed).

OGRE
Install OGRE 1.7.2 SDK for MinGW the self extractor will place it self where ever you download it, but copy the extracted folder to your root (C:\OgreSDK).

Here i basically followed this Ogre guide.

Only thing i changed was:
  • Project Properties -> Build -> Linker -> Output path to "C:/OgreSDK/bin/Debug/ogregame1". Switch out ogregame1 with your name of choice.
  • Project Properties -> Run -> Console Type: External Terminal.

NOTE: OgreMain_d.dll and OIS_d.dll is in the bin/Debug directory.
NOTE2: Executar is Run in English.

Now everything builds and runs. You can test it your self, with the main.cpp file from MadMarx tutorial One.

Thursday, March 17, 2011

Automatic Testing with PHP

Want to commit Friday night? Tired of the same bug appearing again, when already fixed it once? Constantly writing small test.php scripts to test behaviour?

Why not organize the whole thing, so you only have to press a button to ensure everything works as intended, or better yet, do it automatically whenever you commit something to your repository?

PHPUnit allows for all that and more, it can be intimidating at first, but if keep it simple, it’s not very hard and not very time consuming.

You need to install PHPUnit on your local computer and configure it with your IDE of choice (move along if your using notepad).

Configuration

Add a folder to your checkout/clone called “tests” containing the following:

library/
tests/
  My/
    Tests/
      Here.php
  bootstrap.php
  phpunit.xml

library in this case, is the directory containing the code you want to test, but pretty much any structure will work.

The bootstrap file contains the minimum to get your code (and your tests) running, usually something like an include path and autoloader:

$rootPath = realpath(dirname(dirname(__FILE__)));
$libraryPath = $rootPath . '/library';
$testsPath = $rootPath . '/tests';

$paths = array(
    $libraryPath,
    $testsPath,
    get_include_path()
);

set_include_path(implode(PATH_SEPARATOR, $paths));

spl_autoload_register(function($class) {
    return spl_autoload(str_replace('\\', '/', $class));
});

phpunit.xml is the configuration file, which PHPUnit will look for by default. This configures how your unit tests should be run, and among other things defines the name of your bootstrap file:

<?xml version="1.0"?>
<phpunit bootstrap="./bootstrap.php">
    <testsuite name="My Test Suite">
        <directory>./</directory>
    </testsuite>
    <groups>
        <exclude>
            <group>disable</group>
        </exclude>
    </groups>
    <filter>
        <whitelist>
            <directory suffix=".php">../library</directory>
        </whitelist>
    </filter>
</phpunit>

Now your ready...

Wait, how do you test your code? Well that's easy! In the My/ directory we add a file, I like to keep the exact same structure as in my library for unit-tests. But basically all the rules of normal code applies to your tests as well. E.g. refactor large classes into smaller ones, use inheritance where it makes sense etc.

Here is an example called tests/My/SimpleXMLTest.php (not our class, but we will borrow it for now). And while we are at it, we might as well just parse our PHPUnit configuration file (because it's already there!).

namespace My;

class SimpleXMLTest extends \PHPUnit_Framework_TestCase
{
    public function testMagicGet_BasicStringExample_ReturnsDirectoryValue()
    {
        $path = dirname(dirname(__FILE__)) . '/phpunit.xml';
        $xml = simplexml_load_file($path);
        $actual = (string)$xml->testsuite->directory;
        $this->assertEquals('./', $actual);
    }
}

There is a couple of things to note here:

  • I name the function according to some advice I found on the web: testMethod_Scenario_Assertions().
  • There are many assertX() methods, but they function pretty much the same. An expected value and the actual return value.
  • You should always try to expect a static value (first argument).
  • You should absolutely minimize the logic of your test (no if's, switches or loop!) helper functions are great though.
  • I keep my tests in the same namespace as my actual code (but not the same directory). Your IDE should ignore test classes for auto-completion.

Running the Tests

Will depend on what IDE you are using. In Netbeans Shift+F6 will run the selected test. Ctrl+F6 will run the test matching the selected implementation class.

Alternatively you can run the test suite manually:

$ phpunit <path-to-tests>

Sunday, March 13, 2011

Use that Namespaced Class

I've been spending a fair amount of time with php namespaces. So far experience has shown me that, it is much simpler to "use" classes explicitly, instead of namespaces.

A quick example:
use Namespace;
$obj = new Namespace\Class();
vs.
use Namespace\Class;
$obj = new Class();

Note that often you will use many more classes than one. Which would make "using" the namespace a one liner, and explicit use 5+ lines. However this has it's own advantages.

The Good:
  • You can see at a glance, in the top of a file, which dependencies it has.
  • You shorten class names even more, with no need for the namespace prefix.

The Bad:
  • The potential for name-clashes, but that is what aliasing is for, right?

It may seem like obvious advice, but I still did it the former way until I "got it".

Friday, March 11, 2011

Setting up Jenkins with Github

I just spend a lot more time cloning from github in Jenkins CI than was necessary.

After installing Jenkins, I started with Sebastian Bergmann's excellent php template for Jenkins was pretty straightforward and very well documented.

Cloning from Github

My first problem was with cloning my GitHub repository. I spend some time setting up ssh keys for authentication with Github. Now the easiest way would have been, to simply clone via the read-only url, as you therefore do not have to configure ssh.

Pick the right branch

After successfully cloning from Github, I kept getting some odd content. It turned out that it came from the gh-pages branch (wiki), that Github creates for you. Jenkins by default clones all the branches, one after another (look for ** in the configuration). Simply specifying the Branch Specifier as "master" fixed the problem.

Running the test suite

Lastly i had some trouble running the test suite. Console contained PHPUnit --help output, which basically means it doesn't know where the tests are. This is because, the template searches in the workspace root, instead of the tests folder. The solution was to add an argument, with the tests configuration file.

<target name="phpunit">
  <exec executable="phpunit" failonerror="true">
    <arg line="--configuration ${source}/tests/phpunit.xml ${source}/tests"/>
  </exec>
</target>

Missing coverage output

When the tests were running, Jenkins had trouble finding some xml files (build/logs/clover.xml and the build/coverage directory was empty). The php template for Jenkins recommends some logging options in phpunit.xml to generate these. However the logging methods that require Xdebug do not get executed without the extension. PHPUnit does not notify about this, but installing Xdebug fixed the problem.

Now everything is running smoothly, hurray!