# AttachNodeMover

`AttachNodeMover` repositions existing attach nodes for a variant without creating new ones.

## Purpose

Use this transformer when the node already exists on the base part and a variant only needs to shift that node to a new location. This is the lighter-weight option when you do not need a new dynamic node definition.

## Type

Source-backed runtime type: `VSwift.Modules.Transformers.AttachNodeMover`

## Fields

* `MovedNodes`: `Dictionary<string, Vector3d>`
* Each dictionary key is an existing node tag such as `top`, `bottom`, or another predefined node name

## Behavior

* `ApplyCommon`: no effect
* `ApplyInOab`: looks up each named node on the OAB part and updates its local position if the node exists
* `ApplyInFlight`: no effect

## State handling

* Reverter: yes, via `PredefinedNodeReverter.Instance`
* Saves information: no
* Visualizes information: no

## Example

```patch
@use "VSwift:*"

@parts {
  #my_tank_part {
    @include part-switch() {
      VariantSets +: [{
        VariantSetId: "length",
        VariantSetLocalizationKey: "MyMod/VSwift/Length",
        Variants: [{
          VariantId: "extended",
          VariantLocalizationKey: "MyMod/VSwift/Extended",
          Transformers: [{
            Name: "AttachNodeMover",
            MovedNodes: {
              top: { x: 0, y: 0.45, z: 0 },
              bottom: { x: 0, y: -0.45, z: 0 }
            }
          }]
        }]
      }];
    }
  }
}
```

## Caveats

* This transformer only moves nodes that already exist. Missing nodes are ignored.
* It changes position only. It does not add nodes, change node size, or change orientation.
* Because it is OAB-only, it should be paired with generated-part-data behavior only when the final craft definition must remember the resulting variant choice.

## Related

* [AttachNodeAdder](https://docs.ksp2redux.org/doc/attachnodeadder-LL5IbEMKY8)
* [Rulesets, Selectors, and Selection Blocks](https://docs.ksp2redux.org/doc/rulesets-selectors-and-selection-blocks-Gu3aJrvSmY)