Skip to content

Prop Config

MOARdV edited this page Apr 20, 2018 · 18 revisions

Prop Config is a tool designed to automate prop generation. It allows props to be grouped by arbitrary groups and output into separate folders based on those groups. Within each group, Prop Config allows the definition of one or more Styles. A Style is a collection of MODEL elements and MASComponent elements that defines common traits found in props. Each element in a Style may be overridden in the prop config, and additional fields may be added by a prop to further customize it.

Prop Config uses XML files for input. One or more XML files may be provided on the command line, ie. PropConfig.exe myprops.xml otherprops.xml.

One caveat about Prop Config: it is a fairly dumb tool. You can tell it to create invalid MASComponent nodes, and you can reference textures and models that don't exist. Making it smart enough to ensure the models and textures exist in the KSP installation, and that only valid MASComponent nodes are created would make it run slower, and it would mean that it must be updated at the same time that new features are added.

NOTE: Capitalization matters. An element named model is not the same as an element named MODEL.

XML Layout

An example of the PropConfig XML file can be found in the distribution under GameData/MOARdV/MAS_ASET. TODO: Actually add it

Root Node

The root node must be named PropConfig:

<PropConfig>
  ...
</PropConfig>

Prop Groups

A prop group is a collection of props that generally share common characteristics, such as ASET modular toggle switches. Each prop group should include a folder attribute. This folder tells PropConfig to write the config files for that prop group. If the folder attribute is missing, PropConfig will write the group's configs in the current directory. PropConfig creates these folders relative to the current working directory if they are not a full path. A prop group can have any name for its element - PropConfig will display that name as part of its output, but the name has no further effect on prop generation.

The folder attribute may consist of a nested folder, eg "Switch_Toggle_Modular/aircraft". UNTESTED

<ToggleSwitch folder="Switch_Toggle_Modular">
  ...
</ToggleSwitch>

Each prop group contains two categories of child elements: styles and props.

A style consists of a set of configuration values that are shared by multiple props. The style provides a template that is used to build a prop's config file.

A prop defines an actual prop that will be created by PropConfig. It consists of a name, a style, and overrides for nodes in the style. Any field in a style may be overridden, and a prop may add additional fields to any prop. In addition, it may add whole new MASComponent or MODEL nodes to the config file.

Style

A Style defines the common values used in a particular style of prop. It consists of one or more MODEL elements and any number of other elements that correspond to MASComponent nodes. The style defines the default values for all of these common nodes. A Prop may override these defaults. Each style must include a name attribute so that PropConfig can identify it later. The name may be any valid string.

<style name="MOARdV Power Switch">
  <MODEL>
    ...
  </MODEL>
  ...
</style>

Prop

A Prop defines a single prop. It consists of a name element, a style element, zero or MODEL override elements, and zero or more MASComponent override elements.

<prop>
  <name>MAS.toggle_ARRT_Power</name>
  <style>MOARdV Power Switch</style>
  <COLLIDER_EVENT id="0">
    <onClick>ARRT_TogglePower()</onClick>
  </COLLIDER_EVENT>
  <ROTATION>
    <variable>fc.GetPersistentAsNumber("MAS_ARRT_On")</variable>
  </ROTATION>
  <TEXT_LABEL id="0">
    <text>ON</text>
  </TEXT_LABEL>
</prop>

The name element may contain any name that can be used for both a file name and a KSP prop name. PropConfig will automatically replace any empty space (' ') with an underscore ('_') for the prop name, since ModuleManager is not able to parse whitespace in a name. When creating the config file, PropConfig will replace any '.' characters with '_'. In the example above, the prop is named "MAS.toggle_ARRT_Power". The config file is named "MAS_toggle_ARRT_Power.cfg".

The style element names the Style that is used as a template for this prop. If an invalid style is selected, PropConfig will skip the part.

MODEL

Both Styles and Props may include MODEL elements. A MODEL element is converted into a MODEL node in the config file. Each MODEL element should include one model element, an optional comment element, and zero or more texture elements. When more than one MODEL element is required in a prop (such as the ASET modular props), each MODEL element must be identified by an id attribute, which is an integer number. If the id attribute is omitted, it defaults to 0.

<MODEL id="1">
  <comment>Basic toggle</comment>
  <model>ASET/ASET_Props/Control/Switch_Toggle_Modular/models/TgglLever_Type_5</model>
  <texture>Switch_TUMBLEDiffuse,ASET/ASET_Props/Control/Switch_Tumble/Switch_TUMBLEDiffuse</texture>
  <texture>Tggl_Cap_Diffuse,ASET/ASET_Props/Control/Switch_Toggle_Modular/models/Tggl_Cap_White</texture>
</MODEL>

In this case, the MODEL has an id of 1, so if a Prop needs to edit this MODEL for some reason, it will also need to use <MODEL id="1">.

The above MODEL element results in the following output in the config file:

