Valve Map Format

From Valve Developer Community
Revision as of 13:40, 14 May 2009 by Aybraus (talk | contribs)
Jump to: navigation, search

VMF stands for Valve Map Format. A .vmf file is the source code of a map designed for use in the source engine. Programs like Valve Hammer Editor (Hammer) are used to create or modify these files. Like any source file it must be compiled to be used and is thus designed to be easy to read and work with rather than optimized for execution. Because of this a .vmf file is written in an easy to understand form of coding language common in dealings with the source engine. This is to be the documentation of everything defined within a .vmf file detailing what is what and how it's shown. This is not a tutorial with an end result, it is more like a lesson in the theory behind it. This documentation is written using files generated by Hammer 4.1 within the Jan 1st 2006 Source SDK Beta.

The structure of .vmf

The code structure in a .vmf is simple and easy to understand, it's also common in many other factors of the engine. This is a simple review of the structure for those first exposed and to set out the terms that things will be referred to as.

// This is a comment.
ClassName_1
{
      "Property_1" "Value_1"
      "Property_2" "Value_2"
      ClassName_2
      {
            "Property_1" "Value_1"
      }
}

The given names are merely placeholders using the naming techniques they will be referenced with; Classes, Properties and Values. Within this documentation each section will be laid out the same. It will have a title of the Class it is explaining followed by a simple introduction of what that Class defines. Underneath will be a code sample, and then each property and the valid data type will be stated along with an explanation. There are only a few data types a .vmf file could contain, they are generally standard data types and values but are listed for reference.

Notation Description
int Any integer value.
dec Any decimal value.
sz Any string of characters.
bool A Boolean value of true/false in binary.
vertex An XYZ location given by 3 decimal values separated by spaces.
rgb A color value using 3 integers between 0 and 255 separated by spaces corresponding to the Red channel, Green channel, and Blue channel, respectively.

The Properties and values will always come right under the code sample and be laid out in the following manner. The explanation will be in brief and cover only that Property.


  • property_1 (data_type):
This will explain what the property represents and any further notes on possible values.

Sometimes the explanation cannot be brief, or a Property for one Class is in fact another different Class. When one line requires its own explanation it will be written as a link below the code sample. This merely indicates it is explained under its own title and is not included in the definitions for that Class. After each property is defined the Class will be discussed as a whole, along with the reasons behind the properties and how they affect the end result will be detailed.

Usual Structure

The usual structure of a vmf is as follows:

versioninfo{}
visgroups{}
world{}
entity{}
hidden{}
cameras{}
cordon{}

See each of these for what they do. The order does not matter, but Hammer will put them in this order when it saves.

Version info

This Class details information for Hammer on what version created the file and how many times it has been saved. It is basically the file header and contains no information relevant to the map itself.

versioninfo
{
      "editorversion" "400"
      "editorbuild" "3325"
      "mapversion" "0"
      "formatversion" "100"
      "prefab" "0"
}
  • editorversion (int)
The version of Hammer used to create the file, version 4.00 is "400".
  • editorbuild (int)
The patch number of Hammer the file was generated with.
  • mapversion (int)
It represents how many times you've saved the file, useful for comparing old or new versions.
  • formatversion (100)
Unknown.
  • prefab (bool)
Whether it is a full map or simply a collection of prefabricated objects.

What the formatversion represents is unknown due to the fact no different values are ever generated. Any changes in value yield no results and are simply overridden back to "100" on save. The prefab property is used to define if the file contains an object like a sofa made from other brushes and entities, rather than a full blown map. If any of this information is missing Hammer will simply recreate it from its current form.

VisGroups

This Class itself is usually empty; however, it contains all the unique VIS group definitions in Hammer, along with their structure and properties. The first separated section in the code sample is one unique group. The entire code sample is used for example.

