Difference between revisions of "User:Greys"
m (→Texture Assets: *GIMP should do the job too;) |
(added incomplete new section regarding conventions) |
||
Line 7: | Line 7: | ||
{{Box|*Ø comments indicate notes on existing content that is incorrect or inadequate, and will need to be addressed | {{Box|*Ø comments indicate notes on existing content that is incorrect or inadequate, and will need to be addressed | ||
*þ comments are formatting or structural changes that need to be made}} | *þ comments are formatting or structural changes that need to be made}} | ||
+ | = Conventions = | ||
+ | KSP's cfg format can be difficult to converse about without getting into how the code works because the format is a direct reflection of the code, but also because it's not very regular and a lot of labels get used repeatedly for different meanings while a lot of meanings get labeled differently in various places; all the while there are misnomers abound and piles of deprecated things that may or may not still work. | ||
+ | |||
+ | For example | ||
+ | {{Box|þ Example cfg needs to be stripped of identity, reorganized, and have it's sections be made consistent, instead of having three General Parameters sets}} | ||
+ | <pre> | ||
+ | PART | ||
+ | { | ||
+ | MODEL | ||
+ | { | ||
+ | model = HexCans/Models/Rack | ||
+ | position = 0.0, 0.0, 0.0 | ||
+ | scale = 1.0, 1.0, 1.0 | ||
+ | rotation = 0.0, 0.0, 0.0 | ||
+ | texture = HexCan000, HexCans/Parts/HexProbe/Probe | ||
+ | } | ||
+ | MODEL | ||
+ | { | ||
+ | model = HexCans/Models/Pistons | ||
+ | position = 0.0, 0.0, 0.0 | ||
+ | scale = 1.0, 1.0, 1.0 | ||
+ | rotation = 0.0, 0.0, 0.0 | ||
+ | parent = Rack | ||
+ | texture = HexCan000, HexCans/Parts/HexProbe/Probe | ||
+ | } | ||
+ | // --- general parameters --- | ||
+ | name = HexDecouplerRackNormal | ||
+ | module = Part | ||
+ | author = Greys | ||
+ | |||
+ | // --- asset parameters --- | ||
+ | mesh = model.mu | ||
+ | texture = hexcan.png | ||
+ | scale = 1 | ||
+ | rescaleFactor = 1 | ||
+ | specPower = 0.3 | ||
+ | rimFalloff = 3 | ||
+ | alphaCutoff = 0 | ||
+ | |||
+ | // --- general parameters --- | ||
+ | node_attach = 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 2 | ||
+ | node_stack_top = -0.035, 0.0, 0.0, 0.0, 1.0, 0.0, 1 | ||
+ | |||
+ | attachRules = 1,1,1,1,1 | ||
+ | |||
+ | // --- editor parameters --- | ||
+ | cost = 200 | ||
+ | category = Structural | ||
+ | subcategory = 0 | ||
+ | title = Decoupler Rack Normal | ||
+ | manufacturer = PanSpace Manufacturing Inc. Ltd. LLC. Co. | ||
+ | description = A small truss section for holding normal sized HexCans | ||
+ | |||
+ | // --- general parameters --- | ||
+ | mass = 0.04 | ||
+ | dragModelType = default | ||
+ | maximum_drag = 0.2 | ||
+ | minimum_drag = 0.3 | ||
+ | angularDrag = 2 | ||
+ | crashTolerance = 18 | ||
+ | breakingForce = 400 | ||
+ | breakingTorque = 400 | ||
+ | maxTemp = 2900 | ||
+ | |||
+ | stageOffset = 1 | ||
+ | childStageOffset = 1 | ||
+ | |||
+ | stagingIcon = DECOUPLER_HOR | ||
+ | |||
+ | MODULE | ||
+ | { | ||
+ | name = ModuleAnchoredDecoupler | ||
+ | anchorName = Mounting_Rack | ||
+ | ejectionForce = 600 | ||
+ | explosiveNodeID = srf | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | The most obvious way to reference pieces of this format is to mimic it, such as PART{MODULE{scale}}, but this can be just as confusing and complicates the issue when code does get involved with the conversation. In code each block of curly brackets is an object ( object{} ) and each variable with an = is a key ( key = value ). Keys contain information, and objects are associated with code, which runs on an object defines the the necessary keys and default values itself. While any keys can be passed to the object, the code must ask for that key for it to become part of the object. | ||
+ | |||
+ | For example: | ||
+ | |||
+ | cfg: | ||
+ | <pre> | ||
+ | PART | ||
+ | { | ||
+ | ... | ||
+ | MODULE | ||
+ | { | ||
+ | name = ModuleExample | ||
+ | key = value | ||
+ | other = value | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | code: | ||
+ | <pre> | ||
+ | ... | ||
+ | public class ModuleExample : PartModule | ||
+ | { | ||
+ | [KSPField] | ||
+ | public string key; | ||
+ | ... | ||
+ | } | ||
+ | ... | ||
+ | </pre> | ||
+ | |||
+ | In the code key would be refered to as this.key by ModuleExample, and object.key by things outside this exact instance of ModuleExample. Within the code there is no direct address for an instance of a module, there is an address for the code of the module but that's not usually useful, instances must be found and then have a reference to them created, | ||
+ | |||
+ | [KSPField] tells the code that the variable defined immediately afterwards should be read from the keys specified for that object in the cfg. In this example there is no default value for key, and key must contain a string, strings are pretty lenient since most anything you can put in a cfg file qualifies as a string; but if key was defined as an int and the cfg provided it with a string, this would cause problems. As an example, PART.cost is an integer, if the cfg specifies cost as 1,000 the comma makes that not valid as an integer. This will cause a situation sometimes referred to as a "Loader Crash", which is a failure in one of the steps of processing cfg files into parts that causes the loading step to immediately end, skipping any and all parts, objects, or keys that follow | ||
+ | |||
+ | In the cfg example, PART.MODULE{name} defines which code will act on the object, so changing it's value can entirely break or entirely change everything. | ||
+ | |||
= GameData = | = GameData = |
Revision as of 18:38, 23 April 2014
Contents
Conventions
KSP's cfg format can be difficult to converse about without getting into how the code works because the format is a direct reflection of the code, but also because it's not very regular and a lot of labels get used repeatedly for different meanings while a lot of meanings get labeled differently in various places; all the while there are misnomers abound and piles of deprecated things that may or may not still work.
For example
PART { MODEL { model = HexCans/Models/Rack position = 0.0, 0.0, 0.0 scale = 1.0, 1.0, 1.0 rotation = 0.0, 0.0, 0.0 texture = HexCan000, HexCans/Parts/HexProbe/Probe } MODEL { model = HexCans/Models/Pistons position = 0.0, 0.0, 0.0 scale = 1.0, 1.0, 1.0 rotation = 0.0, 0.0, 0.0 parent = Rack texture = HexCan000, HexCans/Parts/HexProbe/Probe } // --- general parameters --- name = HexDecouplerRackNormal module = Part author = Greys // --- asset parameters --- mesh = model.mu texture = hexcan.png scale = 1 rescaleFactor = 1 specPower = 0.3 rimFalloff = 3 alphaCutoff = 0 // --- general parameters --- node_attach = 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 2 node_stack_top = -0.035, 0.0, 0.0, 0.0, 1.0, 0.0, 1 attachRules = 1,1,1,1,1 // --- editor parameters --- cost = 200 category = Structural subcategory = 0 title = Decoupler Rack Normal manufacturer = PanSpace Manufacturing Inc. Ltd. LLC. Co. description = A small truss section for holding normal sized HexCans // --- general parameters --- mass = 0.04 dragModelType = default maximum_drag = 0.2 minimum_drag = 0.3 angularDrag = 2 crashTolerance = 18 breakingForce = 400 breakingTorque = 400 maxTemp = 2900 stageOffset = 1 childStageOffset = 1 stagingIcon = DECOUPLER_HOR MODULE { name = ModuleAnchoredDecoupler anchorName = Mounting_Rack ejectionForce = 600 explosiveNodeID = srf } }
The most obvious way to reference pieces of this format is to mimic it, such as PART{MODULE{scale}}, but this can be just as confusing and complicates the issue when code does get involved with the conversation. In code each block of curly brackets is an object ( object{} ) and each variable with an = is a key ( key = value ). Keys contain information, and objects are associated with code, which runs on an object defines the the necessary keys and default values itself. While any keys can be passed to the object, the code must ask for that key for it to become part of the object.
For example:
cfg:
PART { ... MODULE { name = ModuleExample key = value other = value } }
code:
... public class ModuleExample : PartModule { [KSPField] public string key; ... } ...
In the code key would be refered to as this.key by ModuleExample, and object.key by things outside this exact instance of ModuleExample. Within the code there is no direct address for an instance of a module, there is an address for the code of the module but that's not usually useful, instances must be found and then have a reference to them created,
[KSPField] tells the code that the variable defined immediately afterwards should be read from the keys specified for that object in the cfg. In this example there is no default value for key, and key must contain a string, strings are pretty lenient since most anything you can put in a cfg file qualifies as a string; but if key was defined as an int and the cfg provided it with a string, this would cause problems. As an example, PART.cost is an integer, if the cfg specifies cost as 1,000 the comma makes that not valid as an integer. This will cause a situation sometimes referred to as a "Loader Crash", which is a failure in one of the steps of processing cfg files into parts that causes the loading step to immediately end, skipping any and all parts, objects, or keys that follow
In the cfg example, PART.MODULE{name} defines which code will act on the object, so changing it's value can entirely break or entirely change everything.
GameData
All add-on files should be placed in the GameData folder, located in the root KSP folder alongside the KSP executable. Everything related to a given Add-on should be contained within a folder created specifically for that Add-on. Inside the dedicated folder, the directory structure is largely unimportant.
All of the stock parts are contained within GameData as well, and Squad uses this structure:
/Flags/ -- Flags must go here or they won't be loaded as flags, Capitalization Matters /Parts/Aero/ -- Aerodynamic parts /Parts/Command/ -- Command pods, probe cores, and reaction wheels /Parts/Electrical/ -- Parts that create and store electricity /Parts/Engine/ -- Engines /Parts/FuelTank/ -- Fuel Tanks /Parts/Structural/ -- Parts that don't do anything, and don't contain resources /Parts/Utility/ -- Parts that do things and don't contain resources (except some of them do) /Parts/Wheel/ -- Things that roll /Props/ -- Props are the functional little elements in IVAs /Resources/ -- This folder contains the file that declares all of the stock resources /Sounds/ -- Can you hear the love tonight /Spaces/ -- Spaces are IVAs
(This is just the way Squad does it, you can do it any way you want)
All assets will be loaded in a depth first alphabetic order, in sets based on file type. Parts will be displayed in the order they are loaded in.
Because of this parts located in /GameData/Squad/Parts/Utility/ will always be listed before those in /GameData/Squad/Parts/Wheel/, even if the wheel part's name is before the utility part's name alphabetically.
Aside from load order, the directory structure of /GameData/YourFolder/ only serves as an organizational tool for the developer.
.CFG Files
File type .cfg is used for every configuration file in KSP except persistence files, which are stored in .sfs, these files are simply disk-storable containers for Config Nodes and as such their names and locations are almost entirely insignificant. Each .cfg file will be addressed in depth-first alphabetical order based on it's position within /GameData/, relative to other .cfg files, and that is the extent of the value that a file's name has.
It is entirely possible to merge all of the top level config nodes of a given add-on pack into a single file, but this is likely to make working with that file much more difficult. It's generally accepted that the best practice is to have a single top level config node per file, or put a small number of closely related parts in a single file. For example, if you have a command pod you could have the PART{}, INTERNAL{}, any custom PROP{}s and any custom RESOURCE_DEFINITION{}s in a single file, but as far as KSP is concerned, having a part.cfg, internal.cfg, props.cfg, etc, in one folder is functionally the same thing.
Note that the .cfg file is not loaded into RAM. The config nodes in it are used to build code objects, and the variables are populated into those objects. As such, reducing the total number of files has zero impact on RAM usage.
Model Assets
There are only two model formats which KSP will load without outside forces, .MU, and .DAE
- .DAE is a legacy mode option and should not be used for a multitude of reasons, the first is that .DAE is much more complex to set up, and more finicky about what will work. You also don't have a lot of the options that you would have with .mu
- .MU is a compiled model format developed by our holy father Mu produced in Unity using PartTools. .MU files permit a large number options to be applied and changed, and stored inside the model itself. These include animations, manipulations to the texture sheets, customized and primative colliders, control over the shaders used on a part, and the inclusion of Transforms.
þ make 'Unity' and 'PartTools' links, give PartTools it's own page?
þ Transforms are maybe not relevant to this text
A Transform is a Unity Game Object in a specific place and with a specific orientation that is referenced by code to achieve many things, the Gimbal Transform is used to move an engine's nozzle mesh, which is a child of the transform, and the Thrust Transform is used as the coordinates and orientation to apply force to a part, RCS thrusters also use transforms for this.
Model assets can be located anywhere within /GameData/ and referenced by their address from .cfg files using MODEL{}, if not using MODEL{} they need to be in the same folder as the .cfg file.
Texture Assets
þ Phrasing may be confusing, perhaps omit that Unity can natively handle texture formats KSP doesn't recognize There are a lot of kinds of textures which can be used in KSP but only 3 formats are currently accepted by the loader, .MBM, .TGA, and .PNG
Once loaded the format you choose Does Not Matter, KSP will convert everything into DXT1 or DXT5 depending on the presence of an alpha channel (transparency), both of which are lossy formats. Both formats are direct bits-per-pixel formats so the actual content of those pixels is unimportant but because DXT5 has an alpha channel, it is directly twice as large as DXT1. KSP chooses the format based on the image so make sure you don't have unnecessary alpha channels.
- .TGA and .PNG are both editable, .MBM is technically editable, but it is not a format that graphics editing software will know what to do with, and you'll have to edit some stuff by hand before it can be opened.
- .MBM is uncompressed, and .TGA has very little compression but is a lossy format.
- .PNG is a very well compressed lossless format that allows for an alpha channel.
To repeat, the format of your files does not matter in game, it only impacts the amount of Data On Disk and the time it takes to read that data off the disk.
There are various programs available to edit PNG and TGA images like Paint.NET or GIMP. While Paint.NET's interface is easier that GIMP's, GIMP is not only available for Windows but also for Linux and Mac OS X.
Sound Assets
They're not broken, they're just weird.
Config Nodes
(Note to plugin developers, this document only pertains to .cfgs) Starting in KSP 0.15 a .cfg structure known as Config Nodes was introduced, and later in KSP 0.20.0 alongside the game database system and /GameData/ directory structure. Config Nodes, generally seen as any string of upper case letters, numbers[confirmation needed] and underscores followed by an opening curly bracket ( { ) and later a closing one are a means of having more complexly organized data inside a part's configuration.
Prior to KSP 0.20.0 all parts had to exist by themselves in a file specifically named 'part.cfg', limiting any one folder to containing only one part, and due to restrictions on addressing assets, every part had to have it's own textures and models.
Following the release of KSP 0.20.0 parts must exist inside a .cfg file with any name, and must be wrapped in a PART{} config node. You are permitted to have multiple PART{}s in any given file, and the means of addressing assets has changed to be relative, treating /KSP/GameData/ as the root of any address.
Between the curly brackets of a config node you are able to define variables, their values, and other config nodes so long as they exist in that context. For an example:
PART{ name = Example title = Superfly description = These are variables, they are case sensitive and the code defines what that case is you = can define anything you want, but the code in game is only going to use what it needs. banana = is a fully valid variable, that will not be used by anything in KSP not = every key or config node uses a reliable capitalization scheme so if you're having problems, double check your case RESOURCE{ name = LiquidFuel amount = 400 } MODULE{ name = etc } }
It is important to note that everything in KSP is Case Sensitive, from the variables and values in a .cfg file, to the names of asset files and folders. The capitalization scheme of keys and config nodes is defined entirely by the code that will use it, RESOURCE{} and Resource{} are not the same thing, and the later will do nothing, but also RESOURCE{Name=LiquidFuel} is not valid. Unfortunately within KSP there is no singular capitalization scheme to fall back on. "Generally" Config Nodes are in ALL CAPS, sometimes they're in lowerCamelCase, but you always have to follow the code, or it won't work.
Proper tabulation in .cfg files is not necessary, but extremely useful in maintaining readability of complex configurations and will help to make sure all your config nodes are closed properly.
Keys
The order of keys in a .cfg file is completely unimportant. All config nodes and keys are loaded in one solid step, before any other code is given the chance to access the data, as such all of the information in a .cfg file is available to the code immediately. It will not occur that one thing doesn't load right because some piece of information has not been loaded yet. Organize your configurations as you see fit.
What does matter is the kinds of information that the code expects a key to contain. Also, Capitalization Always Matters. In both Keys and Values, if it's not capitalized the right way, it won't do what you want. This becomes problematic because KSP's capitalization scheme is rather inconsistent.
þ This table will likely need multiple revisions to achieve an optimal representation of the truth in a form that conveys the information adequately.
Data Type | Something | Example |
---|---|---|
Integer | A Number without decimal values and without any formatting | 40008 |
Float | A number with decimal values but still no formatting | 40.008 |
Text | Plain text | Hi, my name is Guacamole, and I'm stealing your car right now. |
Identifier | A set of letters and numbers, capital or lower case, without spaces or punctuation (exceptions...) | SmallGearBay |
Address | An address relative to /KSP/GameData/ (always use /, never \) | /Squad/Parts/Engine/liquidEngine2-2/ |
List | A set of comma separated values, usually integers or floats | 0.00, 0.147, 0.00, 0.0, 1.0, 0.0, 1 |
Binary | A 0 or 1 indicating a yes or no to enable or disable certain things | 1 |
Vector | A list of 3 values, X, Y, and Z, used to describe coordinates, orientations, and complex scales | 4.743, 7.853, 0.042 |
The format of defining a key and it's value is as follows regardless of the data being contained within it. No line end marker is necessary.
Key = Value
The keys you set in a .cfg files don't fit into many clear cut groups, some related to visual assets, some relate to aspects of that part in the world, but most of them fit into several groups, are used at various levels, and don't really do quite what you think. In the following tables they've been roughly organized by category as a factor of what they do, not where they're used.
Stock Config Nodes
Top Level Config Nodes
Node | Used For |
---|---|
PART{} | Defines a new part |
RESOURCE_DEFINITION{} | Defines a new resource to be used in and by PART{}s |
INTERNAL{} | Defines an internal space which can be used by PART{}s |
PROP{} | Defines an prop, a functional self contained element, which can be used in INTERNALS{} |
PART{} Config Nodes
RESOURCE{} Sets a resource and quantity of resource for a part to contain
Key | Data Type | What it does |
---|---|---|
name | Identifier | The Resource the part will contain |
amount | Float | The amount of resource the part will initially contain, will be rounded down to maxAmount if greater, so no overcharging. |
maxAmount | Float | The amount of resource the part can contain |
MODEL{} Alternate to mesh and texture variables, gives much better control but has some bugs
Key | Data Type | What it does |
---|---|---|
parent | (Optional) Specifies what hierarchical element to append this model onto | |
model | Address | The model file (file.mu) that you wish to add to a part |
texture | List | The texture you want to replace, comma, the address of the texture you want to replace it with |
position | Vector | Offset from 0,0,0 in meters |
rotation | Vector | Rotation along X,Y,Z (Units unconfirmed) |
scale | Vector | Modifies the scale of the model along each of the three axis. 1=1:1 scale, 2=2:1 scale, etc |
ATTACH{} Alternate to node_ definitions, very buggy, generally not used because of problems
MODULE{} Used to associate functionality with a part by linking a partModule to the PART{} instance
Part Modules
þ Merge into Config Nodes -> Stock Config Nodes -> PART{MODULE{}} þ Several available partModules deserve their own pages, explaining them sufficiently in this page would be unnecessary clutter.
PART Keys
Key | "Category" | Data Type | What it does |
---|---|---|---|
name | Internal | Identifier | Internal designation of the part used by code |
title | Label | Text | External designation of the part used by players |
author | Label | Text | The names of the people who made it, often involved with add-on licensing |
category | Label | Identifier | Determines which tab of the VAB/SPH the part appears in; choose only one. |
manufacturer | Label | Text | Flavor text presented to the player, displays in a limited space |
description | Label | Text | Flavor text presented to the player, can be used to explain use of a part |
cost | Label | Integer | Representation of the value of a part in an undefined currency, not used by stock but used by some add-ons and challenges |
subcategory | Internal | Integer | Supposedly unused value for further sorting parts |
scale | Asset | Float | !!! Functionality of this key has become ambiguous |
rescaleFactor | Asset | Float | A value used to manipulate the size of models after the fact, usually for reusing elements without needing to remake, or being able to remake the model differently |
mass | Physical | Float | The mass of the part, note, weight is a function of local gravity, so your Thrust to Weight ratio will vary by where you are, but your mass varies by how much resources you have. |
maxTemp | Physical | Integer | The temperature at which the part will explode to death |
crashTolerance | Physical | Integer | How hard the part can hit the ground and not explode |
breakingForce | Physical | Integer | The linear force at which a joint between two parts will fail, and the two parts will no longer be joined. |
breakingTorque | Physical | Integer | The rotational force at which a joint between two parts will fail, and the two parts will no longer be joined. |
PhysicsSignificance | Physical | Binary | If 1, the part doesn't really exist, doesn't have mass, drag, temperature, and can't do a bunch of other stuff. |
specPower | Asset | Float | The specular reflectivity of your part. It's best to leave it as it is. |
rimFalloff | Asset | Float | This defines the strength of the highlight effect in game. Higher values lead to a more pronounced effect near the edges. |
alphaCutoff | Asset | Float | This number defines the threshold for transparency on the part's texture. If your texture has an alpha channel (transparency), you can adjust this number to make sure your part is transparent or opaque where it should be. A value of 0 means nothing in the texture is considered to be transparent. A value of 1 means a completely transparent part. |
dragModelType | Physical | ??? | Which atmospheric drag model to use, always use "default" |
maximum_drag | Physical | Float | The maximum drag value |
minimum_drag | Physical | Float | The minimum drag value |
stageOffset | Internal | Integer | |
childOffset | Internal | Integer | |
fuelCrossFeed | Internal | Binary | Whether fuel will cross through the part at all (Only stack attachment nodes can crossfeed) |
NoCrossFeedNodeKey | Internal | ??? | Disables fuel crossfeed over a specific stack node |
stageOffset and childStageOffset - Can be 0, 1, etc. defines whether this part will create a new stage before or after itself, or both (as do decouplers). This only applies for the automatically generated staging sequence. These replace stageBefore and stageAfter.
Node_s
Another fairly easy section, this defines where we attach our part to other parts. You can have as many as you want, for example, tricouplers have four, three bottom and one top, while most parts simply have two, and a few parts have only one.
node_stack_bottom = x, y, z, angx, angy, angz, size node_stack_top = x, y, z, angx, angy, angz, size node_attach = x, y, z, angx, angy, angz, size
There's three example nodes. There are three different kinds, but only two are useful to us at the moment. We have node_stack and node_attach. Node stack is for defining where the part stacks vertically together with other parts, and node attach is used for defining where on the surface of your part other parts attach - so horizontal attachment.
All node attachment values are given with respect to an object's origin, and their values correspond to a model's units and scaling factors. A node_stack_bottom with x, y, and z values of (2.5, 5.0, 3.0) will have an attachment node 2.5 units to the right, 5.0 units up, and 3.0 units forward. The next three values refer to the orientation that a particular node will accept other attachments, on a scale of -1.0 to 1.0. These represent the vector that a part will orient itself on when attaching to the node. For example, a fuel tank with a node_stack_bottom will have angx, angy, and angz values of (0.0, -1.0, 0.0). This represents a vector downward relative to the part model, in the negative y direction. A value of (0.0, -1.0, 1.0) would represent a diagonal vector downward and forward, while a value of (1.0, 1.0, 1.0) would represent a vector to the right, up, and forward.
Generally, most parts will have angx, angy, and angz values of either (0.0, -1.0, 0.0) for a node_stack_bottom and (0.0, 1.0, 0.0) for a node_stack_top.
The last value indication the visual size of an attachment node. Values may be either 0 (small half-meter node), 1 (normal), or 2 (large). This parameter is optional and will default to 1 if nothing is specified. Keep in mind, naming conventions (_stack_bottom, _stack_top) for nodes only apply to node_attach; they are only helpful in identifying a node's position.
Attachment rules:
þ table This defines how your part attaches to other parts.
- // attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision
- attachRules = 1,1,1,1,1
The rules correspond to the numbers below - 1 is allow, 0 is prevent. The tags are:
stack - Can your part be stacked on others?
SrfAttach - Can your part be placed onto a surface?
allowStack - Will you allow other parts to be stacked on your part?
allowSrfAttach Can other parts be placed on the surface of yours?
allowCollision - A special one: Can your part be placed if part of it is intersecting another part?
Note that you can also force parts attached to this part to attach in a specific symmetry.
- // symmetry rules: 0=1x, 1=2x, 2=3x, 3=4x and so on...
- stackSymmetry = 3
FX definitions:
More definitions! But this time, you're positioning the flame coming out the back of the rocket.
fx_exhaustFlame_yellow = x, y, z, angx, angy, angz, active fx_exhaustLight_yellow = x, y, z, angx, angy, angz, active fx_smokeTrail_medium = x, y, z, angx, angy, angz, active
Okay, looks pretty similar to node_definitions, right?
You'll notice, just like node definitions, there are separate parts to each effect. You have fx_exhaustFlame, fx_exhaustLight, and fx_smokeTrail.
There are exactly what they sound like, the flame, the light, and the smoke trail.
There are variations on flame color, blue is also an option. To get a blue flame, you would use fx_exhaustFlame_blue. You would do the same for the exhaustLight.
The 'active' switch on the end is used to define when this effect will be visible. See the FX Groups listing to know which effect groups are available, and when they are used. It's also possible to assign an effect to more than just one FX Group. If for instance, you want a smoke effect to be visible both when the part activates and also when it deactivates itself, you can do this:
fx_gasBurst_white = x, y ,z, angx, angy, angz, activate, deactivate
Scaling
Due to a series of bugs introduced in 0.20 and 0.21 scaling is not as simple is it should be. These bugs have not yet been properly quantified but revolve around MODEL{scale}, scale, and rescaleFactor
- Bug #1, PART{scale} is impacting the entire part, not just the mesh.
PART{scale} exists to correct mesh that are not in 1m scale. This includes parts that are in say, 1cm scale, or parts that are in imperial units. The mesh is multiplied by this value to result in 1m scale, so a mesh in 1cm scale would have PART{scale=0.01}. This is because KSP/Unity assumes everything to be in meter scale regardless so that 1cm scale part ends up being ten times larger than intended.
Scale is not supposed to change the scale of anything else. Starting in ___ scale is being applied to the entire part, namely including the nodes. This means that if your model is in the wrong scale, you will have to position your nodes in that wrong scale and they will be fixed alongside the mesh. Normally PART{rescaleFactor} is used to rescale the part, so you correct the mesh with scale, place the nodes in 1m coordinates, and change them both with rescaleFactor. Effectively due to this bug, scale and rescaleFactor do the same thing.
It is best to make sure your models are in proper 1m scale to begin with, and always leave scale=1 (scale does not default to 1)
- Bug #2, rescaleFactor v. MODEL{scale}
þ Finish this
Modules
So what part types can you have? þ Reorder rows based on frequency of use: Part, Winglet ControlSurface, HLandingLeg, FuelLine, Strut
Part Name | Description |
---|---|
ControlSurface | Movable wing-like surface. Can act as a rudder, aileron, elevator, canard or other aerodynamic control surface - function depends on placement on a ship. |
Winglet | A lift producing part. Not movable. |
StrutConnector | Used for making struts (the space ducttape kind) |
FuelLine | Allows for transfer of fuel. |
HLandingLeg | A moving landing leg, using .cfg parameters to move. |
Part | This module should be used for all parts except for a few specific instances where the module has not yet been replaced with a partModule
|
Module Settings
þ merge with Modules section
We're almost finished, a complete part is almost at our hands and you should know almost everything you need to create a part.cfg file. However, remember back when we were setting types? Well each type has an individual set of specific part parameters that change depending on what type of part it is.
You cannot mix and match parameters from different module types - it doesn't work.
These specific parameters are actually public variables defined in the Part classes themselves. The standard parameters are declared in the Part base class, and the specific ones in each Part extension (i.e., Modules)
Time to go through and see what special parameters each module can have.
Winglets
- þ Make this a table
dragCoeff - The drag co-efficiency of the wings.
deflectionLiftCoeff - How much lift the wings generate.
Control Surfaces
- þ Make this a table
ctrlSurfaceRange - How far off centre the control surface (rudder / aileron etc) can move under control
ctrlSurfaceArea - The effective surface area of the control surface - the bigger the surface, the bigger the surface area must be set to