Monday, April 11, 2011

Runtime State Editing Android

I was happy to find some more supporting evidence that rapid iterations is the key to developing good software.  Here's a great article from Gamasutra about the development of tools for Dead Rising 2)
"Typically a tool will be some sort of viewer that allows a designer to tweak their content data. That data is then compiled, built, or baked, and somehow makes its way into the game. Often this process is long -- minutes if not hours -- involves restarting the game, and usually involves having a programmer enter some secret code.
It seemed much better to have a designer move objects around at run time from the comfort of their PC, so we developed a communications protocol that could talk between a game console and the PC.  
Tools could now make the game do things (like spawn objects, move their locations, change an items attributes, etc.) at runtime."

I think games are a prime example of why designing tools for real time are so powerful.  Developers for games spend a good deal of time developing the foundation (physics, rules, etc.) then folks (who aren't programmers, sometimes artists or level designers) populate the game with content.  If those iterations are slow (as described in the article) it's painful, and you really make the process tedious.  The easier it is for people to make changes, the more likely you will end up with a refined product in the end.

Normally (and especially with Android) the Software are optimizing for the finished/deployed application (i.e. they are concerned with performance, load times, memory footprint, etc.)  And those are good things to focus on for a finished product.  However, having all of the resources local inside a single distro requires a recompile, repackage and redeploy each time, and therefore is not efficient for creation of software.  What I want to offer is a way to optimize quick iterations, in a way that can produce a refined finished product.

Originally I was looking to create some simple telemetry for determining what areas of the game are too difficult and return information about the game as it is being played.  Taking this a step further, it seemed logical that if I could Monitor the state of the game, why not allow real time editing as well. (If you can identify an issue using telemetry, why couldn't you "fix" and retest it in real time?) 


The system I have in mind is a client server based system.  The Android device will have a Service (call the RealTimeChangeService) that can be bound to by the application (only in development/debug mode).  During bootstrap the application class will resolve all of the dependencies including all of the application "state" (it will not only wire components (code) together, but it will also resolve variables (i.e. touchSensitivity), images (headerleft.gif), sounds (alarm.au), etc.

For example, I have a "state" class which contains the variables for dealing with the accelerometer:


/** The configuration properties of a GameTiltListener */ 
public class GameTiltListenerConfig {


/** threshold to determine if the x tilt encountered should cause movement (i.e. dead zone) should be > 0 */
public float xTiltDampener = 0.3f;

/** threshold to determine if the y tilt encountered should cause movement (i.e. dead zone)  should be > 0 */
public float yTiltDampener = 0.3f;

/** factor applied to the xTilt (assuming the xTilt > xTiltDampener)...(> 1.0 = speedup) (< 1.0 = slowdown)  should be > 0 */ 
public float xTiltSpeedFactor = 1.0f;
}


GameTiltListenerConfig is created at bootstrap and used within the game to modify the character movement.  In real-time development mode, in addition to creating and setting these values, the application will also create and register an "Editor" which has a reference to the GameTiltListenerConfig, and this editor will be capable of : exporting the "specification" (i.e. the Editor will be aware of all of the properties available in the GameTiltListenerConfig object), and the editor will be able to export the state of the object (at the moment I'm using JSON as a data format) as well as accept changes to the state (i.e. allow someone to say editor.set("yTiltDampener", 0.5);


This is where Java Reflection comes in handy... I create a simple class (FieldEditor) that takes any JavaBean class in it's constructor, it introspects the class (in this case a GameTiltListenerConfig to find all of it's fields (the names and types).  The FieldEditor can accomplish all of the tasks (export the specification of the object, the state of the object, and also accept changes to update the value of the fields).

So on bootstrap
1) The state is created and the game entities are wired together
2) Editors are created with references to the game state
3) The application binds to the "RealTimeChange" service
4) The specification(s) are exported (there are many specifications for the many stateful game objects)
5) The state of the game is exported
6) The game listens for changes coming from the "RealTimeChange" Service
---On change: The appropriate Editor will process the change

The Service will perform all of the required Server connectivity, it will upload the specifications and state to the server, and the state can be changed on the server (through any client that is appropriate).  The Service (on the Android Device) will poll the server at set increments and determine if changes are required, if so, the client requests the updates and the appropriate editor will mutate the state of the program at runtime.

..Later I'll describe more on the Specifications, etc., and how the specifications are tied to the data and the server-side editors (a dynamic UI editor that that is created at runtime).

No comments:

Post a Comment