visgroups
{

      visgroup
      {
            "name" "Tree_1"
            "visgroupid" "5"
            "color" "65 45 0"
      }

      visgroup
      {
            "name" "Tree_2"
            "visgroupid" "1"
            "color" "60 35 0"
            visgroup
            {
                  "name" "Branch_1"
                  "visgroupid" "2"
                  "color" "0 192 0"
            }
            visgroup
            {
                  "name" "Branch_2"
                  "visgroupid" "3"
                  "color" "0 255 0"
                  visgroup
                  {
                        "name" "Leaf"
                        "visgroupid" "4"
                        "color" "255 0 0"
                  }
            }
      }
}

  • name (sz)
The name of the group, it's the only identifier within in Hammer so it should be unique for your own benefit.
  • visgroupid (int)
A unique value among all other visgroup ids, identical values will cause weird minor errors in Hammer.
  • color (rgb)
A color for the group, can be applied to brush outlines in Hammer.

VIS groups are unrelated to the VIS part of a compile and in the new Hammer there are 2 types; auto, and custom. Auto refers to the automatic ones Hammer creates to single out types of brushes or entities, the auto groups are not defined in the file as Hammer generates them. Custom refers to groups that a user creates and they are defined within this Class. In older versions all groups were originally listed here. The groups themselves have a hierarchical tree like structure, meaning that one group may be a parent and have other groups be its children. When something is done to a parent children are affected, but children do not affect parents. To establish one group as a child to another group you define that group within the definition of the parent group. The code sample given is an example of this structure. Tree_1 is the parent of Branches and Branch_2 is the parent of Leaf_1. There's no limit to the complexity of this Class and its subclasses; however, there is a limit of 128 groups before Hammer begins to function improperly. It is possible to have more than one visgroups class, but Hammer will condense them into one, adding the additional vis groups into the main visgroup.

Viewsettings

This class contains the map specific view properties used in Hammer, any of the other properties are not saved into the map.

viewsettings
{
      "bSnapToGrid" "1"
      "bShowGrid" "1"
      "bShowLogicalGrid" "0"
      "nGridSpacing" "64"
      "bShow3DGrid" "0"
}
  • bSnapToGrid (bool)
Whether the map has the grid snapping feature enabled.
  • bShowGrid (bool)
Whether the map is showing the 2D grid.
  • bShowLogicalGrid (bool)
Undetermined. Does not appear to affect displays in Hammer.
  • nGridSpacing (int)
The value the grid lines are spaced at.
  • bShow3DGrid (bool)
Whether the map is showing the 3D grid.

If bSnapToGrid is true, Hammer will force all points the user interacts with to a multiple of nGridSpacing; this does not affect loaded vertices. Any other property set within Hammer will only be set for Hammer and not for the map. If any of this information is missing Hammer will simply recreate it from defaults so it is not essential.

World

VMF documentation: World Class

Group

This class sets the brush groups that exist and their propertied. It also defines their hierarchy.

group
{
      "id" "7"
      editor{}
}
  • id(int)
This is a unique number among other group ids.

A group is assigned one id, the brush itself states whether or not it is within the group. The definition for the editor Class is included again. This is important because it is how the hierarchy of all the groups is maintained. If one group is a child to another it then includes the group id within its editor subclass. That defines it is a sub group of the parent group, so when the parent groups break all the child groups will remain intact.

Hidden

There are two versions of the hidden class, but both include classes which have the visgroupshown or autovisgroupshown in editor set to "0".

The first type is in the world and entity class

hidden
{
      solid{}
}

This is very simple, just every hidden solid that would usually be held under world or entity is instead held under this. There's no other difference. Hammer itself will show solids under "hidden" if both of the visgroupshown properties are true.


The second type is under the file itself:

hidden
{
      entity{}
}

As with the other version this is simple, it simply holds the entity which is hidden. No other difference is visible. Again, Hammer will show entities with both visgroupshown properties set to true, even if it is under "hidden".

Entity

