[Submitted] Generic Procedural Content Management

Threads related to Google Summer of Code
Post Reply
Posts: 3
Joined: Mon Mar 26, 2007 9:37 pm
Location: Florida, US

[Submitted] Generic Procedural Content Management

Post by Tachyon »

EDIT: Revised as of 3/28 to match current proposal and status (submitted). Most up to date proposal or project status can be found here: http://my.fit.edu/~dnickers/GSoC/

Okay, I'm new here and I just recently (like last couple days) heard about GSoC and realized this could be a really awesome summer opportunity for me -- and fun too! (I'm currently searching for summer employment.)

Generic Procedural Content Management (GPCM)
(An Extensible Scripting Language for Arbitrary Algorithms)

This project intends to implement a plug-in for OGRE for generic management and execution system for arbitrarily complicated procedural algorithms. This will be accomplished via a scripting language with features including local variables, loops, conditional logic, and calls to other script functions and with bindings to properties of several internal classes such as ExternalTextureSource and SceneNode which will expose useful parameters for procedural modification. The system of classes (including a script ResourceManager) can be easily extended by inheriting a ScriptElement base class and providing the appropriate implementation. At the end of this project I intend to implement as many primitive ScriptElements as time allows and create a small demo showcasing the functionality.

Procedural content is roughly defined as content created with little or no intervention of a human artist, automatically and consistently, but with a certain degree of randomness. Such "random within bounds" behavior can easily be extracted from simply mathematical constructs such as fractals, but also with various noise functions or even complex AI routines.

OGRE has a nice management system in place for meshes, materials, shader scripts, etc. - however procedural content (whether pre-generated, on-load, or real-time in origin) is a blooming area with respect to it's integration with OGRE and (I am aware) there are currently proposed GSoC projects in this area. From what I've seen, concentration has been on application of procedural concepts (noise generation, fractal concepts, etc.) to specific problems - for instance, distributing trees to form a forest, or generate a city-scape -- landscaping in general, fractal-patterned textures, etc. However, I think a more abstract approach is more useful since it can then be applied to those problems as well as any other problems of that type. Naturally the more abstract features and concepts added to the tool box - the more TYPES of problems can be solved easily.

Extending the example above: why not place any object (scene node) onto a surface (or better yet a pre-defined region on space)? One can imagine a simple density map (2D image, or density function - 3D or even parameterized in time) such that placement of objects in the field match (to within random variations) the desired density distribution. Be these objects trees, buildings (or procedurally generated trees or buildings), or perhaps asteroids in space, leaves on a tree, flowers in a large bouquet -- it doesn't matter since we've abstracted away "what" each object is. Similarly, even the placement function (i.e. density map, noise generator, etc.) can be abstracted using listeners and delegates for example. Going to an extreme case, we want to script generic behavior of generic entities using generic parameters and user defined functions. Of course this definition of the problem is too general, but you can see where I'm going: Just as the type of object should be generic, why not the parameters we procedurally specify too? For example, instead of position (X,Y,Z) -- why not orientation (rotation about an arbitrary axis)? - what about material parameters - make the object more or less reflective, change it's texture based on a procedural event, make it transparent or partially transparent as a function or time -- or any user defined function!) -- what about particle systems adaptively changing based on procedural functions -- I realize there may be a little overlap in what I'm talking about here and particle systems) -- heck - even a substitute a coefficient within an existing script, such as a shader program, etc. Clearly, the possibilities are virtually endless.

The interrelation of all these possible entities, functions, and parameters ("Management") is of course key to the success of such a system. Hence a resource management and scripting system are in order.

The scripting language should be rich enough to allow the author to perform many types of procedures (like those mentioned above), while still providing an easy way for extensions to the language bindings written in the underlying C++ when a developer wants to write more complicated functions or use an existing library or plug-in. The former will be accomplished through language features including: local variables, types, conditional statements ("if" for example), and loops (basic "while" and "for" for example) and a core set of "primitive" types (int, float, vector, image, ... ) and functions/values which bind to OGRE classes' properties (for example the position vector for a SceneNode). The latter (extensible bindings) will be accomplished by providing an abstract base class from which a developer would have to implement a set of functions such as getValue() or execute().

-I'll look into the OGRE script compiler system and see if it's more useful to re-use that code as a basis for this parser or to write my own. Also, using Lua could be a possibility if we need that much power.
-Will investigate the implementation of OGRE resource classes such as texture, material, etc. to see if .reload() will allow dynamic update of procedurally generated content, or if I'll need to devise a way to make that happen. If they inherit ManualResourceLoader than it may not be an issue. Most OGRE core classes from what I've seen have a .createXXX() function so generating content from scratch should not be a problem.
-I will look into more white papers and other technology describing documents in the procedural generation field to refine the exact features that would be most useful to the community. (Note, I'm already working on this currently.)
-I'll delve into the OGRE code to see if existing things like Controllers may work for what I'm intending to do. From what I gather they can only take 1 parameter and can't generate new content, but have a similar purpose to this.

This will likely be a plug-in if no modification of OGRE's internals is necessary (and it probably won't be).

