<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Phil Peron &#187; PushButton Engine</title>
	<atom:link href="http://philperon.com/tag/pushbutton-engine/feed/" rel="self" type="application/rss+xml" />
	<link>http://philperon.com</link>
	<description>Flash Platform Developer and Game Development Hobbyist</description>
	<lastBuildDate>Wed, 23 Jun 2010 15:30:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>An Introduction to ElectroServer and PushButton Engine: Part Two</title>
		<link>http://philperon.com/2010/03/31/an-introduction-to-electroserver-and-pushbutton-engine-part-two/</link>
		<comments>http://philperon.com/2010/03/31/an-introduction-to-electroserver-and-pushbutton-engine-part-two/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 10:11:48 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[mmo]]></category>
		<category><![CDATA[ElectroServer]]></category>
		<category><![CDATA[gamedev]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=629</guid>
		<description><![CDATA[
In part one, the focus was on building the server logic for a multiplayer game. Now, we&#8217;ll get to work on a PushButton Engine client that will connect and communicate with ElectroServer. If you&#8217;re completely unaware of how PushButton Engine works, I&#8217;d urge you to spend some time checking out the documentation to get yourself [...]]]></description>
			<content:encoded><![CDATA[<p>
In <a href="http://philperon.com/2010/03/17/an-introduction-to-electroserver-and-pushbutton-engine-part-one/">part one</a>, the focus was on building the server logic for a multiplayer game. Now, we&#8217;ll get to work on a PushButton Engine client that will connect and communicate with ElectroServer. If you&#8217;re completely unaware of how PushButton Engine works, I&#8217;d urge you to spend some time checking out the <a href="http://pushbuttonengine.com/docs/">documentation </a>to get yourself up to speed.
</p>
<p>
Let&#8217;s get started!
</p>
<p><span id="more-629"></span></p>
<h2>The Client</h2>
<p>
The client we&#8217;re going to build is a fairly primitive one. It will connect to ElectroServer, spawn a knight player avatar and display anyone else that is connected as a black wizard. As players move around the area, their position will be broadcast across all connected clients and updated appropriately.
</p>
<p>
PushButton Engine lets the developer declare which objects they&#8217;d to use via an XML file (typically referred to as a &#8216;level file&#8217;). For the application developers among you, it will feel a lot like some of the Inversion of Control solutions that are available today. We&#8217;ll create one file that will declare common entities that are relevant across various game states and another that represents the primary game mode.
</p>
<h3>Defining the Game</h3>
<p><strong>File: /ESPBEDemo-client/assets/levels/common.xml</strong></p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;

&lt;!-- Define all the entities that will be used across game modes. --&gt;

&lt;things version=&quot;1&quot;&gt;

    &lt;!-- We need a spatial manager entity component to keep track of entities
    that have a spatial component and thus require a position be set. Like our
    soon-to-be-created avatars. --&gt;
    &lt;entity name=&quot;spatialManager&quot;&gt;
        &lt;component type=&quot;com.pblabs.rendering2D.BasicSpatialManager2D&quot; name=&quot;manager&quot; /&gt;
    &lt;/entity&gt;

    &lt;!-- Create a display object scene that will do the rendering for us. --&gt;
    &lt;entity name=&quot;scene&quot;&gt;
        &lt;component type=&quot;com.pblabs.rendering2D.DisplayObjectScene&quot; name=&quot;scene&quot;&gt;
            &lt;!-- Assign it a name --&gt;
            &lt;sceneViewName&gt;sceneView&lt;/sceneViewName&gt;
            &lt;!-- and set the scene position. --&gt;
            &lt;position&gt;
                &lt;x&gt;-400&lt;/x&gt;
                &lt;y&gt;-300&lt;/y&gt;
            &lt;/position&gt;
        &lt;/component&gt;
    &lt;/entity&gt;

    &lt;!-- Now add these two entities to a group so they can be instantiated conveniently. --&gt;
    &lt;group name=&quot;common&quot;&gt;
        &lt;objectReference name=&quot;spatialManager&quot; /&gt;
        &lt;objectReference name=&quot;scene&quot; /&gt;
      &lt;/group&gt;

&lt;/things&gt;
</pre>
<p>
We now have a spatial manager to handle the positioning of objects on the screen and a scene to render them to. Now let&#8217;s define the object we&#8217;ll need when our main game mode (or level) is loaded.
</p>
<p><strong>File: /ESPBEDemo-client/assets/levels/game.xml</strong></p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;

&lt;!-- Define all the objects that need to be available when this level is loaded --&gt;
&lt;things version=&quot;1&quot;&gt;

    &lt;!-- Create the player avatar. --&gt;
    &lt;template name=&quot;player&quot;&gt;
        &lt;!-- Create a sprite renderer to render the player avatar --&gt;
        &lt;component type=&quot;com.pblabs.rendering2D.SpriteRenderer&quot; name=&quot;sprite&quot;&gt;
            &lt;!-- Tell the sprite on what scene it should be rendered.
            (The 'scene' entity we created in common.xml.) --&gt;
            &lt;scene entityName=&quot;scene&quot; componentName=&quot;scene&quot;/&gt;
            &lt;!-- Define the location of the image file. --&gt;
            &lt;fileName&gt;../assets/images/player.png&lt;/fileName&gt;
            &lt;!-- Assign the layer index. --&gt;
            &lt;layerIndex&gt;1&lt;/layerIndex&gt;
            &lt;!-- Define where this sprite should be rendered. --&gt;
            &lt;positionProperty&gt;@spatial.position&lt;/positionProperty&gt;
        &lt;/component&gt;
        &lt;!-- This component allows the entity to be positioned on the screen. --&gt;
        &lt;component type=&quot;com.pblabs.rendering2D.SimpleSpatialComponent&quot; name=&quot;spatial&quot;&gt;
            &lt;!-- Make sure it knows where the spatial manager is (from common.xml). --&gt;
            &lt;spatialManager entityName=&quot;spatialManager&quot; /&gt;
            &lt;!-- And how large it should be. --&gt;
            &lt;size&gt;
                &lt;x&gt;48&lt;/x&gt;
                &lt;y&gt;48&lt;/y&gt;
            &lt;/size&gt;
        &lt;/component&gt;
        &lt;!-- Add a keyboard input component to accept user input. --&gt;
        &lt;component type=&quot;com.philperon.espbedemo.components.KeyboardInput&quot; name=&quot;keyboardInput&quot;&gt;
            &lt;!-- Assign W, A, S and D for player movement. --&gt;
            &lt;inputMap childType=&quot;com.pblabs.engine.core.InputKey&quot;&gt;
                &lt;up&gt;W&lt;/up&gt;
                &lt;down&gt;S&lt;/down&gt;
                &lt;left&gt;A&lt;/left&gt;
                &lt;right&gt;D&lt;/right&gt;
            &lt;/inputMap&gt;
        &lt;/component&gt;
        &lt;!-- Add a controller component to deal with how user input should be handled. --&gt;
        &lt;component type=&quot;com.philperon.espbedemo.components.PlayerController&quot; name=&quot;controller&quot;&gt;
            &lt;keyboardInput componentName=&quot;keyboardInput&quot; /&gt;
            &lt;spatial componentName=&quot;spatial&quot; /&gt;
        &lt;/component&gt;
    &lt;/template&gt;

    &lt;!-- Create the opponent avatar. --&gt;
    &lt;template name=&quot;opponent&quot;&gt;
        &lt;!-- Similar setup to that shown above. --&gt;
        &lt;component type=&quot;com.pblabs.rendering2D.SpriteRenderer&quot; name=&quot;sprite&quot;&gt;
            &lt;scene entityName=&quot;scene&quot; componentName=&quot;scene&quot;/&gt;
            &lt;fileName&gt;../assets/images/opponent.png&lt;/fileName&gt;
            &lt;layerIndex&gt;1&lt;/layerIndex&gt;
            &lt;positionProperty&gt;@mover.position&lt;/positionProperty&gt;
        &lt;/component&gt;
        &lt;!-- Add a component to handle interpolated movement based on position
        updates from the server. --&gt;
        &lt;component type=&quot;com.pblabs.rendering2D.Interpolated2DMoverComponent&quot; name=&quot;mover&quot;&gt;
            &lt;!-- How many degrees should be of the goal position before movement begins. --&gt;
            &lt;movementHeadingThreshold&gt;360&lt;/movementHeadingThreshold&gt;
            &lt;!-- Assign the spatial manager. --&gt;
            &lt;spatialManager entityName=&quot;spatialManager&quot; /&gt;
            &lt;!-- Tweak the movement speed slightly to give it a more natural look. --&gt;
            &lt;nudge&gt;1.2&lt;/nudge&gt;
            &lt;!-- Like the player avatar, define the size. --&gt;
            &lt;size&gt;
                &lt;x&gt;48&lt;/x&gt;
                &lt;y&gt;48&lt;/y&gt;
            &lt;/size&gt;
        &lt;/component&gt;
    &lt;/template&gt;

&lt;/things&gt;
</pre>
<p>
The game.xml file really starts to illustrate how powerful PushButton Engine can be once you wrap your head around a composition-style architecture. By writing small components that have a single primary duty, you can reuse them again and again in an unlimited number of entities. Game assembly then becomes a simple matter of defining the &#8220;recipe&#8221; that makes your game unique. It also opens up opportunities for game designers to have a hand in game development with only a limited knowledge of ActionScript.
</p>
<p>
Another group of items being referenced are the actual assets themselves. For this demonstration this includes the .xml level files and .png game graphics. We&#8217;ll place these in a group so they can be embedded and easily handled when the game initializes.
</p>
<p><strong>File: /ESPBEDemo-client/src/com/philperon/espbedemo/Resources.as</strong></p>
<pre class="brush: jscript;">
package com.philperon.espbedemo
{
    import com.pblabs.engine.PBE;
    import com.pblabs.engine.resource.ImageResource;
    import com.pblabs.engine.resource.ResourceBundle;
    import com.pblabs.engine.resource.XMLResource;

    import flash.display.Bitmap;
    import flash.utils.ByteArray;

    // Create a new resouce bundle to handle loading and registering
    // embedded resources.
    public class Resources extends ResourceBundle
    {
        // Add the level files we'll need.
        [Embed(source=&quot;../assets/levels/common.xml&quot;, mimeType=&quot;application/octet-stream&quot;)]
        public var Common:Class;

        [Embed(source=&quot;../assets/levels/game.xml&quot;, mimeType=&quot;application/octet-stream&quot;)]
        public var Game:Class;

        // And the graphics used to represent the game.
        [Embed(source=&quot;../assets/images/background.png&quot;)]
        public var BackgroundPNG:Class;

        [Embed(source=&quot;../assets/images/player.png&quot;)]
        public var PlayerPNG:Class;

        [Embed(source=&quot;../assets/images/opponent.png&quot;)]
        public var OpponentPNG:Class;

        public function Resources()
        {
            // When this class is instantiated, tell the resource manager to register the resources listed above.
            PBE.resourceManager.registerEmbeddedResource(&quot;../assets/levels/common.xml&quot;, XMLResource, new Common() as ByteArray);
            PBE.resourceManager.registerEmbeddedResource(&quot;../assets/levels/game.xml&quot;, XMLResource, new Game() as ByteArray);
            PBE.resourceManager.registerEmbeddedResource(&quot;../assets/images/background.png&quot;, ImageResource, new BackgroundPNG() as Bitmap);
            PBE.resourceManager.registerEmbeddedResource(&quot;../assets/images/player.png&quot;, ImageResource, new PlayerPNG() as Bitmap);
            PBE.resourceManager.registerEmbeddedResource(&quot;../assets/images/opponent.png&quot;, ImageResource, new OpponentPNG() as Bitmap);
        }
    }
}
</pre>
<p>
Now we have all the assets we&#8217;ll need to display our game. It&#8217;s time to start filling in some of the actual game logic that typically resides inside components. If you recall, we referenced a component to handle keyboard input and another to deal with how that input should be handled. Let&#8217;s start with our KeyboardInput component.
</p>
<p><strong>File: /ESPBEDemo-client/src/com/philperon/espbedemo/components/KeyboardInput.as</strong></p>
<pre class="brush: jscript;">
package com.philperon.espbedemo.components
{
    import com.pblabs.engine.core.InputMap;
    import com.pblabs.engine.entity.EntityComponent;

    // A component that handles keyboard input!
    public class KeyboardInput extends EntityComponent
    {
        // Define some variables to store keyboard input values.
        public var up:Number = 0.0;
        public var down:Number = 0.0;
        public var left:Number = 0.0;
        public var right:Number = 0.0;

        // getter and setter for the InputMap class that does the
        // real work here.
        public function get inputMap():InputMap
        {
            return _inputMap;
        }

        public function set inputMap(map:InputMap):void
        {
            // Store the input map in a private variable...
            _inputMap = map;

            // ...and map the actions we defined in game.xml to
            // the handlers.
            if (_inputMap != null)
            {
                _inputMap.mapActionToHandler(&quot;up&quot;, upHandler);
                _inputMap.mapActionToHandler(&quot;down&quot;, downHandler);
                _inputMap.mapActionToHandler(&quot;left&quot;, leftHandler);
                _inputMap.mapActionToHandler(&quot;right&quot;, rightHandler);
            }
        }

        // Finally, set up the handlers themselves.
        private function upHandler(value:Number):void
        {
            up = value;
        }

        private function downHandler(value:Number):void
        {
            down = value;
        }

        private function leftHandler(value:Number):void
        {
            left = value;
        }

        private function rightHandler(value:Number):void
        {
            right = value;
        }

        private var _inputMap:InputMap;
    }
}
</pre>
<p>
The game can now respond to keyboard input. We&#8217;re getting close to the core of our demo but need some way to ensure all these great resources make it on to the display list. For this purpose, we&#8217;ll use a subclass of BaseScreen that will be registered with a screen manager once we dive into the main game class.
</p>
<p><strong>File: /ESPBEDemo-client/src/com/philperon/espbedemo/GameScreen.as</strong></p>
<pre class="brush: jscript;">
package com.philperon.espbedemo
{
    import com.pblabs.engine.PBE;
    import com.pblabs.engine.debug.Logger;
    import com.pblabs.engine.resource.ImageResource;
    import com.pblabs.rendering2D.ui.SceneView;
    import com.pblabs.screens.BaseScreen;

    // Create a new screen class that will be registered with the
    // screen manager.
    public class GameScreen extends BaseScreen
    {
        // Declare a scene variable so we have something to actually
        // draw to.
        public var sceneView:SceneView;

        public function GameScreen()
        {
            super();

            // Create the scene view to match the same size as the .swf
            // and add to the display list.
            sceneView = new SceneView();
            sceneView.name = &quot;sceneView&quot;;
            sceneView.width = 800;
            sceneView.height = 600;
            addChild(sceneView);

            // Request that a background image be loaded on to the screen.
            // Pass in handlers to deal with a success or failure.
            PBE.resourceManager.load(&quot;../assets/images/background.png&quot;, ImageResource, imageLoadSuccessHandler, imageLoadFailedHandler);
        }

        // Once the image is loaded, send the bitmap data into a fill on
        // the Graphics instance of this display object.
        private function imageLoadSuccessHandler(imageResource:ImageResource):void
        {
            cacheAsBitmap = true;
            graphics.clear();
            graphics.beginBitmapFill(imageResource.image.bitmapData);
            graphics.drawRect(0, 0, imageResource.image.bitmapData.width, imageResource.image.bitmapData.height);
            graphics.endFill();
        }

        private function imageLoadFailedHandler(imageResource:ImageResource):void
        {
            Logger.print(this, &quot;Failed to load image '&quot; + imageResource.filename + &quot;'&quot;);
        }
    }
}
</pre>
<p>
We&#8217;re getting close. It&#8217;s time to wire up the PlayerController we added to the player entity in the game.xml file. This will contain all the logic needed to control the player&#8217;s avatar including sending the position updates to ElectroServer. Here we go&#8230;
</p>
<p><strong>File: /ESPBEDemo-client/src/com/philperon/espbedemo/components/PlayerController.as</strong></p>
<pre class="brush: jscript;">
package com.philperon.espbedemo.components
{
    import com.electrotank.electroserver4.ElectroServer;
    import com.electrotank.electroserver4.esobject.EsObject;
    import com.electrotank.electroserver4.message.request.PluginRequest;
    import com.pblabs.engine.PBE;
    import com.pblabs.engine.components.TickedComponent;
    import com.pblabs.rendering2D.SimpleSpatialComponent;

    import flash.geom.Point;

    // This represents the core logic for a player avatar.
    // It extends TickedComponent so we have access to game ticks.
    public class PlayerController extends TickedComponent
    {
        // Set how fast we'd like the player to move.
        public static const SPEED:uint = 100;

        // Declare a variable to hold the ElectroServer connection.
        public var connection:ElectroServer;
        // Make sure the player knows the current room and zone ids.
        public var currentRoomID:Number;
        public var currentZoneID:Number;
        // Create a handle to the KeyboardInput component we just created.
        public var keyboardInput:KeyboardInput;
        // As mentioned earlier, the spatial component manages position.
        public var spatial:SimpleSpatialComponent;
        // And of course, every player has a name.
        public var username:String;

        // The position buffer will ensure we're not sending updates if
        // the player hasn't moved.
        private var _positionBuffer:Point = new Point();

        public function PlayerController()
        {
            super();
        }

        // The onTick method that gets called every game tick.
        override public function onTick(deltaTime:Number):void
        {
            // Set the x and y velocity based on the keyboard input registered
            // from the KeyboardInput component.
            spatial.velocity.x = (keyboardInput.right - keyboardInput.left) * PlayerController.SPEED;
            spatial.velocity.y = (keyboardInput.down - keyboardInput.up) * PlayerController.SPEED;

            // Bounds check the player's movement. (Ideally, this would also be
            // enforced on the server but I'm trying to keep things as
            // simple as possible.)
            if(spatial.position.x &lt; 0 &amp;&amp; spatial.velocity.x &lt; 0 ||
                spatial.position.x &gt; 800 &amp;&amp; spatial.velocity.x &gt; 0)
                spatial.velocity.x = 0;

            if(spatial.position.y &lt; 0 &amp;&amp; spatial.velocity.y &lt; 0 ||
                spatial.position.y &gt; 600 &amp;&amp; spatial.velocity.y &gt; 0)
                spatial.velocity.y = 0;
        }

        // This fires when this component is added to an entity.
        override protected function onAdd():void
        {
            super.onAdd();
            // Schedule a position update task with the process manager.
            PBE.processManager.schedule(200, this, sendPosition);
        }

        // The function that's called when the task we just scheduled is due.
        public function sendPosition():void
        {
            // Check to make sure we've actually moved.
            if((spatial.x != _positionBuffer.x) || (spatial.y != _positionBuffer.y))
            {
                // If we have moved, create a new request to be sent back to the server
                var pr:PluginRequest = new PluginRequest();
                // Set the plugin name as well as the room and zone id
                // that we created in Part 1 of this tutorial.
                pr.setPluginName(&quot;GamePlugin&quot;);
                pr.setRoomId(currentRoomID);
                pr.setZoneId(currentZoneID);

                // Create an EsObject that will act as our message payload.
                var pos:EsObject = new EsObject();
                // Set the opcode (also found in Part 1)
                pos.setInteger(&quot;opcode&quot;, ESPBEDemo.STATE_UPDATE);
                // Make sure the server knows who it's coming from...
                pos.setString(&quot;name&quot;, username);
                // ...and what we're changing.
                pos.setNumber(&quot;x&quot;, spatial.x);
                pos.setNumber(&quot;y&quot;, spatial.y);
                // Add the payload to our plugin request.
                pr.setEsObject(pos);
                // Now send it on it's way.
                connection.send(pr);                

                // Push our current position into the buffer.
                _positionBuffer.x = spatial.x;
                _positionBuffer.y = spatial.y;
            }
            // Finally, schedule this task to run again.
            PBE.processManager.schedule(200, this, sendPosition);
        }
    }
}
</pre>
<p>
All the support classes are finished. Now to focus on the main game class that will set up the server connection and start our client.
</p>
<h3>A Series of Events</h3>
<p>
Much of what we&#8217;ll be looking at within our main game class is driven by events. Both PushButton Engine and the ElectroServer AS3 API expose events that help you drive your game logic. For a large project you may not want to bundle all your handlers in one place, but we do so here to make it easier to follow how the logic flows from game initialization, server connection and finally gameplay.
</p>
<p><strong>File: /ESPBEDemo-client/src/ESPBEDemo.as</strong></p>
<pre class="brush: jscript;">
package
{
    import com.electrotank.electroserver4.ElectroServer;
    import com.electrotank.electroserver4.entities.Protocol;
    import com.electrotank.electroserver4.entities.SearchCriteria;
    import com.electrotank.electroserver4.entities.UserVariable;
    import com.electrotank.electroserver4.esobject.EsObject;
    import com.electrotank.electroserver4.message.MessageType;
    import com.electrotank.electroserver4.message.event.ConnectionEvent;
    import com.electrotank.electroserver4.message.event.PluginMessageEvent;
    import com.electrotank.electroserver4.message.request.LoginRequest;
    import com.electrotank.electroserver4.message.request.PluginRequest;
    import com.electrotank.electroserver4.message.request.QuickJoinGameRequest;
    import com.electrotank.electroserver4.message.response.CreateOrJoinGameResponse;
    import com.electrotank.electroserver4.message.response.LoginResponse;
    import com.pblabs.engine.PBE;
    import com.pblabs.engine.core.TemplateManager;
    import com.pblabs.engine.entity.IEntity;
    import com.pblabs.engine.entity.PropertyReference;
    import com.pblabs.rendering2D.*;
    import com.pblabs.rendering2D.spritesheet.SpriteSheetComponent;
    import com.philperon.espbedemo.*;
    import com.philperon.espbedemo.components.*;

    import flash.display.Sprite;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.Point;

    // Set up our swf configuration
    [SWF(width=&quot;800&quot;, height=&quot;600&quot;, frameRate=&quot;60&quot;, backgroundColor=&quot;0x000000&quot;)]
    public class ESPBEDemo extends Sprite
    {
        // Define our game protocol here. This reflects the same values we set in
        // part one.
        public static const PLAYER_INIT:int = 1;
        public static const OPPONENT_ENTERED:int = 2;
        public static const STATE_UPDATE:int = 3;
        public static const PLAYER_LEFT:int = 4;

        // declare variable for the ElectroServer connection.
        private var _es:ElectroServer;
        // The room and zone ids.
        private var _roomID:Number = -1;
        private var _zoneID:Number = -1;
        // General properties on users.
        private var _userProps:EsObject;
        // The player name
        private var _name:String;
        // And a collection to hold opponents objects.
        private var _opponents:Object = {};
        // This will hold the type of game we're assigned to.
        private var _gameType:String;

        public function ESPBEDemo()
        {
            // Set the scale mode.
            stage.scaleMode = StageScaleMode.SHOW_ALL;

            // Register classes that we reference in our level files here.
            // This is so the compiler knows to include them.
            PBE.registerType(DisplayObjectRenderer);
            PBE.registerType(DisplayObjectScene);
            PBE.registerType(Interpolated2DMoverComponent);
            PBE.registerType(SimpleSpatialComponent);
            PBE.registerType(SpriteSheetComponent);
            PBE.registerType(SpriteRenderer);
            PBE.registerType(PlayerController);
            PBE.registerType(KeyboardInput);

            // Start PushButton Engine.
            PBE.startup(this);

            // Add our resources.
            PBE.addResources(new Resources());

            // And register the game screen we created earlier.
            PBE.screenManager.registerScreen(&quot;game&quot;, new GameScreen());

            // Set up a loaded handler so that we know when our common.xml file is ready to go.
            PBE.templateManager.addEventListener(TemplateManager.LOADED_EVENT, loadedHandler);
            PBE.templateManager.loadFile(&quot;../assets/levels/common.xml&quot;);
        }

        // The loadedHandler fires once the common.xml level file is loaded.
        private function loadedHandler(event:Event):void
        {
            // Clean up the listener.
            PBE.templateManager.removeEventListener(TemplateManager.LOADED_EVENT, loadedHandler);

            // Instantiate the &quot;common&quot; group we defined in common.xml. This ensures
            // the spatial manager and scene are ready and available.
            PBE.templateManager.instantiateGroup(&quot;common&quot;);

            // Now it's time to start the ElectroServer connection process.
            _es = new ElectroServer();
            // Set the protocol to binary for best performance.
            _es.setProtocol(Protocol.BINARY);
            // Wire up our listeners for connection...
            _es.addEventListener(MessageType.ConnectionEvent, &quot;onConnectionEvent&quot;, this);
            // ...login response...
            _es.addEventListener(MessageType.LoginResponse, &quot;onLoginResponse&quot;, this);
            // ...game joins...
            _es.addEventListener(MessageType.CreateOrJoinGameResponse, &quot;onCreateOrJoinGameResponse&quot;, this);
            // ...and finally, general plugin messages.
            _es.addEventListener(MessageType.PluginMessageEvent, &quot;onPluginMessageEvent&quot;, this);
            // Now, create the connection to the server.
            //(This assumes you're running the server locally.)
            _es.createConnection(&quot;127.0.0.1&quot;, 9899);
        }

        // Handle the connection response from the server.
        public function onConnectionEvent(event:ConnectionEvent):void
        {
            // If the connection is accepted...
            if (event.getAccepted()) {
                // ...generate a user name.
                _name = &quot;user&quot;+Math.round(10000*Math.random());
                // Create and send a login request to the server.
                var loginRequest:LoginRequest = new LoginRequest();
                loginRequest.setUserName(_name);
                _es.send(loginRequest);
            // Otherwise, throw an error.
            } else {
                throw new Error(&quot;Connection failed: &quot; + event.getEsError().getDescription());
            }
        }

        // This handles our login response from the server.
        public function onLoginResponse(event:LoginResponse):void
        {
            // Create a new search criteria instance. This is used
            // inside a join game request below.
            var criteria:SearchCriteria = new SearchCriteria();
            // Set the game type to match the name we defined in part one of the tutorial.
            criteria.setGameType(&quot;game&quot;);

            // Grab the first user variable sent from the server.
            var uservar:UserVariable = event.getUserVariables()[0];
            // Extract the EsObject value from the user variable.
            var esobj:EsObject = uservar.getValue();
            // Make sure we're looking at &quot;gameType&quot;.
            if(esobj.doesPropertyExist(&quot;gameType&quot;))
            {
                // ElectroServer 4 is not yet capable of adding a player to a game automatically
                // so we'll request it from the client side.
                //
                // Grab the game type.
                var mode:String = esobj.getString(&quot;gameType&quot;);
                // And create a new join game request.
                var request:QuickJoinGameRequest = new QuickJoinGameRequest();
                // Set the game type we just grabbed.
                request.setGameType(mode);
                // As well as the zone name.
                request.setZoneName(mode + &quot;Zone&quot;);
                // Finally, set the criteria and send the request back to the server.
                request.setSearchCriteria(criteria);
                _es.send(request);
            }
        }

        // When a game request response arrives from the server, enter this handler.
        public function onCreateOrJoinGameResponse(event:CreateOrJoinGameResponse):void
        {
            // Check to see if we've successfully joined.
            if(event.getSuccessful() == true)
            {
                // Make sure we have a &quot;type&quot;.
                if(event.getGameDetails().doesPropertyExist(&quot;type&quot;))
                {
                    // And set that here.
                    _gameType = event.getGameDetails().getString(&quot;type&quot;);

                    // Store a local reference to the room and zone id.
                    _roomID = event.getRoomId();
                    _zoneID = event.getZoneId();

                    // Tack a listener on to the TemplateManager to notify us when the next file is loaded.
                    PBE.templateManager.addEventListener(TemplateManager.LOADED_EVENT, gameLoadedHandler);
                    // Request that our game.xml file that defines our game is loaded.
                    PBE.templateManager.loadFile(&quot;../assets/levels/&quot; + _gameType + &quot;.xml&quot;);
                }
            }
            // Otherwise, throw an error.
            else
            {
                throw new Error(&quot;Could not join game: &quot; + event.getEsError().getDescription());
            }
        }

        // Jump in this handler once we've loaded our client game assets and are ready to begin.
        private function gameLoadedHandler(event:Event):void
        {
            // Head off to the screen we registered above in the constructor.
            PBE.screenManager.goto(_gameType);

            // Grab the player EsObject that was stored in the _userProps variable. (We'll find
            // out how _userProps got defined below.)
            var player:EsObject = _userProps.getEsObject(&quot;player&quot;);
            // And get the initial x and y location of the player. We do this now because
            // we finally are able to do something about it; Render it on-screen.
            var spawnPoint:Point = new Point(player.getNumber(&quot;x&quot;), player.getNumber(&quot;y&quot;));
            // Create a list of opponents that are already in-game.
            var opponentList:Array = _userProps.getEsObjectArray(&quot;playerlist&quot;);

            // Iterate over each opponent in the list.
            for(var i:uint = 0; i &lt; opponentList.length; i++)
            {
                // Access each opponent EsObject
                var oppObj:EsObject = EsObject(opponentList[i]);
                // Get it's name.
                var name:String = oppObj.getString(&quot;name&quot;);
                // And if the name exists...
                if(name != _name)
                {
                    // ...extract the current position...
                    var p:Point = new Point(oppObj.getNumber(&quot;x&quot;), oppObj.getNumber(&quot;y&quot;));
                    // ...and request that a new opponent avatar be spawned.
                    spawnOpponent(name, p);
                }
            }

            // Finally, don't forget to spawn the player's avatar.
            spawnPlayer(spawnPoint);
        }

        // Define what happens when an opponent avatar is created.
        private function spawnOpponent(name:String, spawnPoint:Point):void
        {
            // Based on the name, create a new entity passing in all the parameters
            // it needs to work properly.
            //
            // &quot;opponent&quot; is the name we gave to the template in game.xml. The &quot;@&quot; symbols
            // mean we're accessing a component of the entity template.
            _opponents[name] = PBE.makeEntity(&quot;opponent&quot;, {
                &quot;@mover.initialPosition&quot;:spawnPoint,
                &quot;@mover.translationSpeed&quot;:100,
                &quot;@controller.currentRoomID&quot;:_roomID,
                &quot;@controller.currentZoneID&quot;:_zoneID,
                &quot;@controller.username&quot;:name
            });
        }

        // Define what happens when a player avatar is created.
        private function spawnPlayer(spawnPoint:Point):void
        {
            // As mentioned above, create a new entity based on the &quot;player&quot;
            // template we defined in game.xml.
            PBE.makeEntity(&quot;player&quot;, {
                &quot;@spatial.position&quot;:spawnPoint,
                &quot;@controller.connection&quot;:_es,
                &quot;@controller.currentRoomID&quot;:_roomID,
                &quot;@controller.currentZoneID&quot;:_zoneID,
                &quot;@controller.username&quot;:_name
            });
        }

        // Define a handler to deal with messages coming in from the plugin.
        public function onPluginMessageEvent(event:PluginMessageEvent):void
        {
            // Get the EsObject from the event object.
            var eso:EsObject = event.getEsObject();
            // Grab the opcode.
            var opcode:int = eso.getInteger(&quot;opcode&quot;);
            // Set up some shared variables.
            var player:EsObject;
            var name:String = &quot;&quot;;

            // switch over the opcode being passed in.
            switch(opcode)
            {
                // When the player was first logged in, we received this message
                // from the server. If you were wondering, this is how _userProps
                // was defined.
                case PLAYER_INIT:
                    _userProps = eso;
                    break;
                // Each time an opponent enters, grab the player object and name and
                // spawn a new opponent avatar.
                case OPPONENT_ENTERED:
                    player = eso.getEsObject(&quot;player&quot;);
                    name = player.getString(&quot;name&quot;);
                    if(name != _name)
                        spawnOpponent(name, new Point(player.getNumber(&quot;x&quot;), player.getNumber(&quot;y&quot;)));
                    break;
                // The only state updates we're handling in this demo are position updates.
                // When they arrive, move the corresponding opponent.
                case STATE_UPDATE:
                    name = eso.getString(&quot;name&quot;);
                    if(name != _name)
                        moveOpponent(name, eso.getNumber(&quot;x&quot;), eso.getNumber(&quot;y&quot;));
                    break;
                // When a player leaves, request that they be removed from the game.
                case PLAYER_LEFT:
                    name = eso.getString(&quot;name&quot;);
                    removePlayerFromList(name);
                    break;
                // Die if we don't recognize an opcode.
                default:
                    throw new Error(&quot;Unknown opcode: &quot; + opcode);
            }
        }

        // Defines what takes place when the server tells us a player has left.
        private function removePlayerFromList(name:String):void
        {
            // Grab the entity reference to the player...
            var player:IEntity = _opponents[name];
            // ...and destroy it.
            player.destroy();
            // Finally, remove it from the collection.
            delete _opponents[name];
        }

        // Handles moving the opponent avatar on the screen.
        private function moveOpponent(username:String, moveX:Number, moveY:Number):void
        {
            // Grab the entity reference.
            var entity:IEntity = _opponents[username];
            // If it's not null, set a new goal position for the interpolated mover component.
            if(entity != null)
            {
                entity.setProperty(new PropertyReference(&quot;@mover.goalPosition&quot;), new Point(moveX, moveY));
            }
        }
    }
}
</pre>
<p>
That&#8217;s it! Make sure the server is started and fire up your newly created client. Click inside the swf and remember to use W, A, S and D (or whatever you chose to set inside the KeyboardInput component) and watch your avatar move. Now open up another browser window and point to the same location to see what happens when another client connects. You may want to play a bit with the &#8220;nudge&#8221; property of the Interpolated2DMoverComponent to get it feeling right but regardless, you&#8217;re off and running!
</p>
<h2>Next Steps</h2>
<p>
We covered a lot of ground in this tutorial and you may be wondering what the heck to do next. If you struggled a bit with some of the server-side stuff we covered in part one, I&#8217;d head over to the ElectroServer <a href="http://www.electro-server.com/forum/">forums</a> or <a href="http://es-wiki.com/index.php?title=Main_Page">wiki</a> and start looking at some of the great tutorials and references they&#8217;ve set up there. If you&#8217;d like to dive deeper into PushButton Engine, the <a href="http://pushbuttonengine.com/forum/">forums</a> are an excellent place to start learning as well as the <a href="http://pushbuttonengine.com/docs/">docs</a> and awesome IRC channel, #pbengine. Finally, if you&#8217;re ready to dig deeper into the world of multiplayer games, I&#8217;d urge you to start looking at some pieces that will be integral once you begin creating a production-grade system. Check out articles and tutorials for things like clock/time synchronization, dead reckoning, area of interest management, object state distribution and persistence. If you&#8217;re feeling especially brave, check out how we handle custom game protocol management using the <a href="http://github.com/pperon">Gliese Framework</a> for RedDwarf
</p>
<p>
If you&#8217;ve come this far, thank you. I appreciate your time and your visit. Now go make a great game!
</p>
<p><em><br />
You can download the source code covered in this post <a href="http://philperon.com/files/ESPBEDemo-client.zip">here</a>.<br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2010/03/31/an-introduction-to-electroserver-and-pushbutton-engine-part-two/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>An Introduction to ElectroServer and PushButton Engine: Part One</title>
		<link>http://philperon.com/2010/03/17/an-introduction-to-electroserver-and-pushbutton-engine-part-one/</link>
		<comments>http://philperon.com/2010/03/17/an-introduction-to-electroserver-and-pushbutton-engine-part-one/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 17:07:57 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[mmo]]></category>
		<category><![CDATA[ElectroServer]]></category>
		<category><![CDATA[gamedev]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=585</guid>
		<description><![CDATA[
There are many options available when deciding on which Flash engine or framework to use before development begins on your next single-player project. Should you decide to add multi-player capability, the list gets shorter. This is especially true if your game crosses over into the MMOG or Virtual World domains. Code reusability, game asset management [...]]]></description>
			<content:encoded><![CDATA[<p>
There are many options available when deciding on which Flash engine or framework to use before development begins on your next single-player project. Should you decide to add multi-player capability, the list gets shorter. This is especially true if your game crosses over into the MMOG or Virtual World domains. Code reusability, game asset management and premium performance are all key to successfully reaching that goal. PushButton Engine satisfies these criteria and more by offering a component-based architecture, dependency injection, a robust engine core and a strong community.
</p>
<p>
When deciding on which server technology to use it&#8217;s quite a different story. The list of viable options is much shorter. Scalability, maintainability, extensibility and price all come to mind when shopping around for the right product. The RedDwarf server (formerly Project Darkstar) is tempting due to it&#8217;s cost (free) but developers who are interested in simply writing their game code may become discouraged due to it&#8217;s steep learning curve. Enter, ElectroServer. When I recently started exploring ElectroTank&#8217;s flagship product, I was hooked on it&#8217;s highly-polished API and how dead-simple it was to get up and running. Couple that experience with it&#8217;s potential to scale to hundreds of thousands of simultaneous users and it&#8217;s difficult to find a better option.
</p>
<p><span id="more-585"></span></p>
<h3>Goals</h3>
<p>The goal of this tutorial is not to have you up and running with a full-blown, ready to ship product. Instead, the focus is on just how little you have to do to get something started. I hope it will help illustrate how powerful the combination of PushButton Engine and ElectroServer can be. Although introductory in nature, I believe you&#8217;ll see the incredible value merging these two great technologies can provide.</p>
<h3>Prerequisites</h3>
<p>I&#8217;m assuming you&#8217;re comfortable moving around an IDE or text editor, have some fairly advanced ActionScript skills, some Java experience and generally aren&#8217;t afraid to get your hands dirty. If you&#8217;ve never used ElectroServer or PushButton Engine, I would urge you at least check out their respective starter lessons to get you up to speed.</p>
<h2>The Server</h2>
<p>Before a client application can start a game, it needs something to connect to. ElectroServer is built on a plugin architecture which allows developers to easily extend it&#8217;s core functionality. Plugins can be scoped to the server, a room or a player. In this example, we&#8217;ll focus on server initialization, user login and finally the game logic itself. Let&#8217;s start digging into some code!</p>
<h3>Initialization</h3>
<p>Our first plugin is scoped to the server and is in charge of configuring the primary game plugin.</p>
<p><strong>File: /ESPBEDemo-server/src/com/philperon/espbedemo/plugins/InitPlugin.java</strong></p>
<pre class="brush: java;">
package com.philperon.espbedemo.plugins;

import com.electrotank.electroserver4.extensions.Plugin;
import com.electrotank.electroserver4.extensions.PluginLifeCycle;
import com.electrotank.electroserver4.extensions.api.PluginApi;
import com.electrotank.electroserver4.extensions.api.value.EsObject;
import com.electrotank.electroserver4.extensions.api.value.EsObjectRO;
import com.electrotank.electroserver4.extensions.api.value.ExtensionComponentConfiguration;
import com.electrotank.electroserver4.extensions.api.value.GameConfiguration;
import com.electrotank.electroserver4.extensions.api.value.RoomConfiguration;

// This is the plugin that gets everything started.
public class InitPlugin implements Plugin, PluginLifeCycle {

    // Define a private handle to the plugin api (used in the getter/setter below)
    private PluginApi api;

    // init is called when the object based on this class is instantiated.
    @Override
    public void init(EsObjectRO esObj) {

        // Create the plugin variable that will contain the plugin.
        ExtensionComponentConfiguration plugin = new ExtensionComponentConfiguration();

        // Define which extension the plugin will be associated with.
        plugin.setExtensionName(&quot;ESPBEDemo&quot;);
        // Set the handle which is how the plugin will be accessed when instantiated in a room.
        plugin.setHandle(&quot;GamePlugin&quot;);
        // Set the name that will be used to label this plugin in the Extension.xml file.
        plugin.setName(&quot;GamePlugin&quot;);

        // Create the room configuration for the room that will host the plugin.
        RoomConfiguration roomConfig = new RoomConfiguration();
        // Set the user connection limit.
        roomConfig.setCapacity(25);
        // Now add the plugin to the room configuration.
        roomConfig.addPlugin(plugin);

        // Create an ElectroServer object that will contain extra details that should be relayed to the user.
        EsObject gameDetails = new EsObject();
        // Set the type so that the client knows how to request access after it connects.
        gameDetails.setString(&quot;type&quot;, &quot;game&quot;);

        // Create a new game configuration instance.
        GameConfiguration gameConfig = new GameConfiguration();
        // Add the game details.
        gameConfig.setInitialGameDetails(gameDetails);
        // Add the room configuration we defined above to the game config object.
        gameConfig.setRoomConfiguration(roomConfig);
        // We're not interested in listening for room list updates in this demonstration...
        gameConfig.setReceivingRoomListUpdates(false);
        // ...or room variable updates.
        gameConfig.setReceivingRoomVariableUpdates(false);
        // Make sure we receive user list updates...
        gameConfig.setReceivingUserListUpdates(true);
        // ...as well as user variable updates.
        gameConfig.setReceivingUserVariableUpdates(true);
        // We're not interested in video events.
        gameConfig.setReceivingVideoEvents(false);
        // Finally, register our &quot;game&quot; using the game configuration object we just created.
        getApi().registerGameConfiguration(&quot;game&quot;, gameConfig);
    }

    @Override
    public PluginApi getApi() {
        return api;
    }

    @Override
    public void setApi(PluginApi api) {
        this.api = api;
    }

    @Override
    public void destroy() {
        // Clean up any loose ends.
    }

}
</pre>
<p>
That wraps up the initialization process. Before jumping into the game plugin, we&#8217;ll need to think about how user logins are handled.
</p>
<h3>Accepting User Logins</h3>
<p>
Event Handlers are another way the ElectroServer API allows you to extend functionality. At this point, the server is aware of the game plugin but we need some way to send this information to a connected client. This is where the LoginEventHandler comes into play.
</p>
<p><strong>File: /ESPBEDemo-server/src/com/philperon/espbedemo/handlers/LoginEventHandler.java</strong></p>
<pre class="brush: java;">
package com.philperon.espbedemo.handlers;

import com.electrotank.electroserver4.extensions.BaseLoginEventHandler;
import com.electrotank.electroserver4.extensions.ChainAction;
import com.electrotank.electroserver4.extensions.LoginContext;
import com.electrotank.electroserver4.extensions.api.value.EsObject;

// Like the other event handlers, there are base classes you extend to get started quickly.
public class LoginEventHandler extends BaseLoginEventHandler {

    // This method fires after a player logs in.
    public ChainAction executeLogin(LoginContext login) {

        // Create a new EsObject to hold values that will soon be passed to the client.
        EsObject uservars = new EsObject();

        // Set a gameType value to the name of our plugin, &quot;game&quot;.
        uservars.setString(&quot;gameType&quot;, &quot;game&quot;);

        // Add the user variables to the login context.
        login.addUserVariable(&quot;uservars&quot;, uservars);

        // And let the server know that all is well.
        return ChainAction.OkAndContinue;
    }
}
</pre>
<p>
Now, any time a user logs in, they will be sent the information they need to request access to the game. Ideally, the server would insert a player automatically but because that functionality is not yet available in the current version of ElectroServer, we&#8217;ll deal with that later on in the client code.
</p>
<h3>Writing the Game Plugin</h3>
<p>
Now to our server-side game code! The objective here is to listen for various player action events such as entering and exiting the game as well as moving around the game world.
</p>
<p><strong>File: /ESPBEDemo-server/src/com/philperon/espbedemo/plugins/GamePlugin.java</strong></p>
<pre class="brush: java;">
package com.philperon.espbedemo.plugins;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import com.electrotank.electroserver4.extensions.BasePlugin;
import com.electrotank.electroserver4.extensions.ChainAction;
import com.electrotank.electroserver4.extensions.api.value.EsObject;
import com.electrotank.electroserver4.extensions.api.value.EsObjectRO;
import com.electrotank.electroserver4.extensions.api.value.UserEnterContext;

// Extend the BasePlugin class to take advantage of the user events it exposes.
public class GamePlugin extends BasePlugin {

    // Define our game protocol...
    // Player enters
    private static final int PLAYER_INIT = 1;
    // Opponent enters
    private static final int OPPONENT_ENTERED = 2;
    // Player state changes
    private static final int STATE_UPDATE = 3;
    // Player leaves
    private static final int PLAYER_LEFT = 4;

    // Create a thread-safe map to store players currently in-game.
    private ConcurrentMap&lt;String,EsObject&gt; playerMap = new ConcurrentHashMap&lt;String,EsObject&gt;(25);

    // When the game initializes, turn on message queueing.
    @Override
    public void init(EsObjectRO esObj) {
        // This will send packaged messages five times per second.
        getApi().startQueue(200);
    }

    // Define what happens when a player enters the game.
    @Override
    public ChainAction userEnter(UserEnterContext context) {

        // Grab the user's name.
        String name = context.getUserName();

        // Create a new EsObject that will represent a player.
        // We're only concerned with their name and position in this demonstration.
        EsObject player = new EsObject();
        // Add their name.
        player.setString(&quot;name&quot;, name);
        // And their starting position.
        player.setNumber(&quot;x&quot;, 400);
        player.setNumber(&quot;y&quot;, 300);

        // Add the player to the room's player map.
        playerMap.put(name, player);

        // Create a EsObject to represent a new player message.
        EsObject uservars = new EsObject();
        // Add the opcode that represents a new player being initialized.
        uservars.setInteger(&quot;opcode&quot;, PLAYER_INIT);
        // Add the player object defined above.
        uservars.setEsObject(&quot;player&quot;, player);
        // Send the player list along so opponents can be properly rendered on the client.
        uservars.setEsObjectArray(&quot;playerlist&quot;, (EsObject[]) playerMap.values().toArray(new EsObject[playerMap.size()]));
        // And send the message privately to the user.
        getApi().sendPluginMessageToUser(context.getUserName(), uservars);

        // Now, define another player object for others to process.
        EsObject userObj = new EsObject();
        // Add the opcode for new opponents entering.
        userObj.setInteger(&quot;opcode&quot;, OPPONENT_ENTERED);
        // Add the player object.
        userObj.setEsObject(&quot;player&quot;, player);
        // And send the message to everyone in the room.
        getApi().sendPluginMessageToRoom(getApi().getZoneId(), getApi().getRoomId(), userObj);

        return ChainAction.OkAndContinue;
    }

    // Define what happens when a player leaves the game.
    @Override
    public void userExit(String name) {
        // Create a new message object.
        EsObject eso = new EsObject();
        // Add the opcode that represents a player leaving.
        eso.setInteger(&quot;opcode&quot;, PLAYER_LEFT);
        // Remove the player from the player map and add the name to the message.
        eso.setString(&quot;name&quot;, playerMap.remove(name).getString(&quot;name&quot;));
        // Now, send the message to the room notifying everyone that the player has left.
        getApi().sendPluginMessageToRoom(getApi().getZoneId(), getApi().getRoomId(), eso);
    }

    // Define what happens when a player sends a message to the room.
    @Override
    public void request(String userName, EsObjectRO requestParameters) {
        // If the user's message carries an opcode, process it.
        if(requestParameters.variableExists(&quot;opcode&quot;)) {
            // If the opcode represents a state update, update it here.
            if(requestParameters.getInteger(&quot;opcode&quot;) == STATE_UPDATE) {
                // Grab a handle of the player from the player map using it's name as a key.
                EsObject player = playerMap.get(userName);
                // And set it's new position.
                player.setNumber(&quot;x&quot;, requestParameters.getNumber(&quot;x&quot;));
                player.setNumber(&quot;y&quot;, requestParameters.getNumber(&quot;y&quot;));
            }
            // Finally, add the state update message to the message queue to be sent to
            // everyone in the room during the next 200ms cycle.
            getApi().sendQueuedPluginMessageToRoom(userName, requestParameters);
        }
    }

    // Clean up if and when the game plugin (room) is removed.
    @Override
    public void destroy() {
        getApi().stopQueue();
    }
}
</pre>
<p>
A quick note regarding message queueing. Due to limitations of the Flash Player and general good practice when designing a multi-player game, you don&#8217;t want to send a high number of messages per second. By wrapping up various messages per packet, the Flash Player remains happy and you still have enough information to render other players on the client adequately enough. I suggest 200 milliseconds per package here, but others might say that between 250 and 500 milliseconds is enough for anything outside a fast-twitch, action game. It really depends on your situation.
</p>
<h3>Deployment</h3>
<p>
Deploying a new ElectroServer is a snap. Simply define an extension.xml file, drop the relevant files in the server&#8217;s extension folder, restart the server and activate them. The Extension.xml file for this demonstration looks like this.
</p>
<p><strong>File: /ESPBEDemo-server/src/extension.xml</strong></p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;Extension&gt;

    &lt;!-- The name of our extension --&gt;
    &lt;Name&gt;ESPBEDemo&lt;/Name&gt;

    &lt;!-- Define all event handlers here. --&gt;
    &lt;EventHandlers&gt;
        &lt;LoginHandlers&gt;

            &lt;!-- Our login handler goes here. --&gt;
            &lt;LoginHandler&gt;

                &lt;!-- Define the name of the handle that will be used to access it --&gt;
                &lt;Handle&gt;LoginEventHandler&lt;/Handle&gt;

                &lt;!-- Define the type. We've been using Java but ActionScript 1 is also an option --&gt;
                &lt;Type&gt;Java&lt;/Type&gt;

                &lt;!-- Set the path to the actual login event handler class. --&gt;
                &lt;Path&gt;com.philperon.espbedemo.handlers.LoginEventHandler&lt;/Path&gt;

                &lt;/LoginHandler&gt;
        &lt;/LoginHandlers&gt;
    &lt;/EventHandlers&gt;

    &lt;!-- Define all plugins here --&gt;
    &lt;Plugins&gt;

        &lt;!-- First, the initialization plugin --&gt;
        &lt;Plugin&gt;
            &lt;Handle&gt;InitPlugin&lt;/Handle&gt;
            &lt;Type&gt;Java&lt;/Type&gt;
            &lt;Path&gt;com.philperon.espbedemo.plugins.InitPlugin&lt;/Path&gt;
        &lt;/Plugin&gt;

        &lt;!-- And then the game plugin --&gt;
        &lt;Plugin&gt;
            &lt;Handle&gt;GamePlugin&lt;/Handle&gt;
            &lt;Type&gt;Java&lt;/Type&gt;
            &lt;Path&gt;com.philperon.espbedemo.plugins.GamePlugin&lt;/Path&gt;
        &lt;/Plugin&gt;

&lt;/Plugins&gt;
&lt;/Extension&gt;
</pre>
<p>
Create two directories in [your electroserver install directory]/server/extenstions/ called, &#8220;ESPBEDemo&#8221; and &#8220;classes&#8221;. Copy the extension.xml file to the root of that directory and move the fully pathed .class files from your java project folder inside &#8220;classes&#8221;. When you&#8217;re finished you should have a structure that looks like this:
</p>
<p><em><br />
$EXTENSION_DIR/ESPBEDemo/extension.xml<br />
$EXTENSION_DIR/ESPBEDemo/classes/com/philperon/espbedemo/handlers/LoginEventHandler.class<br />
$EXTENSION_DIR/ESPBEDemo/classes/com/philperon/espbedemo/plugins/InitPlugin.class<br />
$EXTENSION_DIR/ESPBEDemo/classes/com/philperon/espbedemo/plugins/GamePlugin.class<br />
</em></p>
<p>
Now restart the server and activate the server level components, LoginEventHandler and InitPlugin by selecting &#8220;Extensions&#8221; from the top navigation bar in the ElectroServer admin interface and then, &#8220;Create New Server-level Component&#8221; on the left side of the page.
</p>
<p><img src="http://philperon.com/images/espbedemo/initPlugin.gif" alt="initPlugin definition" /></p>
<p>
Extension name should be the same as you created above (ESPBEDemo) and the name and handle fields should be &#8220;InitPlugin&#8221;. Once that&#8217;s saved, do the same for the LoginEventHandler.
</p>
<p><img src="http://philperon.com/images/espbedemo/loginEventHandler.gif" alt="LoginEventHandler definition" /></p>
<p>
Now restart ElectroServer. When it initializes, you should see something close to the following:
</p>
<p><img src="http://philperon.com/images/espbedemo/serverStart.gif" alt="server start screenshot" /></p>
<p>
Log back into the administration tool and check the extensions. If you expand the ESPBEDemo extension, it should look like this:
</p>
<p><img src="http://philperon.com/images/espbedemo/extensionDeployment.gif" alt="Extension deployment success" /></p>
<p>
Congrats! You&#8217;ve successfully built and deployed a Java extension for ElectroServer!
</p>
<p>
In part two, we&#8217;ll build the PBE client and connect it all together. Stay tuned!
</p>
<p>
<em><br />
You can download the source code covered in this post <a href="http://philperon.com/files/ESPBEDemo-server.zip">here</a>.<br />
</em>
</p>
<p>
<em>For more information on all things ElectroServer, check out their <a href="http://es-wiki.com">wiki</a> or visit their <a href="http://www.electro-server.com/forum/">forums</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2010/03/17/an-introduction-to-electroserver-and-pushbutton-engine-part-one/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>S&#8217;troidz!: Week 7 Update</title>
		<link>http://philperon.com/2009/08/18/stroidz-week-7-update/</link>
		<comments>http://philperon.com/2009/08/18/stroidz-week-7-update/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 02:06:03 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[My Game Experiment]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=506</guid>
		<description><![CDATA[Week 7 is here! This has been the most difficult week so far. Trying to juggle family, work and S&#8217;troidz! proved to be difficult and thus, S&#8217;troidz! had to suffer. The good news is that it wasn&#8217;t totally unproductive. I managed to implement the majority of code needed for the final alien type and that [...]]]></description>
			<content:encoded><![CDATA[<p>Week 7 is here! This has been the most difficult week so far. Trying to juggle family, work and S&#8217;troidz! proved to be difficult and thus, S&#8217;troidz! had to suffer. The good news is that it wasn&#8217;t totally unproductive. I managed to implement the majority of code needed for the final alien type and that alone represents a pretty important milestone on the horizon: The completion of all major game objects!<br />
<span id="more-506"></span><br />
Sure, there are plenty of other things that need to be done. In fact, I have well over 50 items on my list. Some of the secondary items include, music, sound effects, art and menus. None of them have a direct impact on gameplay but they&#8217;re important in that I can&#8217;t (or shouldn&#8217;t really) publish without them.</p>
<p>This leads me to something I thought a lot about when I wasn&#8217;t coding my game. Quality. I may not be able to work on this as much as I&#8217;d like, but I certainly won&#8217;t push anything out too soon just for the sake of getting it done. That would cheapen my efforts and my time spent building this simple, little game is much too precious for that. If I can&#8217;t release this and be proud of it, I won&#8217;t release it at all.</p>
<p>In keeping with the theme of quality, I want to mention a few things that distracted me (in a good way) from writing code for S&#8217;troidz. These are folks that I have a massive amount of respect for and whether they realize it or not, continue to inspire and motivate me.</p>
<p>The guys at <a href="http://blog.gamingyourway.com/">Gaming Your Way</a> rock. They just released an <em>incredible</em> Asteroids-style shooter called, <a href="http://www.kongregate.com/games/GamingYourWay/cronusx">CronusX</a>. This game is extremely well polished and really raises the bar on my favorite flash game genre&#8230; shooters. </p>
<p>Richard Davey&#8217;s site, <a href="http://photonstorm.com">PhotonStorm</a> has been one of my favorites for a long time. Richard along with Christian Corti released <a href="http://photonstorm.com/flod">Flod</a>, a module (.mod) replay library. This is a <em>huge</em> accomplishment. To get an idea of how this can effect the flash game movement, I was able to insert a five minute song with only an additional 130KB added to the file size. Yeah. 130. [pause for applause]</p>
<p><a href="http://coderhump.com/">Ben Garney</a> is the man. Or borg. I&#8217;m not certain as I have reason to believe he never really sleeps. Besides guiding development of PushButton Engine, working on Grunts (PBLabs WiP), tearing up the forums and staying in touch with people on IRC he managed to start a <a href="http://www.youtube.com/user/kmprssr">video series</a> that offer quicktalks covering a wide range of features available with PBE.</p>
<p>Finally, I have to mention Danc from <a href="http://lostgarden.com/">The Lost Garden</a>. He recently published part 2 of his &#8220;Flash Love Letter&#8221; series and it really is a must-read for anyone interested in flash game development.</p>
<p>There are many others I&#8217;d like to add but these are the folks who really charged me up over this past week when I was pretty bummed I couldn&#8217;t fit more <em>quality </em> into S&#8217;troidz!</p>
<p>OK, here we go&#8230;</p>
<h4>S&#8217;troidz! r7 Changelog</h4>
<ul>
<li>Started implementation of final alien type.</li>
<li>Extended powerup duration. Enjoy the carnage.</li>
</ul>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_stroidz_r7_216133329"
			class="flashmovie"
			width="500"
			height="400">
	<param name="movie" value="/stroidz/swf/stroidz_r7.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/stroidz/swf/stroidz_r7.swf"
			name="fm_stroidz_r7_216133329"
			width="500"
			height="400">
	<!--<![endif]-->
		<a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="wp-caption aligncenter" style="width: 204px"><img title="Stroidz! Controls" src="/images/wasd2.png" alt="Stroidz! Controls" width="194" height="125" /><p class="wp-caption-text">S&#39;troidz! Controls</p></div>
<p>The next two weeks are jammed full of work and familial obligations. Therefore I won&#8217;t be doing much (or any) coding on S&#8217;troidz! I will however be leisurely exploring sound effects and art in an effort to hone in on what this thing should look and sound like.</p>
<p>Thanks for stopping by!</p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2009/08/18/stroidz-week-7-update/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>S&#8217;troidz!: Week 6 Update</title>
		<link>http://philperon.com/2009/08/11/stroidz-week-6-update/</link>
		<comments>http://philperon.com/2009/08/11/stroidz-week-6-update/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 21:09:29 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[My Game Experiment]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=473</guid>
		<description><![CDATA[Week 6 has arrived along with hyperspace jumps and shields! I struggled with how shields should work but ended up settling on the most destructive method (destruction usually equals fun). This means that when shields are up, your ship becomes a weapon allowing you to smash through anything.

Hyperspace jumps are also included to appease the [...]]]></description>
			<content:encoded><![CDATA[<p>Week 6 has arrived along with hyperspace jumps and shields! I struggled with how shields should work but ended up settling on the most destructive method (destruction usually equals fun). This means that when shields are up, your ship becomes a weapon allowing you to smash through <em>anything</em>.<br />
<span id="more-473"></span><br />
Hyperspace jumps are also included to appease the Asteroid gods. If you&#8217;re familiar with the classic version, you&#8217;ll know what to expect. If you&#8217;re not&#8230; well, use it at your own risk. After all these years, we still haven&#8217;t worked out solid navigation controls when using hyperspace. I blame Apple, ActionScript, Mochi and whatever else is trending at the moment.</p>
<p>OK, in the interest of time (which is <em>very</em> short) here&#8217;s the latest change log and release of S&#8217;troidz!</p>
<h4>S&#8217;troidz! r6 Changelog</h4>
<ul>
<li>Added Hyperspace Jumps</li>
<li>Added Shields</li>
<li>Tweaked difficulty progression to add more s&#8217;troidz sooner</li>
<li>Fixed Power Up &#8220;value not a function&#8221; bug</li>
<li>Bonus points no longer countdown when there are only s&#8217;troid core left on the screen</li>
<li>Many other misc. bug fixes</li>
</ul>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_stroidz_r6_708386400"
			class="flashmovie"
			width="500"
			height="400">
	<param name="movie" value="/stroidz/swf/stroidz_r6.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/stroidz/swf/stroidz_r6.swf"
			name="fm_stroidz_r6_708386400"
			width="500"
			height="400">
	<!--<![endif]-->
		<a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="wp-caption aligncenter" style="width: 204px"><img title="Stroidz! Controls" src="/images/wasd2.png" alt="Stroidz! Controls" width="194" height="125" /><p class="wp-caption-text">S&#39;troidz! Controls</p></div>
<p>I skipped out on adding the final alien type so I&#8217;d like to start work on that for r7. I&#8217;m also interested in adding interstitials between waves that will eventually act as place holders for things like stats and whatnot. The elephant in the room is the latest, greatest PushButton Engine revision that conforms to Adobe&#8217;s coding standards. If time allows, I&#8217;ll start moving the S&#8217;troidz! codebase on top of it. Otherwise, it&#8217;ll be the first thing I tackle in week 8.</p>
<p>Stay tuned! <img src='http://philperon.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2009/08/11/stroidz-week-6-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>S&#8217;troidz!: Week 5 Update</title>
		<link>http://philperon.com/2009/08/04/stroidz-week-5-update/</link>
		<comments>http://philperon.com/2009/08/04/stroidz-week-5-update/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 16:25:41 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[My Game Experiment]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=438</guid>
		<description><![CDATA[It&#8217;s been an incredibly busy two weeks. Unfortunately, not so much for S&#8217;troidz! The good news is that I accomplished the goals I set for myself, was mega-productive at work (or my &#8220;real&#8217; job) and managed to retain some semblance of a life outside coding. As difficult as it was to stay away from S&#8217;troidz!, [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been an incredibly busy two weeks. Unfortunately, not so much for S&#8217;troidz! The good news is that I accomplished the goals I set for myself, was mega-productive at work (or my &#8220;real&#8217; job) and managed to retain some semblance of a life outside coding. As difficult as it was to stay away from S&#8217;troidz!, the break actually served me well and the batteries are charged for another push.</p>
<p>OK, so what&#8217;s new in S&#8217;troidz! r5? Let&#8217;s see!<br />
<span id="more-438"></span></p>
<p>Because of my busy schedule, I thought I&#8217;d go ahead and spend a boat load of cash on advertising now in hopes of building up some early hype. In fact, I hired one of the more prestigious ad design experts around and am quite pleased with the results:</p>
<div class="wp-caption aligncenter" style="width: 281px"><img src="http://philperon.com/images/stroidzAd.gif" alt="S'troidz! Ad!" /><p class="wp-caption-text">WTF?!</p></div>
<p>The folks at Evony better <a href="http://www.codinghorror.com/blog/archives/001286.html">LOOK OUT</a>!</p>
<p>The other two tantalizing items you&#8217;ll notice this week are a new alien bomber and a core attractor power up.</p>
<p>The alien bomber is the third of four total alien types that make up the family of baddies in S&#8217;troidz! The bomber either drops from the top or rises from the bottom of the screen and (you guessed it) drops a bomb in it&#8217;s wake. Be sure and stay clear of the explosion as it destroys you instantly.</p>
<p>So as not to just make the game more difficult, I&#8217;ve added a core attractor power up. Cores are harvested from smaller s&#8217;troidz and once you&#8217;ve collected enough of them, a new life is granted. The attractor greatly increases the velocity by which the cores move toward your ship, quickly boosting your count and helping you get the most out of the bonus points available.</p>
<p>OK, enough yappin&#8217;. Play DISCREETLY on your browser NOW! <img src='http://philperon.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h4>S&#8217;troidz! r5 Changelog</h4>
<ul>
<li>Added Bomber Alien.</li>
<li>Added Core Attractor Power Up.</li>
<li>Fixed a nasty alien movement bug.</li>
<li>Started work on game difficulty progression.</li>
</ul>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_stroidz_r5_1012932958"
			class="flashmovie"
			width="500"
			height="400">
	<param name="movie" value="/stroidz/swf/stroidz_r5.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/stroidz/swf/stroidz_r5.swf"
			name="fm_stroidz_r5_1012932958"
			width="500"
			height="400">
	<!--<![endif]-->
		<a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="wp-caption aligncenter" style="width: 204px"><img title="Stroidz! Controls" src="/images/wasd.png" alt="Stroidz! Controls" width="194" height="62" /><p class="wp-caption-text">S&#39;troidz! Controls</p></div>
<p>The big item up for development this week is the obligatory hyperspace! Once that&#8217;s complete, I&#8217;m going to try and nail down a better form of gameplay progression and finally lay the groundwork for the last alien type. (Martijn, if you&#8217;re reading this&#8230; I&#8217;m sorry but no high scores next week. <img src='http://philperon.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> )</p>
<p>Finally, to anyone who (like me) works full time on other things yet still wants to be a productive game developer, let me offer you this piece of advice:</p>
<p>Get <em>something</em> done.</p>
<p>Even if it&#8217;s something small like tweaking a game value, play-testing or doing a sanity check on your design. You may not be as productive as you&#8217;d like but don&#8217;t brush aside an opportunity to get something done&#8230; even if it seems trite.</p>
<p>Thanks for stopping by!</p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2009/08/04/stroidz-week-5-update/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>S&#8217;troidz!: Week 4 Update</title>
		<link>http://philperon.com/2009/07/21/stroidz-week-4-update/</link>
		<comments>http://philperon.com/2009/07/21/stroidz-week-4-update/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 17:34:12 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[My Game Experiment]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=396</guid>
		<description><![CDATA[I&#8217;m continually amazed at how difficult game design is. I was reminded of this during the r4 dev cycle when I started implementing power-ups and other goodies. Given the platform I&#8217;m building on, it was easy. Adjusting the game play so that it was still fun was tricky and required a change to how the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m continually amazed at how difficult game design is. I was reminded of this during the r4 dev cycle when I started implementing power-ups and other goodies. Given the <a href="http://pushbuttonengine.com">platform</a> I&#8217;m building on, it was easy. Adjusting the game play so that it was still <em>fun</em> was tricky and required a change to how the ship moves.<br />
<span id="more-396"></span><br />
When I <a href="http://philperon.com/2009/06/18/the-genesis-of-stroidz/">first started development on S&#8217;troidz!</a> I knew I wanted power ups. It&#8217;s surely one of those &#8216;must have&#8217; items when building a <a href="http://en.wikipedia.org/wiki/Shmup">shmup</a> and acts as a device that lures the player into the fray. I like the idea of incentivizing player movement so much that I removed the extra life power up in favor of tokens (called &#8217;s&#8217;troid core&#8217;) that will be used toward earning another ship. Once this was implemented, I realized I had a big problem.</p>
<p>Forcing players to move often is fine provided you give them a vehicle to do so that&#8217;s easy and most importantly, fun. Unfortunately, a zero-drag ship tasked with collecting many items in a short period of time is not. It felt like trying to collect marbles on an ice rink. And we all know what that means: <em>marbles + ice rink = not fun</em>. So with a few taps on the keyboard I added something that would solve my problem and also completely change the style of the game. Friction. You&#8217;ll notice now that moving the ship feels more like maneuvering a drift car. This makes it easier to collect power ups, s&#8217;troid core and in my opinion, makes it more fun. </p>
<p>Also worth noting is the Loot Controller component I wrote to support any &#8217;stuff&#8217; that could potentially drop from killing baddies. It&#8217;s pretty basic in it&#8217;s current form. Internally, the loot controller rolls against a table that returns the manager in charge of creating the loot you &#8216;won&#8217;. The biggest problem with my implementation is that it relies completely on my Spawn-family of classes. This makes sharing the component (which was my hope) difficult should someone else have their own way of spawning game objects. Frankly, creating loot and spawner components fit for public consumption merits it&#8217;s own development timeline. Needless to say, it&#8217;s out of scope for the S&#8217;troidz! project.</p>
<p>OK, up and at &#8216;em!</p>
<h4>S&#8217;troidz! r4 Changelog</h4>
<ul>
<li>Implemented Loot Table Component</li>
<li>Created S&#8217;troid Core Spawner and Sprites</li>
<li>50 S&#8217;troid Core collected grants a new life.</li>
<li>Created Increased Fire Power, Power-Up</li>
<li>Various bug fixes with just a hint of refactoring</li>
</ul>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_stroidz_r4_258434980"
			class="flashmovie"
			width="500"
			height="400">
	<param name="movie" value="/stroidz/swf/stroidz_r4.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/stroidz/swf/stroidz_r4.swf"
			name="fm_stroidz_r4_258434980"
			width="500"
			height="400">
	<!--<![endif]-->
		<a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="wp-caption aligncenter" style="width: 204px"><img title="Stroidz! Controls" src="/images/wasd.png" alt="Stroidz! Controls" width="194" height="62" /><p class="wp-caption-text">S&#39;troidz! Controls</p></div>
<p>I have a lot of non-game related work and traveling to do over the next dev cycle and thus won&#8217;t be releasing a new version of S&#8217;troidz! next week. Once my schedule clears up, I&#8217;ll start work on a new alien type and if time allows, another power up.</p>
<p>Thanks for visiting!</p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2009/07/21/stroidz-week-4-update/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>S&#8217;troidz!: Week 3 Update</title>
		<link>http://philperon.com/2009/07/14/stroidz-week-3-update/</link>
		<comments>http://philperon.com/2009/07/14/stroidz-week-3-update/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 16:51:32 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[My Game Experiment]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=356</guid>
		<description><![CDATA[I learned more than I produced this week. This wasn&#8217;t by choice. I had planned for a lot more. What started as a leisure session to create some explosions (among many other things) ended up being a complete rewiring of nearly half of the classes that make up S&#8217;troidz!

When I first started tying game objects [...]]]></description>
			<content:encoded><![CDATA[<p>I learned more than I produced this week. This wasn&#8217;t by choice. I had planned for a lot more. What started as a leisure session to create some explosions (among many other things) ended up being a complete rewiring of nearly half of the classes that make up S&#8217;troidz!<br />
<span id="more-356"></span></p>
<p>When I first started tying game objects together I used events exclusively. Having just started using PBE, I wasn&#8217;t interested in changing the tools I was comfortable with. What I didn&#8217;t expect was how events would behave when you start dispatching, handling and responding to many of them several times per second. The results were sketchy. Inconsistent. The worst case scenario is that an event never reaches the handler. Unfortunately for me, this happened way too often. Shoving aside a list of items I wanted to address this week, I decided to rewrite the communication layer using function pointers instead.</p>
<p>The results were fantastic. It&#8217;s precise, reliable and direct. The downside is that I lose the convenience behind using events. For a relatively simple game like S&#8217;troidz! it&#8217;s not too gnarly having to manage it all yourself but in the future, I&#8217;ll probably want to design a more formal system. Don&#8217;t get me wrong, I&#8217;m still using events for other, less timely things but if it&#8217;s super critical, time sensitive and/or needs to happen in a serial fashion, I&#8217;ll stick with callbacks. OK, moving on&#8230;</p>
<p>Explosions! If refactoring a bunch of code was for me, adding explosions was for the player. It&#8217;s almost silly how something like this can add so much value to a game. Maybe I&#8217;m just being juvenile but it really <i>is</i> more fun when you can blow crap up.</p>
<p>Speaking of blowing crap up, why don&#8217;t you give it a shot?</p>
<h4>S&#8217;troidz! r3 Changelog</h4>
<ul>
<li>S&#8217;troidz no longer spawn on top of your ship.</li>
<li>Explosions!</li>
<li>Adjusted flight pattern of the &#8216;Waver&#8217; alien. (If you&#8217;ve been hanging out in the center of the screen, you may want to think about moving.)
<li>A few other minor bug fixes.</li>
</ul>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_stroidz_r3_149605428"
			class="flashmovie"
			width="500"
			height="400">
	<param name="movie" value="/stroidz/swf/stroidz_r3.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/stroidz/swf/stroidz_r3.swf"
			name="fm_stroidz_r3_149605428"
			width="500"
			height="400">
	<!--<![endif]-->
		<a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="wp-caption aligncenter" style="width: 204px"><img title="Stroidz! Controls" src="/images/wasd.png" alt="Stroidz! Controls" width="194" height="62" /><p class="wp-caption-text">S&#39;troidz! Controls</p></div>
<p>This week I plan on wrapping up last week&#8217;s tasks which included creation of a loot table and power-ups. If I can rip threw those, I might begin work on the next alien type.</p>
<p>Let me know if anything breaks or just plain sucks.</p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2009/07/14/stroidz-week-3-update/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>S’troidz!: Week 2 Update</title>
		<link>http://philperon.com/2009/07/07/stroidz-week-2-update/</link>
		<comments>http://philperon.com/2009/07/07/stroidz-week-2-update/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 16:05:50 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[My Game Experiment]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=315</guid>
		<description><![CDATA[This week&#8217;s update is bittersweet. I added some cool stuff but had to dump dynamic game balancing. (It&#8217;s not you, it&#8217;s me) Deep down I knew it wouldn&#8217;t last. I just didn&#8217;t think I&#8217;d be killing it so soon. It&#8217;s still something I&#8217;d like to work on some day but for now, I&#8217;ll be rocking [...]]]></description>
			<content:encoded><![CDATA[<p>This week&#8217;s update is bittersweet. I added some cool stuff but had to dump dynamic game balancing. <em>(It&#8217;s not you, it&#8217;s me)</em> Deep down I knew it wouldn&#8217;t last. I just didn&#8217;t think I&#8217;d be killing it so soon. It&#8217;s still something I&#8217;d like to work on some day but for now, I&#8217;ll be rocking a more linear approach. It&#8217;s easier to test and <em>much</em> easier to change. Onward!<br />
<span id="more-315"></span></p>
<h4>S&#8217;troidz! r2 Changelog</h4>
<ul>
<li>Added a logo.</li>
<li>Added a preloader.</li>
<li>Removed mouse cursor when the game starts.</li>
<li>Fixed focus so that you no longer have to click the game twice to start playing.</li>
<li>Added another alien! (clear 6 waves to meet him)</li>
<li>Improved fonts.</li>
<li>Added labels to scoreboard.</li>
<li>Linear game difficulty adjustment.</li>
<li>New hero ship!</li>
<li>New missle sprites for hero and aliens.</li>
<li>Increased large S&#8217;troid speed slightly.</li>
<li>More bugs!</li>
</ul>
<p><em>Note: I&#8217;ve been testing Flex 4 builds of PBE and S&#8217;troidz! which target Flash Player 10.</em><br />

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_stroidz_r2_563015608"
			class="flashmovie"
			width="500"
			height="400">
	<param name="movie" value="/stroidz/swf/stroidz_r2.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/stroidz/swf/stroidz_r2.swf"
			name="fm_stroidz_r2_563015608"
			width="500"
			height="400">
	<!--<![endif]-->
		<a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="wp-caption aligncenter" style="width: 204px"><img title="Stroidz! Controls" src="/images/wasd.png" alt="Stroidz! Controls" width="194" height="62" /><p class="wp-caption-text">S&#39;troidz! Controls</p></div>
<p>I hope you enjoyed this week&#8217;s release of S&#8217;troidz! Up next is design and development of a &#8220;loot table&#8221; component that will allow for things like power-ups. I also need to suck it up and deal with some annoying gameplay issues. Finally, if there&#8217;s time I&#8217;d like to also start work on explosion sprites and maybe even sound.</p>
<p>As always your comments and criticisms are greatly appreciated.</p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2009/07/07/stroidz-week-2-update/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>S&#8217;troidz!: Week 1 Update</title>
		<link>http://philperon.com/2009/06/26/stroidz-week-1-update/</link>
		<comments>http://philperon.com/2009/06/26/stroidz-week-1-update/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 17:11:08 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[My Game Experiment]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=125</guid>
		<description><![CDATA[Welcome to the week of aliens. Well, one alien actually. I&#8217;ve already written the movement for four of them but a nasty (unrelated) bug with one of my components and a half-baked integration plan made the beginning of this week&#8217;s development a bit muddy. The good news is that I came away with a better [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to the week of aliens. Well, one alien actually. I&#8217;ve already written the movement for four of them but a nasty (unrelated) bug with one of my components and a half-baked integration plan made the beginning of this week&#8217;s development a bit muddy. The good news is that I came away with a better understanding of how things should be structured and when that magical day of refactoring comes around (probably next week), I&#8217;ll be ready. Without further ado, here&#8217;s the change log for S&#8217;troidz! r1:<span id="more-125"></span></p>
<ul>
<li>Created dev artwork for first alien (Slider) and projectiles.</li>
<li>Wrote Slider controller PBE component.</li>
<li>Wrote Slider missle controller PBE component</li>
<li>Wired up all collision detection for Slider/Ship and Slider missle/Ship interaction.</li>
<li>Increased the ship rotation speed (slightly).</li>
<li>Fixed a bug inside my random number from range utility function.</li>
<li>Cleaned up some unused spatial properties.</li>
<li>Implemented a &#8217;safe period&#8217; that occurs when a ship spawns (there&#8217;s no visual cue yet and you&#8217;re still fair game after a new wave).</li>
<li>Tweaked the game balancing a bit. Things get gnarly pretty quickly.</li>
</ul>
<p>OK, here we go&#8230;</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_stroidz_r1_473290529"
			class="flashmovie"
			width="500"
			height="400">
	<param name="movie" value="/stroidz/swf/stroidz_r1.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/stroidz/swf/stroidz_r1.swf"
			name="fm_stroidz_r1_473290529"
			width="500"
			height="400">
	<!--<![endif]-->
		<a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="wp-caption aligncenter" style="width: 204px"><img title="Stroidz! Controls" src="/images/wasd.png" alt="Stroidz! Controls" width="194" height="62" /><p class="wp-caption-text">S&#39;troidz! Controls</p></div>
<p>Please share with me any bugs you find or thoughts about gameplay. Even in this raw form, that sort of feedback forces me to shift my perspective and ultimately has a positive affect on development. Have something you&#8217;d like to see in a future build? Let me know! I have a pretty clear design in place but if your request is on the list I have no problems bumping up the priority.</p>
<p>One last bit&#8230; releasing on Fridays doesn&#8217;t make a lot of sense for a number of reasons. Going forward, all new revisions will be deployed on Tuesdays instead. The next one will add another alien craft (fun!), some refactoring and if time permits, start work on designing a PBE &#8220;Loot Table&#8221; component that will allow for power-ups to drop from s&#8217;troidz. I&#8217;m also thinking it&#8217;s about time I add some dev art for explosions as well.</p>
<p>So much to do! Thanks for visiting and above all else, thanks for playing!</p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2009/06/26/stroidz-week-1-update/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>S&#8217;troidz!: Week 0 Update</title>
		<link>http://philperon.com/2009/06/19/stroidz-week-0-update/</link>
		<comments>http://philperon.com/2009/06/19/stroidz-week-0-update/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 15:46:49 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[My Game Experiment]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://philperon.com/?p=99</guid>
		<description><![CDATA[It&#8217;s here! The zeroth weekly update on My Game Experiment! I&#8217;ve actually been working on S&#8217;troidz! for a few weeks now but I don&#8217;t like negative week indexes. That&#8217;s just crazy. This update will cover the development I&#8217;ve done so far and close with what&#8217;s on the table for next week&#8217;s build.

First let me tell [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s here! The zeroth weekly update on <a title="My Game Experiment" href="http://philperon.com/2009/06/16/my-game-experiment/">My Game Experiment</a>! I&#8217;ve actually been working on S&#8217;troidz! for a few weeks now but I don&#8217;t like negative week indexes. That&#8217;s just crazy. This update will cover the development I&#8217;ve done so far and close with what&#8217;s on the table for next week&#8217;s build.</p>
<p><span id="more-99"></span></p>
<p>First let me tell you quickly why I&#8217;ve chosen this format to develop my first game&#8230;</p>
<p>I practice a type of <a title="Agile Development" href="http://en.wikipedia.org/wiki/Agile_development">Agile development</a> at my &#8220;real job&#8221; where projects are broken down into sprints, cycles or whatever-you-want-to-call-them and releases are built at the end of each. Requirements drive these cycles and business folks get to choose what they&#8217;d like to see next. This empowers them to decide what&#8217;s most important and allows developers to show and share their work quickly and efficiently. The beauty is that you have a working &#8220;thing&#8221; every development period.</p>
<p>Moving on&#8230;</p>
<p>After creating what&#8217;s essentially a skeleton <a title="PushButton Engine" href="http://pushbuttonengine.com/">PushButton Engine</a> project, I lifted some art from the interweb (I&#8217;ll totally give it back) and fleshed out the sprite sheets I&#8217;d need for the ship avatar and of course, the S&#8217;troidz!. The nice thing about using a framework like PBE is that once the project was setup, I only had to write a controller to deal with motion and collision. Input, rendering, spatial logic and other goodies are done for you. I spent about 12 seconds creating missiles in <a title="Graphics Gale" href="http://www.humanbalance.net/gale/us/">Graphics Gale</a> which gave me all the assets I needed to move around the game screen and shoot stuff.</p>
<p>The next block of development was dedicated to object spawning and collision detection crap. The latter was a pain in the neck. <a href="http://philperon.com/2007/09/07/bitmap-collison-detection-with-actionscript-3/">I wrote a class</a> a while back that I wanted to use but it flaked out way too often. Then I tried the <a title="troygilbert.com" href="http://troygilbert.com/2007/06/25/pixel-perfect-collision-detection-in-actionscript3">PixelPerfectCollisionDetection class</a> but that kept throwing runtime errors due to null object references (and I liked that one too <img src='http://philperon.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> ). Finally, I settled on <a title="labs.boulevart.be Collision.as" href="http://labs.boulevart.be/index.php/2007/06/08/skinner-collision-detection-in-as3/">yet another class</a> that seems to be working well so far. <em>(I haven&#8217;t played with Corey O&#8217;Neil&#8217;s <a title="Collision Detection Kit" href="http://coreyoneil.com/portfolio/index.php?project=5">Collision Detection Kit</a> yet but it looks pretty solid.)</em></p>
<p>By the end of this period I had finished a family of Spawn classes that instantiate game objects based on things like collision detection. This allows me to easily create smaller chunks of S&#8217;troidz! when a large one was hit for example.</p>
<p>Now for the final development block where I spent most of my time writing countdown components, text render components and my own version of <a title="Dynamic Game Balancing" href="http://en.wikipedia.org/wiki/Dynamic_game_balancing">Dynamic Game Balancing</a>.</p>
<p>The countdown component worked out really well. It&#8217;s amazing how handy this is for various game actions. PBE gives you a simple method to call functions in the future but I needed a few more bells and whistles. Once complete I was able to hook up the scoreboard, life counter and bonus point text rendering components. S&#8217;troidz! rewards fast play and the combination of countdown and bonus point render components makes it easy for the player to know how they&#8217;re doing.</p>
<p>Most recently, the game balancing piece was activated which relieves me of having to pre-package gameplay that accomodates 2 or 3 difficulty levels.</p>
<p>That brings us to today&#8217;s demo! Please keep a few things in mind:</p>
<ul>
<li>Expect bugs.</li>
<li>Expect S&#8217;troidz! to spawn <em>right</em> on top of your ship killing you instantly.</li>
<li>Expect it to be either really hard or really easy while I fine tune the balancing.</li>
<li><span style="text-decoration: line-through;">Expect a slight delay while the game resources load after pressing the start button. I&#8217;m experiencing an old embedded resource issue again.</span></li>
<li>No fonts are being embedded so if you see a grey box with no text, click it and the game will begin.</li>
</ul>
<p>Ok, I&#8217;ll shut up.</p>
<p>(NOTE: If you have trouble viewing it below you can view the swf directly <a href="http://philperon.com/stroidz/swf/stroidz_r0.swf">here</a>)</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_stroidz_r0_1396095261"
			class="flashmovie"
			width="500"
			height="400">
	<param name="movie" value="/stroidz/swf/stroidz_r0.swf?" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="/stroidz/swf/stroidz_r0.swf?"
			name="fm_stroidz_r0_1396095261"
			width="500"
			height="400">
	<!--<![endif]-->
		<a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<div class="wp-caption aligncenter" style="width: 204px"><img title="Stroidz! Controls" src="/images/wasd.png" alt="Stroidz! Controls" width="194" height="62" /><p class="wp-caption-text">S&#39;troidz! Controls</p></div>
<p>If you&#8217;ve gotten this far it wasn&#8217;t so awful as to push you immediately from the page. That being said, I know it probably wasn&#8217;t a blast either. Good, bad or indifferent I&#8217;d love to hear your thoughts.</p>
<p>That wraps up week zero. The next dev cycle will focus on the installation of alien crafts and if I have time, implement a period of invulnerability for player ships that respawn after being destroyed.</p>
<p>Thanks so much for visiting. S&#8217;troidz! will be back next week!</p>
]]></content:encoded>
			<wfw:commentRss>http://philperon.com/2009/06/19/stroidz-week-0-update/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
