This tutorial will guide you through the bare minimum steps to make a basic custom map work in-game.
By the end of this tutorial, you should have a small map that is just a square piece of ground with a couple locators.
NOTE: Missions will not yet work in this map and it will not have a custom HUD map. This tutorial is just the bare minimum required to go ingame, these will be covered in the next tutorial.
You will need a PC copy of The Simpsons: Hit & Run as well as the following tools to accomplish the steps in this tutorial:
- Lucas' Simpsons Hit & Run Mod Launcher
- Lucas' Simpsons Hit & Run Model Builder
- SketchUp Make 2017
- Knowledge of how to use SketchUp in general will help as these tutorials will assume you're already at least a bit familiar with the software.
- A Text Editor, we recommend Notepad++ or Visual Studio Code.
Part 1: The Mod
To actually play our map in-game, we'll first need a basic mod to start with. We've gone ahead and created a basic mod for these purposes that you can download here.
This mod contains the following:
- A basic
Meta.inithat requires the CustomFiles hack.
- A set of Level scripts to load everything needed for our map.
- A couple dummy missions with no objectives that will let us jump into our map by creating a new game from the main menu or by selecting L1M1.
- A folder named "_Assets" that you'll work out of.
You will need to extract the "Tutorial Map" mod folder itself into any of the Mod Launcher's default mods folders or any custom ones you have defined in the Launcher's Settings.
Part 2: The SketchUp File
Step 1: Setting up SketchUp
SketchUp's interface is very customizable so depending on your chosen layout you may not have certain important panels in view. We'd like to make a couple recommendations for the purposes of these tutorials.
Since the Model Builder relies heavily on a hierarchy of groups with special names and tags within them to work we'd first like to recommend that you keep the Outliner easily accessible. If you don't currently have a tray with the Outliner in it, you can go to
Window > New Tray... to create one containing it. You may also want the Entity Info panel in the same tray as it will make editing attributes of the currently selected object easier.
With large models that have many thousands of groups, you may experience slowdown having the Outliner open so it may be good to get used to minimizing it by clicking the arrow near its header when you're not using it. It would also be very beneficial to learn and understand how to make use of Layers for larger map projects.
You will also want the Materials and Components panels accessible. You can technically put these in the same tray though if you have a good amount of screen real estate, it might be better to make another new tray containing just them.
Also note that all new models start with a Component named "Chris". He's not really relevant to what you're going to be doing and you can leave him there or delete him, it's up to you.
Step 2: Save the model
You haven't done anything yet but it's good to start by saving your model. For the purposes of these tutorials, you should save it as "Map.skp" in the "_Assets" folder of the mod you extracted in Part 1.
Step 3: Terrain
You'll want to start by making some basic "terrain" in your SketchUp model, for the purposes of this tutorial, you should use a flat rectangle (though you could really use whatever you want).
Step 4: Setting up the groups
Now that you have some "terrain" you'll want to group it properly so that you can build it into a zone later. Select the square, right click it and click "Make Group". Then double click the group to focus it and repeat this step. This will create a group within a group.
The reason you do this is so that you can use the outer group to represent the zone and the inner group to represent Intersect collision (the ground). To do that, you will want to name the outer group
Zone001 and name the inner group
Ground [Intersect]. Once you've done that, your Outliner should look like this:
By default, everything within any group that represents a Zone will become a Static Entity model in the map. In this case however, you use the
[Intersect] Group Tag to tell the Model Builder that the contents of this group should also be made into Intersect collision. We're not going to go very in depth with these during this tutorial but you can do some pretty complex stuff with them!
With those groups setup, that's the contents of our first zone done for now.
Step 5: Adding a couple locators
The scripts included in the mod from Part 1 reference a couple locators to specify where the player and their car should start in the level. You're also going to create those with the Model Builder using one of its Special Components.
File > Import and navigate to the "Components" folder next to the Model Builder's executable. From there import "Locator.skp" into your model.
Now go to the Components panel and click the little house icon to bring up the list of components in the current model. If you imported it correctly, you should see "Locator" in this list.
Now click on it and drag a couple out onto the terrain you created in Step 3.
We're going to use these two locators as our player start and car start locators. You'll want to name one of them
level1_homer_start [CarStart] and name the other one
level1_carstart [CarStart]. The
[CarStart] tag here tells the Model Builder to make Type 3 Car Start locators which, despite their name, are also used for character starts.
Now that they're named and tagged select both of the instances, right click and click "Make Group". Name this group "Level" so we can build them into their own P3D file later. With all of that done, your Outliner should now look like this:
Step 6: Save again!
Make sure you save everything you've done so far if you haven't already.
Part 3: Configuring the Model Builder
Step 1: Creating the build files
To start, you want to create an XML file that will contain all of your rules for the Model Builder and a BAT file to actually launch the tool and tell it about your rules.
For now, just make a bare bones XML file that just has a root node:
Save this as "Build.xml" into the "_Assets" folder next to your SketchUp file.
Then make a BAT file that launches the Model Builder with "Build.xml" as a command line argument:
You'll need to manually replace the path with where-ever you put the Model Builder. Save this as "Build.bat" when you're done.
Once those are saved, running Build.bat should work and you should get an output that looks something like this:
[12:58:35 PM] MESSAGE: Loading SketchUp SDK DLL (64-bit) 17.0.18899.0... [12:58:35 PM] MESSAGE: Processing outputs... [12:58:35 PM] MESSAGE: Processing file outputs... [12:58:35 PM] SUCCESS: Completed in 25.2060558021864 ms.
Obviously, you haven't told the tool to do anything yet so it hasn't actually created any output files. This is just to make sure that the BAT file is working as intended.
Step 2: Defining an OutputPath variable
The Model Builder supports defining custom variables and it also has some of its own that you'll be using in this tutorial.
That said, the first order of business is defining one such custom variable in your rules for where your output files are going to go. This step isn't required necessarily but it makes it easier when you have lots of output files going to the same place.
This can simply go in the root element of the XML file you made in the previous step:
<!-- Get the parent path of our main Rules file then go up a directory then into CustomFiles --> <SetVariable Name="OutputPath" Value="$(ParentPath)\..\CustomFiles\art">
Notice that this path uses the special
$(ParentPath) variable. This is a quick and easy way to get the path to the XML file setting the variable.
Step 3: Including the base Zone rules
Before you write any more of your own rules, you'll also want to include some of the tool's base rules. Simply add an
Include element in the root node of the Build file you created in the last step and set the path to
<!-- Use the ModelBuilderPath variable to easily fill in the path to the tool's folder --> <Include Path="$(ModelBuilderPath)\Rules\Zone.xml"/>
This file contains all the necessary definitions to build Zones.
Notice that this path uses the special
$(ModelBuilderPath) variable. This is a quick and easy way to include things relative to where the Model Builder's executable and files are located.
Step 4: Specifying output files and zones
The next step is defining what the output files we're going to be building. In this case we're going to be building the Terra file, a single zone and a locators file.
<!-- Specify output files --> <OutputPure3DFile Name="Terra" Path="$(OutputPath)\L1_TERRA.p3d"/> <OutputPure3DFile Name="Zone001" Path="$(OutputPath)\l1z1.p3d"> <!-- Tell the tool that this file requires the Terra file to work --> <!-- This allows it to place textures/shaders used in multiple regions in the Terra file to save space --> <RequiredOutputPure3DFile Name="Terra" Textures="true" Materials="true" Lights="true"/> </OutputPure3DFile> <OutputPure3DFile Name="Level" Path="$(OutputPath)\missions\level01\level.p3d" />
You also want to define some information about the map and some zones for it, assigning each one to output in the appropriate
<!-- Define the map --> <!-- This gives you control what file the k-d tree goes in, the size of its tree nodes and how many DynaPhys are allowed in each node --> <HitAndRunMap Name="Map" TreeMinimumNodeSizeX="20" TreeMinimumNodeSizeZ="20" TreeDynaPhysEntityLimit="10"> <OutputPure3DFile Name="Terra"/> </HitAndRunMap> <!-- Define zones --> <!-- While things can be output directly into P3D files, outputting them into a zone instead makes them get included in the map's k-d tree --> <!-- Which is VERY important of course --> <!-- We don't need to do this for our Level OutputPure3DFile though since it's just going to contain locators and no world stuff --> <HitAndRunZone Name="Terra" Map="Map"> <OutputPure3DFile Name="Terra"/> </HitAndRunZone> <HitAndRunZone Name="Zone001" Map="Map"> <OutputPure3DFile Name="Zone001"/> </HitAndRunZone>
With these rules in place, the tool will now build empty P3D files to those paths. That's progress but you still need to tell it what to put in those files/zones.
Step 5: Making a light group and vertex colors
Before you handle how things are going to be built, you'll need a Light Group and Vertex Colour rules that reference them. This light group will be used to apply vertex colors to your map's models as well as being the actual light group used to dynamically light cars and characters in the world.
<!-- Specify the Light Group and name it --> <LightGroup Name="Level1"> <!-- These lights are more or less equivalent to the "sun" light group in the original game's L1_TERRA --> <AmbientLight Name="Ss_ambientLightShape1" Red="89" Green="89" Blue="89"/> <DirectionalLight Name="Simpsons_sun_directionalShape3" Red="89" Green="89" Blue="89" DirectionX="0" DirectionY="-0.5" DirectionZ="-0.866"/> <DirectionalLight Name="Simpsons_sun_directionalShape2" Red="140" Green="140" Blue="140" DirectionX="-0.75" DirectionY="-0.5" DirectionZ="0.433"/> <DirectionalLight Name="Simpsons_sun_directionalShape4" Red="140" Green="140" Blue="140" DirectionX="0.75" DirectionY="-0.5" DirectionZ="0.433"/> <!-- Specify an output file and chunk name to build this group into --> <OutputPure3DFile Name="Terra" ChunkName="sun"/> </LightGroup> <!-- Specify VertexColours rules that reference that light group --> <VertexColours Name="World" Light="Level1" LightAbsolute="true"/>
Step 6: Specifying a fallback material
Your map doesn't have any materials yet if you've been following this guide so you probably want to specify a material that the tool can fall back to for faces that don't have any.
<!-- Make a white material --> <Material Name="Null" Red="255" Green="255" Blue="255"/>
Step 7: Specifying input files
Now you'll want to specify a couple input files.
<!-- Of course you want to input your Map's SketchUp file --> <!-- Note that this path is relative to the XML file this element is in --> <!-- Since the SKP file is right next to it, we just put "Map.skp" --> <InputSketchUpModel Name="Map" Path="Map.skp"/> <!-- You'll also want to input a couple files from the original game --> <!-- This will make sense in step 9 so stay tuned --> <InputPure3DFile Name="L1_Terra" Path="$(GamePath)\art\L1_TERRA.p3d" /> <InputPure3DFile Name="L1_Level" Path="$(GamePath)\art\missions\level01\level.p3d" />
Step 8: Defining model output instructions
The next step is defining the instructions for outputting your SketchUp file.
<!-- Instruction set used for each zone --> <ModelOutputInstructions Name="Zone"> <!-- Use the instructions we included from "Zone.xml" in Step 3 --> <ExecuteInstructions Name="BaseZone"/> <!-- Set the vertex colors (lighting) of everything to the ones defined above --> <SetParameter Name="VertexColours" Value="World"/> <!-- Set the fallback material (for faces with no material) to the "Null" material created above --> <SetParameter Name="FallbackMaterial" Value="Null"/> </ModelOutputInstructions> <!-- Main instruction set --> <!-- Execute all of these instructions on the InputSketchUpModel named "Map" --> <SketchUpModelOutput InputSketchUpModel="Map"> <!-- Add selectors for each group name --> <!-- Basically when that group name is encountered, we'll execute the instructions inside the selector --> <AddSelector Pattern="^Terra$" Exclusive="true"> <!-- Each zone needs to Output to a Zone so it can be included in the k-d tree --> <AddOutputZone Name="Terra"/> <!-- Use those instructions we defined above --> <ExecuteInstructions Name="Zone"/> </AddSelector> <AddSelector Pattern="^Zone001$" Exclusive="true"> <AddOutputZone Name="Zone001"/> <ExecuteInstructions Name="Zone"/> </AddSelector> <AddSelector Pattern="^Level$" Exclusive="true"> <!-- Since this group just contains locators, we can output to the P3D file directly --> <AddOutputPure3DFile Name="Level"/> <!-- As well as use more specific instructions (also from "Zone.xml") --> <ExecuteInstructions Name="Locators2"/> </AddSelector> </SketchUpModelOutput>
Step 9: Borrowing from the original game
Now is where those P3D files you inputted earlier come in. You're going to want to extract a few things from them to place into your map's files.
<!-- "EnvMap.bmp" is being copied from Input "L1_TERRA" P3D into our new Output "Terra" P3D file so car reflections work --> <!-- This is placed at the start of the Terra file with Start="true" --> <Pure3DFileChunksOutput OutputPure3DFile="Terra" InputPure3DFile="L1_Terra" Type="Texture" Name="EnvMap.bmp" Start="true"/> <!-- Input Road Arrow Anims --> <!-- This is REQUIRED for missions to work (though our map doesn't have any roads so they won't work yet --> <!-- This is mainly here for the next tutorial that gets into adding Roads --> <!-- These need to be placed after any Intersections in the Terra file so you need to specify AfterIntersections="true" --> <!-- Lastly, it is crucial that this is after your SketchUpModelOutput element --> <Pure3DFileChunksOutput OutputPure3DFile="Terra" InputPure3DFile="L1_Terra" Type="Anim" Name="darrow" AfterIntersections="true"/> <Pure3DFileChunksOutput OutputPure3DFile="Terra" InputPure3DFile="L1_Terra" Type="Anim" Name="warrow" AfterIntersections="true"/> <!-- "coinShape_000" is being copied from the Input "L1_Level" P3D to the new Output "Level" P3D --> <!-- Since this is just a mesh, you can really put it wherever you want as long as level.mfk loads it --> <Pure3DFileChunksOutput InputPure3DFile="Level" OutputPure3DFile="L1_Level" Type="Mesh" Name="coinShape_000"/>
Step 10: Build and check it out ingame
Now it's time to run Built.bat again to see if it works ingame.
If you've done everything right, the map should successfully build and look something like this.
That's it for this tutorial. You're now ready to move on to the next one.