In our game, we have decided to use LibGDX-AI library for its behavior tree. One advantage of this library is that it comes with a custom text format to easily create and load behavior trees. Even non programmers can edit those files.
Here’s a simple definition of the text format :
The behavior tree text format recognized by the API is a simple and versatile indentation-based format to load behavior trees from an external resource (usually a file) in a data-driven programming style.
I thought of using that text format (that I name .btree like they do in examples) to store behavior trees as assets. However, I want jMonkey’s asset manager to be able to load those custom assets, mainly because it deals perfectly with already loaded assets, i.e. it doesn’t load the same asset twice.
I thought I could implements the Savable
interface, code the read
method and code the write
method but it won’t work as it saves key-value data. It would only slow down the process of loading the trees and make it hard to edit manually. Also, I don’t want the behavior data to be changed by the exporter and importer.
All I need for LibGDX-AI is a Reader
of the asset. I finally found out that I could do it with the registerLoader
method from the AssetManager
and create our own loader.
package com.chevreuilgames.retroflashyrpg.assets.loader.behaviortree;
import com.badlogic.gdx.ai.btree.BehaviorTree;
import com.badlogic.gdx.ai.btree.utils.BehaviorTreeParser;
import com.chevreuilgames.retroflashyrpg.assets.AssetType;
import com.jme3.asset.AssetInfo;
import com.jme3.asset.AssetLoader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* The <code>AssetLoader</code> for LibGDX-AI's behavior tree text format.
*/
public class BehaviorTreeLoader implements AssetLoader {
public static final AssetType ASSET_TYPE = AssetType.BEHAVIOR;
@Override
public Object load(AssetInfo assetInfo) throws IOException {
BehaviorTree tree = null;
InputStreamReader in = null;
try {
in = new InputStreamReader(assetInfo.openStream());
BehaviorTreeParser parser = new BehaviorTreeParser(BehaviorTreeParser.DEBUG_NONE);
tree = parser.parse(in, null);
} finally {
if (in != null) {
in.close();
}
}
return tree;
}
}
However, still one problem perists :
Important: Unoptimized external model files (.mesh.xml, .material, .obj, .mat, .blend, etc) are not bundled by the default build script into the final game builds in the dist directory! If you or your customers try to run games containing code that loads non-.j3o models, you get a AssetNotFoundException Runtime Error (resource not found). Your final application code should only reference .j3o files. – Note that your developers will not get this runtime error when running development builds straight from the SDK.
Does this mean that my custom asset extension, which is not a .j3o, will be omitted?
Also, does implementing the AssetLoader
interface and coding the load
method make the asset be loaded and kept in memory only once?
I’d also like to make the behavior tree implements the CloneableSmartAsset but I don’t want to change the source Is there a way around this?