KEEYAH – A Procedural Ninja

So about a month ago I was messing around with mesh to mesh UV projection (topic). The results of which was the creation of a really simple throwing star. In addition to the projection methods I was using the GPU to generate sections of my textures including the normal mapping from a black and white image. One thing led to another then eventually I had all the making to start putting a simple game together. Initially I wanted to do everything asset-less, which I was able to do except for the audio which I have a method worked out for (that’s another topic) but for the time being is just not time effective and so was excluded from this project.

The first step to all of this was to start putting together the assets, then come up for a system to “toss” objects (topic). Initial tests with the physics were highly successful and have the ability to be slightly modified to accommodate different game types like Cornhole, Baseball, or Discgolf. The decision was to go with throwing stars cause who does not like to pretend they are a ninja. After I had a basis for what I was going to create the next step was to set up a structure to process through a “stack” of scripts that would create my assets and serve them to a container object to control everything. This meant I needed to come up with a structure for what defines an asset which I also used to contain the texture generation methods. The ASSET class ended up looking like this:

class ASSET{
		this._parent = parent
		this._ready = false
		this._dirty = false
		this._done = false
		this._compileMsg = "Creating Asset"
		this._asset = null			
	/*---- Toggles ----*/		
	isReady(){this._ready = true}
	isDirty(){this._dirty = true}
	isDone(){this._done = true}	
	/*---- Functions/Methods ----*/	
	static GeneratorVS() { ... }
	GenerateGPUTexture(name, fx, returnRTT = false, defines){...}
	GenerateGPUNormalMap(sample, invertDepth = false){...}
	/*---- Getters ~ Setters ----*/
	get parent(){return this._parent}
	get ready(){return this._ready}
	get compileMsg(){return this._compileMsg}
	get ready(){return this._ready}
	get dirty(){return this._dirty}
	get done(){return this._done};
	set asset(a){this._asset = a}
	get asset(){return this._asset}
	get scene(){return this.parent.scene}		

With this structure I was able to then Extend the class out over several other classes to pre-generate my assets, and example of one would be:

class SCENE_MATERIAL0 extends ASSET{
	constructor (parent) {
		this._compileMsg = "Generating Main Scene Material"
		var mat = new BABYLON.StandardMaterial("Scene-Material0", this.scene);
		mat.diffuseTexture = this.parent.assets['Scene-Texture0-Color'];
    		mat.specularTexture = this.parent.assets['Scene-Texture0-Specular'];
    		mat.specularPower = 32;
    		mat.bumpTexture = this.parent.assets['Scene-Texture0-Bump'];
    		mat.emissiveTexture = this.parent.assets['Scene-Texture0-Emissive'];    		
	    	this.asset = mat;

Each asset could also have a callback for once its compiled which is handled by the main container object after the asset was marked as ready. Here is a section script from the main container that handles the assets:

	var _a = this.assetStack[0]
	if(_a.ready && !_a.done){
	    this.msg = _a.compileMsg
	        this.assetStack.push(new className(this))
		if(asset.asset) this.assets[] = asset.asset				
		if(asset.callback) asset.callback(asset)

What this breaks down to is a simple array of Asset objects that the system checks the top one in the stack and sees if it is marked complete, if so it drops it out of the stack proccess a callback if needed then moves on to the next Asset in the stack. The only thing that I needed to make sure was that my last asset (which ended up being event bindings) fired a callback to tell the scene its time to proceed to the welcome screen. Once that was done it was more or less just linking everything together.

Some of the notable parts of this project where:
– Flick Input Visualization Shader
– Simplification of Touch Input
– Curving Throws
– In Scene 3D Text Popups
– Procedural Textures (GPU Generated)
– Procedural Meshs
– Normal Map Generation from Procedural Black and White Heightmaps (GPU Generated)
– Asset Handling System
– UV Projection Methods
– Dynamic Background Shader

When I get more time Ill write up more on it. For now why don’t you head over to the game and try a couple tosses. If you have access to the console feel free to type toss.buildStage(#) and what ever level you want to play. Eventually I will be dropping that out as I add level progression scripts. There are plans to add “balloons” as well that will multiply your tosses score. All and all this was a cool side project and should have more added to it as time goes on.