Both brush and point based entities are defined in the same way. Both are defined outside of the world class as the world class itself is an entity. All entities work in the same way: you define its properties and then either give the entity solids to inhabit or a point to exist at.

entity
{
      "id" "19"
      "classname" "func_detail"
      "spawnflags" "0"
      ______
      connections{}
      solid{}
      hidden{}
      "origin" "-512 0 0"
      editor{}
}
  • id(int)
This is a unique number among other entity ids.
  • classname(sz)
This is the name of the entity class.
  • spawnflags(int)
Indicates which flags are enabled on the entity.
  • origin(vertex)
This is the point where the point entity exists.

There are several lines that are important. First is the underscores, this is a placeholder for all the entities properties and values. These are the exact same thing seen with smart edit disabled in Hammer. The properties and values can be anything, but only valid properties will mean anything when compiled. It may be wise to review the definition of the world Class and the Worldspawn entity. With entities the possible values and properties extend far beyond the scope of this document and should be reviewed independently. Second is the connections{} Class. This is all the i/o information and is optional. Third, is the solid line. Defining a solid subclass will make it a brush based entity; having both an origin and solid will make a brush based entity with an origin property. Defining only an origin will make it a point based entity. Any missing entity properties will be recreated from default upon compiling and do not have to be saved.

Connections

This is where all the outputs for an entity are stored. Inputs are not stored as they are simply traced from the outputs. Therefore only the outputs are stored in this optional class.

connections
{
      "OnTrigger" "bob,Color,255 255 0,1.23,1"
      "OnTrigger" "bob,ToggleSprite,,3.14,-1"
}
  • Output(sz,Input,sz,dec,bool)
The entire output event stored in 1 string.

The string is pretty simple to decompose. The property is the output event triggering another entities input. The value on the other hand, is a comma separated string of the rest of the output's properties. First is the target entity name or class. Second is the Input being triggered on the target object(s). Third is the parameter overide, leave blank for no value. Fourth being the delay before triggering. The final parameter is the number of times to fire, or -1 to always fire. To create multiple outputs you simply add more properties.

Note that this is one string which Hammer does not make assumptions about. If you omit any value (except the last one) Hammer will crash with an unhelpful error message. If you omit the last value, which is the number of times to fire, Hammer sets it to 1 or Fire Once.

Cameras

Used for the 3D viewport cameras used in Hammer, created with the Camera Tool. These cameras are not used in-engine and are not compiled into the final .BSP.

cameras
{
    "activecamera" "1"
    camera
    {
        "position" "[-1093.7 1844.91 408.455]"
        "look" "[-853.42 1937.5 175.863]"
    }
    camera
    {
        "position" "[692.788 1394.95 339.652]"
        "look" "[508.378 1493 347.127]"
    }
    camera
    {
        "position" "[-4613.89 2528.77 -2834.88]"
        "look" "[-4533.53 2950.1 -2896.85]"
    }
}
cameras
{
    "activecamera" "-1"
}
  • activecamera (int)
Sets the currently active camera used for the Hammer 3D View. When no cameras are present in the .VMF, this value is set to -1 and the camera position defaults to the world origin, facing North.
  • position (vertex)
The eye position of the camera in the map.
  • look (vertex)
The position of the camera target -- the point the camera is looking toward.

Cordon

This stores all the information Hammer needs and uses for its cordon tool.

cordon
{
      "mins" "(99999 99999 99999)"
      "maxs" "(-99999 -99999 -99999)"
      "active" "0"
}
  • mins (vertex)
The top right upper co-ordinate.
  • maxs (vertex)
The bottom left lower co-ordinate.
  • active (bool)
Whether or not the cordon is turned on.


After the 2 points are defined, a rectangular prism is drawn between the two points. This will make any object that is outside the prism excluded from rendering or compiling.

Conclusion

That's all the information on the .vmf file format that Hammer will generate. This hopefully covers all possible questions and enables anyone to do what they wish with the file format. Below are some files for use as reference or used for the experiments that revealed how the format is laid out.