The first stage of development will be the framework of abstract classes (and some not abstract) for managing, parsing, and executing scripts.

Class ProceduralScriptResourceManager : ResourceManager, Singleton<ProceduralScriptResourceManager>, ScriptLoader, ManualResourceLoader
Implements loading, unloading, reloading of scripts, parseScript() function, and getSingleton functions
Parses (splits) the scripts at the highest level and instantiates the appropriate ProceduralScript objects logging errors as necessary
Classes ScriptElement, ScriptFunction, ScriptValue -- all base classes defining appropriate contracts for sub-classes
Classes ScriptLoop, ScriptConditional, ScriptExpression, ScriptOperator, etc. -- as needed depending on the core supported syntax of the language
Class ProceduralScript
Encapsulates a list of ScriptElements of the script (local variables and executable elements)
Implements a static createScriptFromParse(string) to be called from the ResourceManager which acts as a factory function to instantiate a callable script
Provides the top level execution strategy - calling referenced scripts, and (in general) delegating execution of more atomic commands to the corresponding ScriptElements

The bulk of the work (after lying down the abstract framework) will then be binding various parameters within OGRE to scriptable elements. Perhaps (although I've not explored this thoroughly yet) I would inherit the ControllerFunction and ControllerValue classes and provide dynamic execution (loaded from scripts).

Provide a specification (start out small at first) of which OGRE types (or rather which changeable properties of OGRE classes -- i.e. X, Y, Z of SceneNode, R,G,B of fog color or diffuse light, etc.) are allowable "procedural parameters" (ScriptValues) -- i.e. what can be assigned to by a procedural function and probably the acceptable value ranges -- i.e. X,Y,Z can be negative whereas R,G,B for a color cannot).
Implementation classes for various ScriptFunction and ScriptValue -- as many as time will allow
Each will implement .execute() (functions) or .value() (value)
Some will bind to basic types commonly used in procedural scripts - int, float, Vector, Matrix, RGBColorValue, 2DTexture, ...
Some will bind to certain OGRE class properties via "getters" and "setters"
Write the execution control functions - starting with loading a primitive, executing a single primitive (hence write all primitive execution code first) and working up to a generic .execute() command for high level (composed) procedures.

Also, elements of the library (or perhaps just the script resource manager itself) will probably inherit ExternalTextureSource since at some point in the execution (probably at the end) a resultant image will be applied to a material.

It may sound like we're writing a generic scripting engine for all of OGRE (and with enough extension, it could be quite comprehensive), but in general we're concentrating on aspects (parameters and functions) that are applicable to procedural content generation.

Development Style:
I propose to use a contract-based "interface -> implementation" approach with well documented code, syntax styles, programming pattern use, etc. all consistent with the current OGRE code-base. A top-down approach will suffice at first to layout the basic abstract constructs and once they are implemented (skeletally) then "work chunking" can proceed with the addition of each ScriptElement. In theory the more time allows, the more parameters and functions can be implemented. Consequently development beyond summer 2007 can continue in such a linear fashion or even concurrent development on other primitives, etc. is possible with little interference (the base classes should abstract dependences away).

In short:
-A small library of classes which implement dynamic loading, and execution of so called "procedural scripts"
-A syntactic and semantic definition of the procedural scripting language as well as an implementation of the parser for it.
-The features of the script language, parser, and execution library are defined (largely) by the primitives that the system will support. Several simple primitives will be supported at a minimum - enough to do simple texture noise and placement of objects on a height-mapped terrain based on a simple 2D density map - since these seem to be a common application of procedural concepts. Naturally, more primitives can be implemented as time allows to provide the system with more functionality.

--Class ProceduralScriptResourceManager
--Classes ScriptElement, ScriptFunction, ScriptValue -- all base classes defining appropriate contracts for sub-classes
--Classes ScriptLoop, ScriptConditional, ScriptExpression, ScriptOperator, etc. -- as needed depending on the core supported syntax of the language
--Class ProceduralScript -- central class representing a script and controlling high-level execution
--Many implementations of ScriptFunction and ScriptValue each providing new types and bindings to the script. The first few will be very necessary primitive types - like int, float, Vectors, etc. and basic bindings such as to SceneNode.Position vector or a texture's bitmap. More time will allow for addition of more and more of these "base features".
--Documentation of all the above (in code as well as some "user" doc. - probably PDF and/or Wiki articles)
--A demo showcasing the available features as of the last few weeks of the project. (I.e. more script elements can be implemented in the future. The demo will only use the features available as of - say - the Aug. 1st timeframe).
--(Optionally depending on user demand and time available)
A visual editor tool, probably with graph-like interface each node representing an input parameter (image for example), a procedural pass / function, etc. -- all implemented with ScriptElements in the backend, of course. A real-time OGRE preview upon which users can apply the given procedural output (whether it be a mesh, material, or simply texture image or number).