// Basic toggle
MODEL
{
  model = ASET/ASET_Props/Control/Switch_Toggle_Modular/models/TgglLever_Type_5
  texture = Switch_TUMBLEDiffuse,ASET/ASET_Props/Control/Switch_Tumble/Switch_TUMBLEDiffuse
  texture = Tggl_Cap_Diffuse,ASET/ASET_Props/Control/Switch_Toggle_Modular/models/Tggl_Cap_White
}

Although they are not included in this example, the MODEL options for scale and rotation may also be included in the XML script.

MASComponent

Any element in a Style or Prop that is not named MODEL is treated as a MASComponent node. The name of the node in the config file is exactly the same as the name of the element. For instance, if the element is called <ROTATION>, then the config file will include a node named ROTATION. If more than one node of the same type is used in the prop, each element should be given a unique id in the same way described for MODEL. If an element does not have an id, it defaults to 0.

Like the MODEL element, a MASComponent element contains multiple child elements. The MASComponent element also supports the comment child element like the MODEL. Each child element is converted into a ConfigNode name/value pair. For example,

<ROTATION>
  <variable>fc.GetPersistentAsNumber("MAS_IMP_On")</variable>
</ROTATION>

will result in

ROTATION
{
  variable = fc.GetPersistentAsNumber("MAS_IMP_On")
}

in the prop config file.

Using Prop Config

Once you create the XML file to create props, run Prop Config from the command line:

PropConfig.exe myprops.xml
  • Prop Config reads the XML file. If there are any XML errors, such as mismatched open/close elements, Prop Config will print the error and skip processing that XML file.
  • Prop Config will process each prop group.

For each prop group,

  • Prop Config reads all of the style elements. Any styles with duplicated names are reported, and only the first style encountered with that name is used.

Within each style,

  • All elements with the name MODEL are processed as MODEL nodes. All other elements are processed as MASComponent nodes.
  • If more than one MODEL element is found in the style, and none have an id attribute, or if multiple MODEL elements are found with the same id attribute, Prop Config will report the duplicates. Only the first MODEL with a duplicated id will be used by the style.
  • Likewise, if more than one MASComponent element is found with matching ids, Prop Config will print a notice and keep only the first one.

Once the styles are processed, Prop Config will process all of the prop elements.

  • If the name contains any whitespace, Prop Config replaces those characters with _ underscore. Prop Config does not test for duplicate prop names.
  • Prop Config searches for the style named in the style element. If a style with that name is not found, Prop Config reports the error and it skips the prop.
  • Prop Config merges the style and the prop elements.

The merging process is as follows:

  • For every MODEL in the style, if the prop does not also have an entry for a MODEL with the same id, then the style's MODEL is used. If the prop has a MODEL with the same id, then Prop Config will copy each field in the MODEL from the style, unless the field exists in the prop as well, in which case the prop`s field is used. The same process is applied to MASComponent elements.

Since this is pretty confusing and important, and I did not explain it well, I'll provide an example:

<PropConfig>
  <SomeProps folder="LameProps">
    <style name="Example Style">
      <MODEL id="0">
        <comment>Unchanged Model</comment>
        <model>Props/Part1</model>
      </MODEL>
      <MODEL id="1">
        <comment>Edit Model</comment>
        <model>Props/Part2</model>
      </MODEL>
      <MODEL id="2">
        <comment>Add To Model</comment>
        <model>Props/Part3</model>
      </MODEL>
      <MODEL id="3">
        <comment>Multiple texture model</comment>
        <model>Props/Part3</model>
        <texture>diffuse,Props/otherDiffuse</texture>
        <texture>emissive,Props/otherEmissive</texture>
      </MODEL>
    </style>
    <prop>
      <name>UselessProp</name>
      <style>Example Style</style>
      <MODEL id="1">
        <model>Props/Part2a</model>
      </MODEL>
      <MODEL id="2">
        <texture>diffuse,Props/differentDiffuse</texture>
      </MODEL>
      <MODEL id="3">
        <comment>Oops - can't edit multiple textures</comment>
        <texture>diffuse,Props/differentDiffuse</texture>
      </MODEL>
    </prop>
  </SomeProps>
</PropConfig>

The above XML will create a prop config file LameProps/UselessProp.cfg. The file will look like

PROP
{
	name = UselessProp

	// Unchanged Model
	MODEL
	{
		model = Props/Part1
	}

	// Edit Model
	MODEL
	{
		model = Props/Part2a
	}

	// Add To Model
	MODEL
	{
		model = Props/Part3
		texture = diffuse,Props/differentDiffuse
	}

	// Oops - can't edit multiple textures
	MODEL
	{
		model = Props/Part3
		texture = diffuse,Props/differentDiffuse
		texture = diffuse,Props/differentDiffuse
	}

	MODULE
	{
		name = MASComponent

	}
}

It's not an interesting prop, since there are no components under MASComponent. But it illustrates the merging system.

One thing to watch out for, especially for MODEL texture fields: there is no way to distinguish between duplicated fields in a style. If a style has a MODEL with multiple texture fields, such as the Part3 MODEL node above, and a prop edits the texture field, all of the style's texture fields are changed. If you need to have MODEL nodes with multiple, different textures, you will have to put each one in its own, separate style.

Clone this wiki locally