Clearing the first hurdle: Python Asset Builder
Hello! I‘m Mike Cronin, a programmer writer with the Lumberyard documentation team. I’ve been a long time game developer, going all the way back to the days when arcades were still a thing. I’ve worked as an artist, animator, technical director, and as an engineer (of sorts). One aspect I like best about working with the Lumberyard documentation team is diving into new features and learning how they work.
Today, I’d like to discuss one of Lumberyard’s latest features: the Python Asset Builder.
Why is that? Let’s start with an old-timer’s story…
I remember sitting in a meeting with a small team of engineers, artists, and UX designers, hashing over a design spec. We had an expensive piece of custom hardware that was three generations behind, a barely beta operating system, an SDK that was not much more than a wrapper for a graphics API , and a blue-sky design that would have been difficult to implement under better circumstances. The team was combatively debating the design spec, hardware and software capabilities, and what was possible.
One of the designers blurted, “It’s a COM-PU-TER! We can make it do whatever we want!”
While I appreciate the sentiment, our ability to make the computer do whatever we want has many obstacles. With real-time 3D, the first hurdle can be the tallest: specifically, getting source data into an asset the engine can use. When the first generation of 3D capable game consoles hit the market, assets were small and simple. An asset could have a mesh, a vertex cache, a set of vertex colors, and a set of texture coordinates. If you were on the cutting edge of technology, you could add skinning information: a staggering two weights per vertex, and a rig with up to a few dozen joints. A modern game asset is far more complex and can easily contain hundreds of times as much raw data. Though exporters and file formats have mostly kept pace with hardware advancements, developers have resorted to all sorts of clever tricks to get their data into game engines; sometimes circumventing the limitations of their asset pipelines, or more often, doing things the hard way just to get it done.
In an ideal scenario, an asset pipeline wouldn’t assume that the data someone wants to visualize comes from one of the usual modeling or animation packages. It wouldn’t expect that the data conform to an industry standard intermediate scene format. With growing interest in game technologies for non-gaming applications, developers will need to be able to parse data from more general purpose formats such as JSON, CSV, HDF5, and even databases. The complexity of data and modern game assets creates additional overhead in the process. Progress has been made enabling developers to create higher quality content faster, but developers also need more flexibility getting their assets into the engine.
The recently introduced Python Asset Builder Gem for Lumberyard is an important first step on this path. I might be biased because I have spent a lot of time writing exporters and trying to crowbar data into game engines, but I think this could be one of Lumberyard’s most forward-looking features. The tools and processes developers use are often dictated by what their engine can consume and how well their tools can support industry standard scene formats. Python Asset Builder can change that.
Simply put, Python Asset Builder enables the import of data from known file formats and automatically processes it with Lumberyard’s Asset Processor. This opens the door a bit to Lumberyard supporting a wider array of file formats. Python Asset Builder can also save artists and developers a lot of time building complex assets, fixing asset issues as they arise, and can be used as part of larger automated process to generate collections of assets procedurally.
To get a better understanding of Python Asset Builder and consider its potential, we can examine the NVIDIA Blast Gem. At a high level, the process for creating dynamic destruction assets for Lumberyard with NVIDIA Blast is the following:
- Fracture a mesh in Houdini. It’s possible to use other tools, but the NVIDIA Blast Gem currently only provides a pipeline for Houdini. The fracturing is done procedurally with standard Houdini Surface Operators.
.blastassets from Houdini.
- The Python Asset Builder script for NVIDIA Blast automatically processes the
.blastassets, and creates a slice asset. (Specifically, a “blast_slice’ asset.)
- Create an entity with Blast components.
- Create and add a Blast material to the entity.
- Apply a force to the entity and watch the ensuing destruction.
If you try to assemble a Blast asset without the automated processing provided by the Python Asset Builder script, you will quickly understand how useful Python Asset Builder can be. When an object is fractured for NVIDIA Blast, it can have hundreds of chunks of geometry. The script generates an assetinfo manifest to automatically process the chunks and builds a slice asset that can be dropped into a Blast Family Mesh Data Component. Without the Python Asset Builder script, each chunk must be added to the asset processor manually. Then, each processed chunk must be added to the Blast Family Mesh Data component manually. This is extremely tedious and time-consuming. It could take days to assemble a single asset of moderate complexity. Worst of all, iteration is prohibitive without automated processing. If the fracturing to the base mesh is edited, it might change something about the naming or hierarchy of the chunks, requiring manual setup from scratch.
There is an obvious application here with huge potential for improving the speed, quantity, and quality of game asset creation. If you are using tools that can procedurally generate content, you can automate large swaths of content creation and focus time and artistic effort on assets that capture the player’s focus.
Using the past as an illustration, consider Metal Gear Solid 2. Prior to the game’s release, Konami published a technology demo. In one of the demo scenes, there were dozens of bottles on a shelf that would break individually when shot by the player. Mind-blowing technology at the time. As archaic as the demo seems today, it probably took an artist weeks to model, fracture, texture, and animate the destruction of the half dozen or so bottle assets that made up the scene. Tools have improved and we can make these assets more realistic and dynamic today, but the process is still manual for most artists. Recreating this scene in a modern engine with modern assets would still take a similar amount of time, though it would be much more visually impressive.
We can reduce the time and effort and possibly get a much better result combining procedural asset generation and Python Asset Builder. It’s trivial to build a tool that automatically generates bottle meshes. The bottle assets can be textured, fractured and have materials generated automatically. A script that randomizes a few properties can generate hundreds of unique bottles. With small modifications to the existing asset_builder_blast.py script, the bottle assets can be processed and built for Lumberyard. In less time than an artist would spend modeling and setting up a handful of these assets, they could generate hundreds of destructible bottles, and select the best assets from the results.
When you’ve created one process like this, it can be repurposed for other types of assets. Rocks, trees, plants, crowds, animals, insects, wall panels, floor tiles, trash and debris, can all be created this way. Artists spend thousands of hours manually building background assets like these, and there is never enough time, money, or talent available to build as many assets as are required to create the level of immersion artists and designers would like to achieve.
Beyond procedurally generating assets, I would look to Python Asset Builder in any situation where a large batch of assets needs to be processed. It might prove useful for sports games that have huge collections of motion capture animations which require specialized processing. When developing for multiple platforms, I might be able to create different job processes for each platform and maintain a single library of assets. I’d look for ways to automate, as much as possible, all the little things artists, animators and designers are required to do to make their source files game ready. Python Asset Builder should prove particularly useful in those scenarios where an unforeseen change requires many assets to be reprocessed with a minor tweak.
I highly recommend getting Lumberyard 1.27 and investigating Python Asset Builder whether you are in a AAA studio or a lone developer. I am barely scratching the surface of the potential it presents. Python is an easy language to learn and use. With so many libraries available to read, write, and manipulate images, models, audio, and animation, you will likely find some idea that will help you make better games in less time.