An Environmental Pipeline in MaxScript
In this technical article, Sony Online's Thornblad explains and makes available his 3DS Max function library and tools, a light mapper and polygon unwrapper, originally created for MMO PlanetSide.
![](https://eu-images.contentstack.com/v3/assets/blt740a130ae3c5d529/bltba62518415cda0e2/652fe6ddbc479f8697ef691f/default-cubic.png?width=1280&auto=webp&quality=95&format=jpg&disable=upscale)
[In this technical article, complete with free-to-download tools and scripts, Sony Online's Thornblad explains his 3DS Max function library and tools, a light mapper and polygon unwrapper, originally created for MMO PlanetSide.]
Nearly eight years ago I moved to St. Louis, where SOE had established a small satellite office, to work on a new game project that was still in the research and development phase.
It was to be a massively multiplayer online first-person shooter, or MMOFPS, on a scale beyond anything I had worked on before. Because of this, it was going to require strong organization and efficient processes in art development.
I had been using MaxScript in personal projects for a year or so, but my knowledge was pretty rudimentary and limited to little more than macros for accomplishing repetitive tasks. The needs of the project presented an interesting challenge that inspired me to spend many late nights teaching myself the 3ds Max scripting language in depth.
When I started work on PlanetSide, there was a basic engine up and running with terrain, skies, objects, and characters. All these components would undergo a great deal of work over the next three years, since they were in fledgling form, but two main graphics components were completely missing.
At the time, there was no graphical user interface and no component for handling building structures and interiors. I was approached to help with R&D on the latter portion. This grew to become my focus on the art and tools side for the majority of my time on the project.
Old Dog, New Tricks
The original intention for construction of building interiors was to use QRadiant, a popular level building tool of the time, because there were a couple of level design enthusiasts on the project who were familiar with the program.
The problem was that the output was a rather messy collection of triangles in a hierarchically arranged format called a BSP tree. BSP (binary space partitioning) trees were useful for interior level-based games such as Doom and Quake because they represented all of the environmental geometric data and were suitable for the graphics hardware available at the time when those games came out.
In a massively multiplayer game, however, the interior levels needed to be seamlessly connected to a larger world represented by a different set of data. Since the BSP tree data was useless, it would need to be converted into geometry.
But because the process that generates the tree splits polygons, the resulting triangle count would be much higher than was needed to represent the model and thus be very inefficient. As an R&D test, I was asked to reconstruct a model in 3d Studio Max that was originally built in QRadiant.
Here is a selection of hallway block pieces put together using a custom move tool in the Planetside editor. (click image for full size)
Creating the model was a simple enough task. It was a matter of matching existing high polygon geometry with a lower polygon representation, similar to building an LOD (level of detail) model.
The main difference is that since the high polygon version was "high" only because triangles were unnecessarily split (a result of the BSP, not artistic decision making), there was no reason to expect the new model to be of lesser quality than the original.
The more challenging aspect of the test was to create the light maps, or textures that represent the static lighting in the scene. This was the most common method used to represent interior lighting back then, but level design tools generated them internally using placed lights. We needed to be able to create the maps in 3ds Max. Fortunately, a little web research turned up a plug-in for 3ds Max called Luminaire.
Luminaire was a radiosity-lighting plug-in designed primarily for architects who wanted something closer to real world lighting than what was available in native Max, but it also had a feature for rendering light maps that proved very useful. The mapping coordinates used for generating light maps are normally unwrapped automatically inside the level building tool, but they had to be created by hand for the R&D test.
Lighting was done inside 3ds Max using standard omni and spot lights, then rendered via Luminaire into texture maps similar to the ones that had been produced for the original model in QRadiant.
The result of the test was a model of a building that looked as good as or better than the one produced in the level design tool, but using approximately one-tenth of the number of triangles. The caveat was that the process took considerably longer than creating levels in QRadiant and needed to be made a lot more efficient or it couldn't be used in full production.
Automated Unwrap
The first step toward improving speed involved the unwrapping of mapping coordinates for light map rendering. This needed to be as automated a process as possible. Expecting artists to generate by hand a second set of efficient mapping coordinates for every piece of static geometry in the world is asking for trouble - both for scheduling reasons and for my personal well-being!
In old-school level design tools (and many recent ones), all the environmental geometry is made of primitive convex objects such as boxes and cylinders and spheres. The tools merge them, cutting away the unused and unseen portions, and at the same time generate mapping coordinates.
Because the starting geometry is simple, the results are somewhat predictable. Our modeling needed to be done entirely in 3ds Max and the triangular mesh results were anything but!
We needed an unwrap procedure that would generate efficient results and be simple to use. Full automation was a bit much to ask, considering the complexity of the geometry we were working with, but I wanted to get as close as possible. The result of that effort was a mapping tool with a few handy functions and an automatic unwrap function.
Snap-Together Interiors
Another issue that needed to be addressed was the efficiency of drawing complex interior spaces in the game. Although the triangle counts of hand built geometry was going to be considerably more manageable than what would be produced by a level design tool, it was certainly not negligible.
The proposed solution was to use a manually set up portal system. Interior spaces would be broken up into rooms that could be connected together via their doorways. Simple geometric objects would be constructed to represent every door and window and others to represent the space that could be seen through them, to which the actual visible geometry would be linked. All of this was to be set up by the responsible artist and named according to a strict convention.
The amp station from Planetside loaded into the editor with the red split showing the building with light maps/textures. (click image for full size)
Interior spaces would therefore be intricate networks of geometry that had to be prepared with extreme precision. Since naming the objects correctly seemed to have tremendous potential for error, my plan was to write a script that would auto-rename everything that had been assembled based on placement and a few math functions. Eventually, that script turned into a methodology for how the interior geometry was to be constructed and set up using pre-fabricated building blocks.
The decision to build interior spaces out of pre-fabricated parts had implications for our tool set. It became clear that keeping track of the numerous models populating the world was going to be a headache. Also, we needed some form of source control. Multiple artists were working on various parts of the same space and we needed a way for them to do so without stepping on each others' toes.
We were using SourceSafe, but although many coders swear by it, I found it to be somewhat unreliable for data tracking and from a script writer's perspective it was difficult to automate the checking in and out procedures. This prompted me to think in terms of making a more ambitious scripted application that would guide the whole process and keep track of assets rather than a series of individual unconnected scripts.
I wanted a tool that would organize and track assets (models and textures), generate thumbnail images, help with the assembly of interior spaces, rename portal objects according to our convention, assist with unwrapping mapping coordinates and rendering light maps, and export all of the data to the internal format used in the game. The next step was to decide how the data would be stored and retrieved.
Model Database
At first, I intended to simply use 3ds Max files and make the scripted tool control how they were saved and organized. However, I soon realized that I was going to need direct access to the information within the files in order to make certain parts of the process work effectively.
Additionally, file size and access speed became a problem, and after a few tests I found that saving basic data to a customized format and reconstructing the models in the current scene was both efficient with disk space and could be accessed very quickly.
This method also avoided a problem with the merge function in earlier versions of 3ds Max. Usage of the function required user input in a number of different situations and the whole point was to automate as much as possible. A "quiet mode" parameter was later added to MaxScript in order to address the problem.
I needed to create a custom format, but I wanted to make it something generic that could easily be changed to suit any kind of data that exists in the 3ds Max application. As I learned more about MaxScript, I found that it makes use of a generic struct data type that was perfectly suited to do just that.
After quite a few late nights, I managed to create a tool that acted as a game model database. Adding a new model involved setting it up according to a few rules, including the linking of untextured geometry that represented either portals or collisions or attached effects, and then pressing a button that would automatically categorize the model, generate a thumbnail image, and save its data to a generic, intermediate format.
Multiple copies of each model were kept and could be retrieved if necessary, providing a rudimentary form of source control. I gave the scripted tool a silly name, BlockHead, for its use of building blocks for construction.
Over several months, BlockHead functionality was my focus and I added nearly all of the features I had envisioned, thanks to 3ds Max's powerful scripting language. I contacted the programmer that had developed Luminaire and he graciously obliged me on a number of feature requests, including MaxScript support.
It would have been impossible to automate the lighting process otherwise. Automatic renaming of objects according to our convention and calling an external export application to get the data in final game format became part of the save procedure.
Over the length of two expansions of PlanetSide, BlockHead was given several overhauls and a complete rewrite and renamed ConMan, short for Content Manager (pictured below). The rudimentary source control was replaced with direct support for Perforce through a proprietary 3ds Max plugin.
A search function with wildcard support was added for navigating the database, as was more robust lighting functionality, including a feature for mixing a weathering pattern into the light maps for models on the terrain.
In 2008, I officially released a library of 3d Studio Max script functions to the public. The unwrap functions and a sample tool are part of the release, as are the math functions used in the portal linking procedure, but without an example. The functions for loading and saving generic struct data as well as the functions for rendering light maps are provided along with sample tools for both.
You can download the library directly from Gamasutra here, or visit the author's site to download it here.
Read more about:
FeaturesAbout the Author
You May Also Like