AI Dev-Log 3: NPC Definitions Part 1

Goal: To create a simple resource that contains multiple definitions and configurations that can be easily loaded into Godot.

Means: A specific format with reserved keywords.

Specification:

The file will be a GDScript extending Resouce as follows:


extends Resource
class_name NpcDefinitions


We now need to convert these nodes:




To a plausible data based representation, as these can and must be created from code. (Note that while the Stimulus [Signals] nodes have been updated, the inhibitors and actions have not).

For these, we will continue and add two dictionaries to the script, these will be our keywords:


 var _functions = {}
 var _stimulus = {}

In this case, the _ indicator will let us identify easily if something should be changed or edited.


And this becomes more obvious as the code progresses. We need to be able to create functions and signals (stimulus) only using this script, so there will be quite a few obligatory fields

 var _functions = {
    "function_name" : {
        "_category" : "Inhibitor/Action/Misc",
        "_code" : "<actual code>",
        "_input_ports" : [
            {"_label_title":"title","_type":TYPE_NIL},
            {"_label_title":"title2","_type":TYPE_NIL}
            ],
        "_output_ports" : [
            {"_label_title":"title","_type":TYPE_NIL},
            {"_label_title":"title2","_type":TYPE_NIL}
            ]
    } 
}
var _stimulus = {
    "signal_name" :{
        "_output_name": "name",
        "_output_type": TYPE_NIL
    }
}

This is a preliminary approach, and ideally you only want one input and one output in all functions, but that would limit signifcantly the kind of functions you can create.

You can see i used TYPE_NIL as a placeholder, this is actually valid in GDscript, it's the global id of the Null type. This works with all integrated scripts we need or want to use. But what happens with classes and objects we define and need to represent on our behavior trees?

We're gonna add a little piece of code that will allow us to get that right, that's class definitions, for example:

 var CLASS_CHARACTER =  {
    "_color" : Color(.5,.5,.1,1),
    "_object_type" : "Character Entity",
    "_variables" : {
        "translation" : TYPE_VECTOR3,
        "target_location" : TYPE_VECTOR3}
    }
As you may guess, the CLASS_ prefix is also a keyword, it will allow us to identify if a variable inside this script is in fact a CLASS definition. "_object_type" contains a more human friendly identifier for the class if needed and can be used for comparisons.