Monday, February 23, 2009

Handling Behavior

As mentioned in prior posts, a large portion of the game focuses on the development of self-autonomous cells. We intend to allow players as much flexibility as possible to implement creative and unique behaviors. To ensure that players with varied levels of experience can feel comfortable sculpting the personalities of their minions, we have turned to implementing a block diagram interface for controlling logic and behavior.

When players enter the cell creation pane, they will be presented with various blocks all of which describe a specific function, and have the appropriate number of inputs and outputs (example: an 'add' block which outputs the sum of two, or more, inputs). Conceptually, these blocks will be cascaded to form complex logic (for instance: If the cell is 10 units of distance from another cell, follow it, otherwise move along the light gradient to find an area of high intensity light). By exposing the low level logic to players, we hope to see some truly unique (and perhaps bizarre) strategies develop, and the decision to use a block diagram format will hopefully make the act of programming the buggers a little less daunting to those less familiar with controls.

To this end, for the last two weeks I have been developing a block diagram parser. The base code is being written in C++ and will be wrapped for use within Python. As parsing and exacting the logic of the multitude of cells will undoubtedly be the most computationally intensive part of the final game, we wanted to make sure it's fast.

The technical details follow: Each block contains a number of registers equal to the sum of the block's number of inputs and outputs. Consider that there is a flow downstream from output of the root block to input of the first child, output of the first child to input of the second, etc. During a game cycle, each block in the logic interface will call all upstream neighbors and load their input registers with the output register values from the respective upstream block. Once all inputs have been loaded, the appropriate calculations will be performed on the input register values (i.e. adders will sum the two input registers, Boolean logic blocks will compare the inputs, etc.). The resulting value is loaded into the output register for the next cycle. Thus as the game clock ticks, inputs will be loaded from upstream outputs, appropriate calculations will be performed, and the output register will be loaded for the next cycle.

Currently, blocks can be adjoined to neighbors and values can be passed between output to input registers. The parser works at a basic level and I am able to propagate a signal along a series of logic blocks. More blocks need to be developed to fully test the parser and I have yet to tackle the question of feedback.

A little to my surprise, the parser might be nearing completion already. Of course there will be additional features that need implementing and I'm sure the code can be trimmed a bit. More to follow about further testing.

No comments:

Post a Comment