# Part modules

A part's behavior comes from its modules: `Module_Engine` makes it an engine, `Module_Deployable` makes it deploy, `Module_Drag` gives it drag, and so on. To change how a part behaves, you reach its module and edit the [data](/doc/module-data-OTSWqA1Rgt) inside it. This page covers getting at the modules themselves.

## Reading a module that is there

If you know a part already has a module, you can reach it as a property named after the module, straight off the part. This real patch dives two levels in one expression:

```lua
PM.Parts:Patch("InflatableHeatShieldHeatTolerance")
        :Named("heatshield_2v_inflatable")
        :Do(function(part)
            part.maxTemp = 3000.0
            part.Module_Deployable.Data_Deployable.deployMaxTemp = 3500.0
        end)
```

`part.Module_Deployable` is the module, `.Data_Deployable` is the [data](/doc/module-data-OTSWqA1Rgt) inside it, and `.deployMaxTemp` is the field. Property access is the most direct route when you are confident the module exists.

## The safe methods

When a module may or may not be present, or you want to add one, use the helper methods. They follow the [shared pattern](/doc/typed-modules-nMMO0SZ6ac):

* `part:AddModule(name, callback)` adds a new module and errors if it already has one.
* `part:PatchModule(name, callback)` edits an existing module, doing nothing if it is absent.
* `part:EnsureModule(name, callback)` adds it if missing or patches it if present.
* `part:RemoveModule(name)` removes it.
* `part:HasModule(name)` tests for it.

The callback receives the module, and you configure it there. `PatchModule` is the everyday choice for editing, since it does nothing when the module is not there instead of erroring:

```lua
PM.Parts:Patch("GridFinSASControl")
        :Named("gridfin_1v_radial", "gridfin_2v_radial")
        :Do(function(part)
            part:PatchModule("Module_ControlSurface", function(module)
                module:PatchData("Data_ControlSurface", function(data)
                    data.IgnoreSASInputs = false
                end)
            end)
        end)
```

## Adding a module a part does not have

`AddModule` gives a part a module it lacked. The callback fills it in, usually by adding the data the module needs. This real patch gives a docking port resource capacities it did not ship with:

```lua
PM.Parts:Patch("DockingPortResourceCapacities")
        :Named("dockingport_2v_m2_inline_sideport")
        :Do(function(part)
            part:AddModule("Module_ResourceCapacities", function(module)
                module:AddData("Data_ResourceCapacities")
            end)
        end)
```

## Module names

Modules are named `Module_<Something>`: `Module_Engine`, `Module_Deployable`, `Module_Drag`, `Module_ControlSurface`, `Module_Fairing`, and so on. That is the name you pass to the methods and the property you read. The set of available module names comes from the game, and your editor's autocomplete (from `pm-parts.d.lua`) will offer the ones it knows about once you start typing inside a part callback.

## Next

The module is just a container. The numbers you usually want to change live in its data entries, covered in [Module data](/doc/module-data-OTSWqA1Rgt).