Compiling your map for Empires.

Discussion in 'Mapping' started by Varbles, Jan 2, 2012.

  1. Varbles

    Varbles Simply Maptastic. Staff Member

    Messages:
    2,093
    Likes Received:
    26
    Trophy Points:
    0
    I decided to write this tutorial for the Empires mapping forum because this seems to be something the newer Empires mappers don't pay a lot of attention to. I hope it proves useful to someone.



    What the compiler actually does

    The compile button in Hammer is probably something you've gotten used to using to test your maps, and sure, maybe you understand what happens when you set Rad to "fast" or set BSP to "entities only". But do you really understand what you're doing when you compile a map?
    When you start that compile, Hammer starts an automated process which runs your VMF through three different programs. These programs are VBSP.exe, VVIS.exe, and VRAD.exe.

    The first program that your VMF is run through is VBSP.exe, short for Valve BSP. This takes your plain Valve Map File and generates a basic BSP file (Binary space partitioning) from it. The brushes and displacements are properly converted into geometry the game can understand, entities and such are converted so the game will understand them. This process never takes more than a couple of seconds. When it is done, the bare-bones BSP is output to the folder that the VMF was loaded from.
    When you do an "Entity only" compile, the process is slightly different. With "Entity only", VBSP.exe doesn't generate a new BSP file from the VMF, it just loads the existing one in the directory where the VMF is, and edits the entity information in it. Changing geometry, brushes, textures, or lighting in a map and then only doing an Entity compile will either be ineffective or cause problems.

    The next build program starts and loads the BSP that VBSP.exe just output. This program is VVIS.exe, short for Valve Visibility. The first few things this program does is prepare the fancier shaders such as water or cameras so in order for water to work properly you need to at least run fast VVIS. The much larger part of VVIS involves using the automatic Visleaf generator to make up the Visleafs of the map. If you don't know what a visleaf is, they are described in detail here, and you should make every effort to learn about them. This part of VVIS is very important if you're doing a compile that you plan on releasing. This part of VVIS will increase the FPS that players get in your map by a HUGE amount. If you do a "fast" VVIS compile, you forsake all FPS gains that the Visleaf generator would give you and the players end up rendering ALL of the map, ALL the time. VVIS is a very important and often skipped part of the compile, mostly because the Visleaf generator will take a frustratingly long time if your map is not at least semi-optimized. Why you should optimize and a rough guide of what to do is something I will cover in the section after this. After VVIS completes it's work, which usually takes 2 to 30 minutes depending on map and cpu speed, it outputs the still partially complete BSP to the directory that it was loaded from.

    The last program in the process is VRAD.exe, short for Valve Radiosity Simulator. This program determines ALL the lighting in your map. If you don't run your BSP through VRAD at all, your map will have no lighting data at all and the engine will be forced to run it with mat_fullbright, which looks horribly, horribly ugly. This program takes the values you set all your lights to and runs them through it's Radiosity Simulator, which calculates the shading on all the different areas of the map, the way the light bounces off of surfaces to light nearby areas, and the way the shaded areas of the map look. This is probably the most important part in making your map look good. When you do a "full" VRAD compile with HDR, the compiler will put the BSP through VRAD twice, once for LDR (LDR is what you have if you don't have HDR) and once for HDR. A "fast" VRAD compile will usually only take a minute or two, but produces very rough lighting. A "full" VRAD compile will take usually 10 to 30 minutes. A "final" VRAD compile will usually take 30 minutes to an hour. Again, if you're doing a compile that you plan on releasing, you should at least do a full VRAD compile, if not a final HDR compile, but I go over that later in the tutorial. After VRAD.exe has finished, the compiler then takes your completed BSP and copies it to the /maps/ directory you specified.

    The compiler will then attempt to launch the game and run your map, if you selected the option. It's also nice to realize that the compiler leaves a copy of the compile log as a text file in whatever directory you loaded the VMF from, along with a copy of the finished BSP. Additionally, you may remember from when you first configured Hammer, under the Tools>Options>Build Programs menu, Hammer has 5 fields where it asks you the location of the executable files for the game, bsp, vis, rad, and the folder that the completed maps should be output to. It asks you this because different iterations of the source engine use slightly different build programs. Since Empires is on Source 2007, the build programs will all be found in "$SteamUserDir\sourcesdk\bin\source2007\bin".



    Why you should optimize your map

    Many novice mappers sit through 2 or 3 day long compiles where VVIS does incredible amounts of completely unnecessary calculations, and then whine about how much Source sucks. The reason behind these absurdly long compile times is the automatic Visleaf generator, and shitty mapper's refusal to understand it. Basically, this generator takes every world brush (any brush not tied to an entity) and calculates what areas of the map it would obscure at every viewing angle in the map. This can be an ENORMOUS task if the mapper hasn't spent the 30 seconds required to address this.
    To address this facet of VVIS, you take every brush that isnt big enough to properly obscure any part of the map from the player, and make it into a func_detail. Func_details, along with every other brush entity, will be ignored by the generator. The generator will also totally ignore the area inside of a func_viscluster, so you should use these in large, open parts of the map, such as the center of emp_isle. There are far better articles about how to optimize in hammer, and optimization is something every mapper should become familiar with. This is just a bit of info to make sure you're on the right track.



    Using "Expert" compile mode

    The "Expert" compile mode in hammer may seem a little bit intimidating at first but it's such a useful tool that it is definitely worth learning about. To access the "Expert" mode, you press the compile button in hammer and then click "Expert..." at the bottom left. It presents you with a slightly different compile option dialogue. In the top left there is a drop down menu of different compile configurations. These are basically what the "Normal" compile mode uses, only you have more control over what the compiler actually does. You can change what they do by adding Parameters in the "Parameters:" field. A useful parameter to add is "-low" if you want the compiler to only use idle cycles instead of all of your cpu, or use "-both" on $light_exe to compile the map for both LDR and HDR. There are many useful parameters you can add, some of which I will cover later, and you can find documentation for all of them on the Valve Developer Wiki.


    Final Compile settings

    Once you've tested your map a few times, ironed out all the bugs, and are ready to compile for a playable release, you don't want to just stick with a "Full" compile. With a "full" compile, models still don't get properly lit, props only cast shadows according to their collision models, and the lighting still isn't perfect. To do a proper release-ready compile, you want to go in the expert compile mode, select the "HDR Full Compile -Final (slow!)", and then add two extra parameters to $light_exe. Those two parameters are "-staticproppolys" and "-staticproplighting".

    This is important for a final release because "-staticproplighting" enables vertex lighting on static props, "-staticproppolys" tells VRAD to calculate shadows from props via their polys instead of collision models, "-final" allows VRAD to use more rays in its radiosity simulator which gives nicer lighting. It is important to do an HDR compile, too, even if you haven't added anything special for HDR. HDR makes the lighting look prettier in places where there is lots of contrast and shadows.


    Building your Cubemaps

    If you don't know what cubemaps are at all and haven't placed any in your map, this won't help you, but it's good to know anyway. Once you've done a final compile, you still have to load the game in the engine to build the Cubemaps. You have to open your console while your map is loaded and type in "buildcubemaps", and the client will start flashing a slideshow of small screenshots taken at each env_cubemap entity. If you compiled for both LDR and HDR, you will have to build Cubemaps twice, once when you have HDR disabled, and once when you have HDR enabled. The cubemap data gets automatically compressed into your BSP and the next time you reload the map, specularity and reflections will look correct. It is important to note that if you rename your BSP after you've built the cubemaps, it will cause problems.
     
    Last edited: Jan 2, 2012
  2. Varbles

    Varbles Simply Maptastic. Staff Member

    Messages:
    2,093
    Likes Received:
    26
    Trophy Points:
    0
    I hope this tutorial documentation will be helpful to someone as these concepts are things I ignored/never understood for a long time, and now that I'm familiar with them they help me tremendously. I know that it seems like a wall of text but I think it's concise while still giving all necessary information.
    If anyone wants to help with formatting or has anything to add/correct it'd be greatly appreciated
     
  3. LordDz_2

    LordDz_2 Strange things happens here

    Messages:
    2,956
    Likes Received:
    93
    Trophy Points:
    0
    func_detail is your friend, use it.
     
  4. flasche

    flasche Member Staff Member Moderator

    Messages:
    13,299
    Likes Received:
    168
    Trophy Points:
    0
    use it for everything since there is probably very little visible, visblocking brush geometry in empires-maps ...
     
  5. LordDz_2

    LordDz_2 Strange things happens here

    Messages:
    2,956
    Likes Received:
    93
    Trophy Points:
    0
    Put huge nodraw blocks below the mountains? Also, nodraw is your friend.
     
  6. flasche

    flasche Member Staff Member Moderator

    Messages:
    13,299
    Likes Received:
    168
    Trophy Points:
    0
    yes thats what i meant to say. if you really do visblocking and dont use keefs hack with draw distance and a "feature-complete" 3dskybox. i guess that is dependend on the layout though ...
     
  7. Silk

    Silk Mapper

    Messages:
    3,147
    Likes Received:
    36
    Trophy Points:
    0
    By glancing over it, i think it pretty much sums up what i did with the last versions of bush and chain.

    I checked the compile setting for chain and i have this:
    -both -final -StaticPropPolys -TextureShadows -StaticPropLighting

    I have forgotten what TextureShadows does, but for some reason i think i needed it.

    And yes, 100% of the visible brushes in chain are func_detailed. I did visblocking by adding nodraw brushes. Nodraw brushes can be placed inside normal brushes without any problems (not only under displacements), and the number of visleafs can be decreased immensly this way. Intersecting normal brushes should be avoided though.

    Also i think all brushes that are func_detailed together (as one entity) are considered as one unit for the visibility calculations. If you put 80 brushes in one huge func_detail, and one of them is visible, i think the engine will draw them all. So don't put all brushes in one func_detail, but divide them into groups first. Turning each and every brush into a func_detail on it's own could cause you to reach entity limitations.

    Also, good job Varbles!
    Please become an official mapper and make real, good and respectable maps ^^
     
  8. Varbles

    Varbles Simply Maptastic. Staff Member

    Messages:
    2,093
    Likes Received:
    26
    Trophy Points:
    0
    I found Occluders to be useful in situations where visleaves wouldn't be able to help. I think I may write a separate tutorial on optimization specific to emp maps unless we have one already.
     
  9. Silk

    Silk Mapper

    Messages:
    3,147
    Likes Received:
    36
    Trophy Points:
    0
    I think that's a very good idea.

    I myself never took the time to learn how to use occluders for example. I thought it was for small areas like windows, blocking off big areas, and my maps never really had places like that.

    For a detailed tutorial in optimization you'll gonna need pictures though ^^. That's quite a lot more work than just summing things up.
     
  10. Solokiller

    Solokiller Member

    Messages:
    4,861
    Likes Received:
    7
    Trophy Points:
    0
    For windows you could use areaportalwindows, and for interiors you could use areaportals to reduce the amount of geometry that's being drawn. I don't think that func_detail counts as an entity since it's stripped after compilation, although the compiler might still count it.
     
  11. Trickster

    Trickster Retired Developer

    Messages:
    16,576
    Likes Received:
    46
    Trophy Points:
    0
    I forgot about this thread. Stickied.
     
  12. Tuxu

    Tuxu Member

    Messages:
    308
    Likes Received:
    1
    Trophy Points:
    0
    good, i guess i should also take the time to read it.
     
  13. DocRabbit

    DocRabbit Member

    Messages:
    307
    Likes Received:
    17
    Trophy Points:
    0
    Just for completeness sake, TextureShadows allow the lighting to use alphas as light masking. It requires you have a file called lights.rad to determine which models will allow for it. The chainlink fencing used in hl2 is a good example.

    Code:
    lights/fluorescentcool001a    189 231 232 350
    lights/fluorescentcool001b    236 255 182 350
    lights/fluorescentcool002a    189 231 232 400
    lights/fluorescentcool002b    236 255 182 400
    lights/fluorescentcool003a    189 231 232 300
    lights/fluorescentwarm001a    239 216 193 350
    lights/fluorescentwarm002a    239 216 193 400
    lights/fluorescentwhite001a    245 245 245 350
    lights/fluorescentwhite002a    245 245 245 400
    
    
    lights/hazzardred001a        228 37 0 300
    lights/hazzardyellow001a    250 215 74 300
    
    lights/HIDcool001a        145 222 172 650
    lights/HIDcool001b        205 232 255 650
    lights/HIDwarm001a        255 201 116 650
    
    lights/white001            250 240 205 100
    lights/white002            189 233 247 425
    lights/white003            232 246 190 350
    lights/white004            170 228 247 425
    lights/white005            234 235 220 375
    lights/white006            234 235 220 100
    
    lights/blue001            166 180 196 200 166 180 196 100
    lights/blue002            141 176 203 200 141 176 203 100
    lights/red001            63 1 1 200 63 1 1 100
    
    lights/white001_nochop    250 240 205 100
    lights/white002_nochop    189 233 247 425
    lights/white003_nochop    232 246 190 350
    lights/white004_nochop    170 228 247 425
    lights/white005_nochop    234 235 220 375
    lights/white006_nochop    234 235 220 100
    
    lights/incandescentcool001a    235 235 235 300
    lights/incandescentwarm001a    250 226 129 300
    
    
    glass/glassscreen001a        172 192 161 225
    glass/glasspipe001f        214 72 44 200
    glass/glassscreen001c        172 192 161 225
    glass/glassscreen001d        211 187 134 225
    glass/glassblock001a        70 194 209 200
    composite/citadelfloor001a    103 143 203 200
    props/tvscreen006a        196 0 0 200
    shadertest/gooinglass        149 49 15 50
    
    glass/glasswindow002e        189 233 247 425
    glass/glasswindow035a        145 222 172 100
    
    dev/DEV_INTERIORLIGHT02B    151 176 204 225
    
    plaster/plasterwall029h        189 223 227 125
    building_template/Building_Trainstation_Template001d    230 230 200 65
    building_template/Building_Trainstation_Template001e    230 230 200 150
    building_template/Building_Trainstation_window002d    230 230 200 300
    building_template/Building_Trainstation_window002e    230 230 200 300
    
    lights/physgunlight    189 231 232 20
    
    noshadow tree_deciduous_01a_branches.vmt
    noshadow tree_deciduous_01a_leaves.vmt
    noshadow tree_deciduous_01a_lod.vmt
    noshadow tree_deciduous_01a_lod-leaves.vmt
    
    forcetextureshadow props_foliage/tree_dead01.mdl
    forcetextureshadow props_foliage/tree_dead02.mdl
    forcetextureshadow props_foliage/tree_dead03.mdl
    forcetextureshadow props_foliage/tree_dead04.mdl
    forcetextureshadow props_foliage/tree_dry01.mdl
    forcetextureshadow props_foliage/tree_dry02.mdl
    forcetextureshadow props_foliage/tree_pine_large.mdl
    forcetextureshadow props_foliage/tree_pine04.mdl
    forcetextureshadow props_foliage/tree_pine05.mdl
    forcetextureshadow props_foliage/tree_pine06.mdl
    forcetextureshadow props_foliage/tree_deciduous_01a.mdl
    forcetextureshadow props_foliage/tree_deciduous_02a.mdl
    forcetextureshadow props_wasteland/interior_fence001a.mdl
    forcetextureshadow props_wasteland/interior_fence001b.mdl
    forcetextureshadow props_wasteland/interior_fence001c.mdl
    forcetextureshadow props_wasteland/interior_fence001d.mdl
    forcetextureshadow props_wasteland/interior_fence001e.mdl
    forcetextureshadow props_wasteland/interior_fence001g.mdl
    forcetextureshadow props_wasteland/interior_fence002a.mdl
    forcetextureshadow props_wasteland/interior_fence002b.mdl
    forcetextureshadow props_wasteland/interior_fence002c.mdl
    forcetextureshadow props_wasteland/interior_fence002d.mdl
    forcetextureshadow props_wasteland/interior_fence002e.mdl
    forcetextureshadow props_wasteland/interior_fence002f.mdl
    forcetextureshadow props_wasteland/interior_fence003a.mdl
    forcetextureshadow props_wasteland/interior_fence003b.mdl
    forcetextureshadow props_wasteland/interior_fence003d.mdl
    forcetextureshadow props_wasteland/interior_fence003e.mdl
    forcetextureshadow props_wasteland/interior_fence003f.mdl
    forcetextureshadow props_wasteland/interior_fence004a.mdl
    forcetextureshadow props_wasteland/interior_fence004b.mdl
    forcetextureshadow props_forest/fence_barb_256.mdl
    forcetextureshadow props_forest/fence_barb_512.mdl
    forcetextureshadow props_forest/fence_border_128.mdl
    forcetextureshadow props_forest/fence_border_256.mdl
    forcetextureshadow props_forest/fence_border_512.mdl
    forcetextureshadow props_forest/fence_trail_128.mdl
    forcetextureshadow props_forest/fence_trail_256.mdl
    forcetextureshadow props_forest/fence_trail_512.mdl
    forcetextureshadow props_wasteland/exterior_fence_notbarbed002a.mdl
    forcetextureshadow props_wasteland/exterior_fence_notbarbed002b.mdl
    forcetextureshadow props_wasteland/exterior_fence_notbarbed002c.mdl
    forcetextureshadow props_wasteland/exterior_fence_notbarbed002d.mdl
    forcetextureshadow props_wasteland/exterior_fence_notbarbed002e.mdl
    forcetextureshadow props_wasteland/exterior_fence_notbarbed002f.mdl
    forcetextureshadow props_wasteland/exterior_fence001a.mdl
    forcetextureshadow props_wasteland/exterior_fence001b.mdl
    forcetextureshadow props_wasteland/exterior_fence002a.mdl
    forcetextureshadow props_wasteland/exterior_fence002b.mdl
    forcetextureshadow props_wasteland/exterior_fence002c.mdl
    forcetextureshadow props_wasteland/exterior_fence002d.mdl
    forcetextureshadow props_wasteland/exterior_fence002e.mdl
    forcetextureshadow props_wasteland/exterior_fence003a.mdl
    forcetextureshadow props_wasteland/exterior_fence003b.mdl
    forcetextureshadow props_foliage/fern01.mdl
    forcetextureshadow props_foliage/ferns01.mdl
    forcetextureshadow props_foliage/ferns02.mdl
    forcetextureshadow props_foliage/ferns03.mdl
    forcetextureshadow props_forest/fern01.mdl
    forcetextureshadow props_forest/fern01lg.mdl
    forcetextureshadow props_c17/fence03a.mdl
    
    copy this and save it in your %userprofile%/empires/empires folder as lights.rad.

    Then when you compile your maps they will take the models alpha texture into account when lighting.

    You will also need to adust your lightmap scale on areas that the shadow will cast onto based on the size of the opening. (This will highly impact compile times so be prepared and set it only to low numbers on just what you need it to.) I'll try to add couple of screenshots to show difference.

    Without -TextureShadows
    [​IMG]

    With -TextureShadows
    [​IMG]
     
    Last edited: May 17, 2016
  14. ViroMan

    ViroMan Black Hole (*sniff*) Bully

    Messages:
    8,382
    Likes Received:
    4
    Trophy Points:
    0
    holly shit thats a bit of a difference, USE IT!
     

Share This Page