Overview
Porting a sentry turret from Portal 2 to Tabletop Simulator as an AssetBundle from start to finish.
Overview
In trying to figure this out myself, I found that there wasn’t a good tutorial on this subject. So to prevent others from having to search forum posts for hours, I decided to put everything I have learned into this guide.
The instructions presented here are by no means the best or easiest way of doing this, but the end result will be a fully animated sentry turret from Portal 2 for use in Tabletop Simulator. This guide should work for any Source Engine model that you want to port.
I am assuming that readers of this guide will have some experience working in the Source Engine, but I will explain everything you need to know. I went into this with no experience at all in Unity or TTS AssetBundles, and you don’t need any either. You are not required to do any modeling or animating of your own since we will simply be porting an existing asset.
Disclaimer
This guide will teach you how to take someone else’s models and put them in a different environment than they were created for. Because of this, you cannot sell your project or profit from it in any way, and any workshop contributions you make must attribute the models to the original author (Valve in this case). Be sure to read Valve’s policies on using their assets before publishing anything. In general you should not have a problem if you are publishing to the Steam Workshop where anyone can access your project.
I am not responsible for any legal trouble you find yourself in after following this guide.
Required Tools
A few software tools will be required to complete this project. You need all of these so I would suggest installing them before you start working:
- Portal 2 (or access to all the sentry turret models, materials, and sound effects)
- GCFScape[gamebanana.com]
- VTFEdit[gamebanana.com]
- Crowbar
- Blender 2.8[www.blender.org]
- Blender Source Tools[steamreview.org]
- Unity 2019.1[unity3d.com]
- Tabletop Simulator Modding project[github.com]
- Tabletop Simulator
Step 1: Extracting models and textures
Source Engine models are composed of several different files. You can read about them in more detail on the Valve Developer Wiki :
- MDL – the base mesh which contains data on the model’s structure, textures, and animations
- VTX – extra information on the model
- VVD – extra information on the model
- PHY – information on how the model interacts with the game world (not required here)
In a file explorer, navigate to steam/steamapps/common/Portal 2/portal2. Using GCFScape, open the file called pak01_dir.vpk. A VPK file is an archive used by Source Games, and is very similar to a regular ZIP archive at a high level.
The files we need are stored at the following locations within that archive:
- models/npcs/turret/turret.mdl
- models/npcs/turret/turret.vtx
- models/npcs/turret/turret.vvd
- materials/models/npcs/turret (extract everything from this folder)
Extract the above files to a folder that you can easily access.
Step 2: Decompiling the models
Blender doesn’t know how to process MDL files because they are in fact just archives of all the parts required for a model. We need to extract each of those pieces and tell Blender how to interpret them.
Sounds like a lot of work, right? Fortunately, the Crowbar tool will do it all for us.
Open Crowbar. Drag the turret.mdl file into the “MDL file or folder” input field. In the “output folder” section, check “subfolder” and input a simple folder name. This will help to keep our project organized.
Leave every other option alone and click “decompile”. If you have all your files in the right place, Crowbar will produce several files in the subfolder you specified. Otherwise, there will be an error saying that you are missing a file. If the operation was successful, you can delete the MDL, VTX, and VVD files since we won’t need them anymore.
If you look in the folder where Crowbar placed the decompiled files, you will see a few things:
- SMD files – these are the individual pieces of the model mentioned previously
- _anims folder – this contains all the animations that the model can perform
- QC file – this will tell Blender how to interpret the SMD files when we import them
You don’t need to worry about any of the decompiled files or what their contents represent, although it can be interesting to look at the contents of the QC file to see how all the SMDs are put together.
Step 3: Exporting the models to FBX
Now that we have our model files decompiled, it’s time to put them in a format that Unity can understand.
Open Blender, then delete everything in the scene (press A and then Delete). Make sure that you deleted both the camera and the light source which Blender so helpfully generated for us.
Go to File > Import > Source Engine, then navigate to the QC file which Crowbar generated. Click Import, and wait. It may take a few moments for the turret to load.
Once the model is fully loaded, go to File > Export > FBX. Name the file anything you like, and click Export. Wait a few minutes for the operation to complete, and then you can close Blender without saving.
Step 4: Importing the FBX into Unity
If you don’t have any experience with Unity, don’t worry! I will explain the entire process.
Launch Unity and select “open project”. Open up the Tabletop Simulator Modding project that you downloaded from GitHub (if it is still in a ZIP file you will need to extract it).
Once Unity has loaded the project, navigate to the project explorer at the bottom left of the screen. Right click on the top folder, and click Create > Folder. Name the folder anything; I called mine “Custom”. Repeat the process to make another folder called “Prefabs”.
Navigate into the Custom folder (the first one you created). Inside, create three folders: “Materials”, “Textures”, and “Sounds”. Now drag the turret.fbx file into the Custom folder and wait for Unity to finish importing it.
If you dragged the turret into the scene now, it wouldn’t look right because we haven’t attached any materials or textures to it. Click on the turret object in the project explorer at the bottom, then move up to the “Inspector” pane in the top right. Click on Materials > Extract Materials, and then select the Materials folder that you created. When the operation is completed, you will see four new objects in the Materials folder.
Now we need to bring the turret’s textures into Unity. Open VTFEdit, then select Tools > Convert Folder. Set the input folder to wherever you extracted your textures, and set the output folder to anything you want. Check “To”, then set the file type to PNG. The input box should contain *.vtf. Once the textures are all converted to PNG, drag them into the Textures folder you created in Unity. Select all the textures, then navigate to the Inspector and check “Alpha is transparency”.
Finally, we need to associate the materials with textures. Navigate to the Materials folder. Click the first one (“models_npcs_turret_turret_casing”) to open it in the Inspector. There is an option called “Albedo”, which refers to the wavelength/amount of light which is reflected from a surface. Click the circle next to Albedo and select the correct texture, which will have a similar name to the current material (in this case we are looking for “turret_casing” or “turret_casing_rusted”). Now click the color picker box on the same line as Albedo and set the color to white. Repeat this process for each object in the Materials folder.
Now you should be able to click and drag the turret object from your Custom folder into the main viewport (known as the scene). Make sure that all the textures look how you would expect, and repeat the previous step if they don’t.
Step 5: Adding animations
It’s time to add some animations to our turret. Tabletop Simulator has looping and trigger effects, which means that the animations are played forever or only once, respectively. In this guide I will only be going over looping effects but the process is the same for trigger effects.
We will need to set three animations to loop. Click on the turret in the project explorer, then in the Inspector click on Animation. In the list of animations, navigate to “turret.qc_skeleton|idle” and check the box labeled “Loop Time”. Leave the other settings alone. Repeat that process for “turret.qc_skeleton|fire” and “turret.qc_skeleton|idlealert”. Finally, make sure that Loop Time is unchecked for the “turret.qc_skeleton|deploy” animation.
Open up the Animator pane (Window > Animation > Animator) and select the “turret” controller in the project explorer (it will appear just beneath the turret model that we worked with earlier).
In the animator pane, you should see four rectangles which are blue, green, orange, and red. Focus on the green and orange rectangles, and notice how there is an arrow going from green to orange. The green box represents Unity’s entry point into the animation set, and the orange box represents the default animation the character will play. Since we don’t want our turret to play any animation when it is first spawned, we will click on the orange box, rename it to “Nothing”, and make sure that the Motion is set to None.
First, we will create the Idle state. Right click on an empty space in the Animator and select Create State > Empty. Click on the newly generated gray box and move to the Inspector panel. Name this state “Idle” and set the Motion to “turret.qc_skeleton|idle”. And that’s it for the Idle state.
Repeat the process above for the Fire state.
Now we will create the Deploy state. This state will be composed of two separate animations: one which plays once, and one which loops indefinitely. We are doing this because we want the turret to deploy and then remain open, and if we just looped the deploy animation it would open and close over and over again. Make a new state called “Deploy” and set the Motion to “turret.qc_skeleton|deploy”. Then make a state called “Open” and set its Motion to “turret.qc_skeleton|idlealert” Right click on the Deploy state and click “Make transition”, then click on the Open state. This will create a white arrow between the two states. This will cause the turret to first open, and then remain open until a different animation is selected.
Finally, we will give Tabletop Simulator control over when each state is entered and their animations played. Click on the turret in your scene, then move to the Inspector. There should be a component called “Animator”; if not, create one by clicking Add Component and searching for Animator. In the Animator component, set the Controller to our turret controller and set the Avatar to None. Now add a component called “TTS Asset Bundle Effects”.
Under Looping Effects, change the Size to 3 since we are adding three effects. Under “Element 0”, set the Name to “Idle”. Then move down to the Animator (not Animation) section and set the Animator Component to our turret controller. Set State Name to Idle. Now repeat this process with the other elements and states.
Once that’s done, we have completed adding animations to the turret.
Step 6: Creating a prefab and spawning the object in Tabletop Simulator
A prefab is a “pre-fabricated” asset. These assets are useful in 3D modeling operations because they can be created and duplicated, with any changes to the base prefab being reflected in all the copies. This is required to make an AssetBundle.
Drag the turret from the scene into the Prefabs folder. Click on the newly created prefab, then move to the bottom right of the screen. Click the dropdown next to AssetBundle, then click New and enter a unique name for the AssetBundle. Then right click on an empty area in the Prefabs folder and click Build AssetBundles. Wait a few moments for Unity to generate an AssetBundle.
Open Tabletop Simulator and create a new single player world. Choose one of the flat, square tables. Now click Objects > Components > Custom > AssetBundle, and then click anywhere on the table to spawn the object. Press escape and you will be brought to the Custom AssetBundle menu. Click the folder icon next to the Main field, then browse to the root of your Tabletop Simulator Modding folder (where the Unity project is stored). Navigate to the AssetBundles folder, and open the turret AssetBundle you just created (it will be stored in unity3d format). Choose either Local or Cloud. Set the Type to Figurine so that we don’t have to worry about the turret being upside-down. Then click Import.
As the turret is quite large it will likely fly around a bit. Grab it and balance it on the table (scale it down a bunch if you want). You should be able to right click on the turret, mouse over Looping Effects , and click on any of them to see if the animation is working. If it works, congratulations! You have successfully imported an animated sentry turret! If not, go back to the previous step and make sure you followed it exactly.
Step 7: Adding sounds to the animations
This step is entirely optional but it will add life to your animated turret. We are going to add a sound that plays when the turret fires and when it is picked up.
Back in GCFScape, navigate to sounds/npcs/turret and extract any of turret_fire_4x… files. Then navigate to sounds/npcs/turret_floor and extract any two of the turret_pickup… files. Rename the extracted files to something easier to remember if you want.
Open Unity, then drag and drop the extracted sound files into the Custom/Sounds folder. Click on the turret in your scene. Now, in the TTS Asset Bundle Effects script, go to the Fire element, expand the Sound section, click on the circle next to Audio and select your firing sound effect. Finally, check Positional 3D. This will make the sound emanate from the turret model rather than everywhere in the world (which would make your firing sound very annoying for other players).
In the Inspector, click Add Component and search for TTS Asset Bundle Sounds. This script controls which sounds play when in-game events such as Pickup and Drop occur on our AssetBundle. Expand the Pickup section and set the size to 2. Now add your two pickup audio clips in the Element fields. Every time you pick up the turret in-game, one of these sounds will be chosen at random. They will automatically emanate from the turret model instead of the world.
You can follow this process to add audio to the other animations we added to the turret if you want.
Conclusion
If you’ve made it this far, congratulations! You have successfully imported a fully-animated Portal 2 sentry turret into Tabletop Simulator. Hopefully you have also gained a greater understanding of how to create AssetBundles in general. This process can be extended to any Source Engine model that you want to add in-game, or really any model that you have provided it can be opened in Blender.
Please leave any suggestions in the comments below, and thanks for reading!