Scripting is part of a game engine that makes
This semester (Spring 2017), I and my teammate, Jonathan, have been implementing our little tools to deal with scripting in Maya for USC’s game engine, PrimeEngine. This is a class project for Game Engine Tools Development. For the first time, we have no experience using Maya (except Jonathan), implementing tools in Maya using Python (it bites hard) and implementing scripting. But in the end, we have some clues how to do all of those.
This post is made as my dev blog, so I can remember what I made and how I made things in school or personal project. And maybe this post will be useful for someone who has no idea how scripting implemented and/or want to implement one.
I must note that in the class, we have 3 same things but with different approach and implementation. So this is not a perfect scripting ever. But it’s good to have an idea for one.
Here are some videos that show our current result of our visual scripting.
The Game Engine
The game engine that we use here is minimalist features engine compare to Unity3D and Unreal Engine (or any engine out there). It has at least Rendering, Event/Messaging System, partially Networking and also partial Lua integration (for pass value from a file into PrimeEngine).
So, if we’re planning to have a game with physics, we need to jump into the engine code and create/integrate physics engine for the game. I believe no one wants to do that, except the one who is really one to learn how a game engine works and implemented (like me). In other words, it’s good to have PrimeEngine if you want to learn and focus and game engine. I know some Studios here have their own custom engine, so learning from PrimeEngine is very valuable here.
Big Picture of the System
The diagram shows the big picture of the system. Mainly, the system has three layers in it: Maya, Python Modules, and the last part is the Game Engine Core (which consists all C++ and all runtime-related content).
The first layer is where we built all tools on top of Maya. Why Maya? Since PrimeEngine doesn’t have its own level editor. Our professor built tools in Maya to create assets and levels, then export them to PrimeEngine. In this layer, we add more tools supporting Visual Scripting, like Struct Editor, Node Editor, and Level Node Editor. Struct Editor is an editor for creating struct for certain type of object. Node Editor is visual scripting editor for creating logic for a struct, which means that the Node Editor is related to a certain struct. The last one is Level Node Editor. Level Node Editor is actually same as Node Editor, except it’s for creating logic for the entire level or scene instead of on certain object.
The second layer is all python modules that help to export or convert all generated files from Maya (in the first layer) into game-ready assets or files and for some files we can do the opposite way. In this modules, we have various modules, like Lua Generation, Struct Generation, Struct Reader, CPP Generation, Blob Writer, and Exporter. Lua Generation will generate Lua script from both Node Editor and Level Node Editor. Struct Generation will generate JSON file which is as a representation of struct definition. Struct Reader is a module that read a JSON file generated by Struct Generation and uses that as for other module and for Maya, such as filling the attribute for an object in Maya scenes. CPP generation will generate C++ class for a struct from struct definition file. Blob writer will write binary blob file of an object in Maya scene that has a struct in it. The last module is Exporter. The exporter is usually used to export all assets in Maya into the game, but in this focus, the exporter will export a script that determines which blob and struct the object used.
In the last layer, we have our engine core. In this layer, PrimeEngine will use all generated files by the second layer and used inside the runtime.
You can think about “struct” in C++ definition that consists variables and functions. But here, we focus to create a struct with only variables. Struct editor is an editor built on top of Maya to create this kind of C++ struct. Struct itself will be saved as a JSON file, so it can read easily back and forth to and from Maya.
The editor is a very simple editor. We can add, delete and modify variables inside the struct. Variable can be a float, int, bool, string or Object ( a basically reference to an object in Maya scene). Once created, the variables of the struct will show up in the properties window of the object where a struct is attached.
Struct is added to the Maya object by adding struct definition (struct name, variables, version, and package) into Maya attribute. Maya has the ability to add any attribute to Maya object/node (For more info Maya addAttr) . Once we added that to Maya object, we can see the attributes under extra attributes. The attributes and its value also saved into Maya file, so we don’t need to worry about saving and loading attributes.
In our struct definition, we have “version” (you can see that in “Struct Definition” image before). This version is used to check if the struct in Maya object has a different object or not. If it has, it will update attributes, by adding, deleting and modifying attributes.
Once we set up everything in the scene, it comes to export all object and run the scene inside game runtime. Before we go to exporting struct, it’s good to know what representation of struct inside C++ engine code. Basically, all struct in Maya will be used by Header and CPP generation module to create the C++ struct. See figure below. That is the one example of Knight struct we used before.
Now we have that on the Engine side, we can export struct in Maya object, into a binary blob. We use binary blob because we can easily convert the binary into a struct. The format for the binary blob is <8 bytes id>. The first 8 bytes are used for ID to determine which struct we should use for the binary blob.
Next, in part two, I will continue to explain how we create Visual Scripting and Integration with PrimeEngine.