# MAPI Documentation
//Someone add a brief description of the MAPI and links to it here. -Swept
[Precompiled 0MultiplayerAPI.dll](https://www.nuget.org/packages/RimWorld.MultiplayerAPI/)
### A Small Example
In this section, we're going to focus on the basics of the api. Specifically, we're going to enable a mod for Multiplayer.
#### The boilerplate
By the time RimWorld reaches your mod the API is ready to use, you can call it wherever you see fit. See basic C# mod tutorials. The easiest place is `[StaticConstructorOnStartup]`
The following is the most basic boilerplate code.
```csharp=
using Multiplayer.API;
using Verse;
namespace MyExampleMod
{
[StaticConstructorOnStartup]
public static class MyExampleModCompat
{
static MyExampleModCompat()
{
if (!MP.enabled) return;
// This is where the magic happens and your attributes
// auto register, similar to Harmony's PatchAll.
MP.RegisterAll();
// You can choose to not auto register and do it manually
// with the MP.Register* methods.
// Use MP.IsInMultiplayer to act upon it in other places
// user can have it enabled and not be in session
}
}
}
```
That's all! You are done.
### More Examples
The [Multiplayer Compatibility Project](https://github.com/notfood/RimWorld-Multiplayer-Compatibility)
### Fields
Well... sometimes you aren't that lucky. Sometimes you want to change a specific Field. For those scenarios there is the `MP.Watch*` methods. Basically, at the beginning of the operation you take a snapshot of the Field value and then compare it later. MPAPI checks them if they need to broadcast it and then spreads the change accordingly.
```csharp=
...
[HarmonyPatch(typeof(RimWorldWindowClass), nameof(DoWindowContents))]
static class RimWorldWindowClass_DoWindowContents_Patch
{
// Draw a 160x16 slider in RimWorldWindowClass
static void Postfix(Rect inRect)
{
if (MP.IsInMultiplayer) {
MP.WatchBegin(); // Let's being watching
// This is here to set the variable if it changed on other clients
// It will update the variable and the logic will stay the same.
MP.Watch(instance, nameof(instance.weight));
}
Rect sliderRect = new Rect(inRect.x, inRect.y, 160f, 16f);
instance.weight = GUI.HorizontalSlider(sliderRect, instance.weight, -10f, 10f);
if (MP.IsInMultiplayer) {
MP.WatchEnd(); // We are done watching!
}
}
static MyObject instance = new MyObject();
class MyObject {
[SyncField]
public float weight;
}
}
...
```
That's all! So easy! Is it?
### Gizmos
Oh dear! Oh deity no no--- NO- Pray you aren't dealing with them with Reflection. See the Examples for dark magic. But if it's your own code, just move the Action delegate to a method anywhere and tag it with `[SyncMethod]`.
### Sync Workers
Sometimes, when you use [SyncMethod], you will encounter...
```
Error writing type: MyType, ... Multiplayer.Client.SerializationException: No writer for type MyType
```
MPAPI needs to know how to reference your type to send it to the other clients. Basically if you have...
```csharp=
[SyncMethod]
static MyReturnType MyMethod(MyArgumentType arg1, MyArgumentType2 arg2, int arg3, float arg4) { ... }
```
You need to teach MPApi to handle your types, so they can send them over the wire to the other players. For our example, we will need to write a SyncWorker for `MyReturnType`, `MyArgumentType` and `MyArgumentType2`, most of RimWorld types are already handled so don't be afraid to use them.
Assuming `MyReturnType` is made of `aString`, `anInt` and `aFloat`, here is how you write a SyncWorker for it:
```csharp=
[SyncWorker(shouldConstruct = true)]
static void SyncMyReturnType(SyncWorker sync, ref MyReturnType type) {
sync.Bind(type.aString);
sync.Bind(type.anInt);
sync.Bind(type.aFloat);
}
```
Bind does the writing and reading for you, `shouldConstruct` makes it so type is constructed before being passed to the SyncWorker (not needed for structs). But if you need more complex situations, you can use Write and Read.
Assuming `MyArgumentType` requires an argument `Pawn` to construct, you'd write it this way:
```csharp=
[SyncWorker]
static void SyncMyArgumentType(SyncWorker sync, ref MyArgumentType type) {
if (sync.isWriting) {
sync.Write(type.Pawn);
} else {
Pawn pawn = sync.Read<Pawn>();
type = new MyArgumentType(pawn);
}
}
```
*Todo migrate the rest of the API doc
https://github.com/Parexy/Multiplayer/wiki/API#mp