Now until May – concentrate on classes, but refine the exact definition of the project details. Work mostly with my mentor and the very active and helpful OGRE community to see exactly what is already out there and how this project can be leveraged to compliment others’.

Weeks 1 – 2: Lay the ground work for the abstract classes – define the basic operating parameters of the system and syntax for the language.

Weeks 3 – 6: Implement the core system's classes – including the ResourceManager, the high-level parsing routines (i.e. no primitives are defined yet), and the basic execution framework. At this point the base classes as well as the abstract interface classes should be fully designed such that script elements can now be incrementally written.

Weeks 7 – end: Implement primitives (inheriting from and implementing ScriptFunction or ScriptValue accordingly) and bind to commonly used OGRE values (i.e. textures, SceneNode position, etc.). Repeat for as many primitives as time allows.

Note: a “substantialâ€
Last edited by Tachyon on Thu Mar 29, 2007 4:33 am, edited 1 time in total.

User avatar
Posts: 465
Joined: Fri Mar 10, 2006 10:22 pm

Post by Aladrin »

Actually, procedural content can have an artist involved. There's really 2 kinds of procedural content.

You described the first... Random/pseudo-randomly generated art including textures, terrain, cityscapes, etc.

The other involves an artist directly, but solves some other problem such as bandwidth or diskspace. When an artist makes a texture, they go through certain steps in a certain order to make it. Instead of storing the final result, you store the steps. Take it a step further and you can not only optimize the steps needed, but allow changes to any step and have the final result show the change made. See MaPZone for an amazing example of this. .werkkzeug1 is also a great example.

Posts: 3
Joined: Mon Mar 26, 2007 9:37 pm
Location: Florida, US

Post by Tachyon »

Sorry, I didn't mean to completely remove the artist from th picture, but lower dependance on the artist is what I meant.

Actually, I'm basically thinking of the same concept you describe -- the steps involded in the procedure are just reflected as lines od script code. In fact I didn't mention but perhaps another type of primative I should consider is "seed" image and meshes upon which tweaks are made prodecurally. I suppose the way I described it includes this idea - I just didn't want to get into too much detail about all the possible configurations.

I also though about an editor (not a script code editor - but a visual editor) much like the one which was shown in (I think) .werkkzeug1

What I remember is a very logical diagram representation of the procedural steps in a top-down arrangment and each node (essential a function from what I gather) connected via lines. It also had built in preview so you could modify the procedure and see the change in real-time. It is a great idea for procedurals creation (note not the pocedurals generating content - that actual writing of the procedure itself - lol) for artists along the lines of the partical editor Add-On.

In the end I figured althoug it'd be nice I don't think I'd have the time for an editor - plus there are some things that could be extended as such (like GOOF??) assuming the procedurals management system is already in place.

User avatar
Posts: 67
Joined: Thu Sep 21, 2006 9:51 pm
Location: Seattle, WA (USA)

Post by aeyr »

This would make an interesting plugin, but I don't think it belongs in the core at all. There are other packages out there (allegorithmic's for instance) that people may want to use instead/in addition to.

Posts: 3
Joined: Mon Mar 26, 2007 9:37 pm
Location: Florida, US

Post by Tachyon »

Perhaps you are right - this could be a plugin too I suppose. But in theory it would allow people to use their own packages -- assuming a primitive for user defined generator functions is implemented. It would simply allow that function to be called from within a script. So, for example, they could add a listener or 2 (their package's functions) to the script engine which will later call their custom function whenever a point, int, 2D image of specified dimension, etc. was required by the executing script. Then, in theory, they wouldn't need to recompile anything - simply tweak the procedural script.

Obviously, this requires a bit of consistency when initially "wiring up" the function calls and what not so that (for example) the bitmap passed from one to the other is the right type, the correct dimensions, the right color depth, etc. Once the mapping between script functions and user defined functions is implemented, then the script just becomes a high-level interpreted language that can be leveraged to easily make changes to the procedure - even real time parameter variation based on things like time.

All this however is a bit high level and at first I'll only implement the most basic of primitives -- and perhaps near the end have time to define a generic framework for adding user defined delegate functions.

Post Reply