Modding:Modder Guide/APIs/Multiplayer

From Stardew Valley Wiki
Jump to: navigation, search
Modder's guide to creating mods SMAPI mascot.png

The multiplayer API provides methods to support modding in a multiplayer context. This API is still minimal, but much more will be added in later versions of SMAPI.

Methods

Get new ID

In some cases the game expects a 'multiplayer ID' value, which is a unique 64-bit number. This is mainly intended for cases where the game expects a multiplayer ID for data sync, such as when creating farm animals:

int animalID = this.Helper.Multiplayer.GetNewID();
var animal = new FarmAnimal("Cow", animalID, ownerID);

Get active locations

In multiplayer mode, the game doesn't sync all locations to other players. Each farmhand will receive data for their current location, the farm, farmhouse, and farm buildings. You can get a list of the locations being sync'd:

foreach (GameLocation location in this.Helper.Multiplayer.GetActiveLocations())
{
   // do stuff
}

Get connected player info

You can see basic info about other players connected to the same server using the GetConnectedPlayer(playerID) and GetConnectedPlayers() methods. This is available immediately when the player connects (before the game even approves the connection). Most of the information is only available for players who are running SMAPI too. You can access these fields for each player:

field type description
PlayerID long The player's unique multiplayer ID, which you can pass to game methods and fields that expect a unique player ID.
IsHost bool True if this player is hosting the server; false if they're a farmhand.
HasSmapi bool Whether this player has SMAPI installed.
Platform GamePlatform (Requires SMAPI.) The player's operating system as a GamePlatform enum (one of Linux, Mac, or Windows).
GameVersion ISemanticVersion (Requires SMAPI.) The version of the game they have installed (like 1.3.31).
ApiVersion ISemanticVersion (Requires SMAPI.) The version of SMAPI they have installed (like 2.8).
Mods IEnumerable<IMultiplayerPeerMod> (Requires SMAPI.) The mods they have installed. Each mod includes the name, unique ID, and version.
GetMod(id) method returns IMultiplayerPeerMod (Requires SMAPI.) A method which returns the mod with the given mod ID using the same case-insensitivity rules as SMAPI, if available. For example, this can be used to check if a mod is installed: if (peer.GetMod("Pathoschild.ContentPatcher") != null).

For example, this will log information about the currently connected players:

foreach (IMultiplayerPeer peer in this.Helper.Multiplayer.GetConnectedPlayers())
{
    if (peer.HasSmapi)
    {
        // prints something like: "Found player -1634555469947451666 running Stardew Valley 1.3.31 and SMAPI 2.8-beta.5 on Windows with 41 mods."
        this.Monitor.Log($"Found player {peer.PlayerID} running Stardew Valley {peer.GameVersion} and SMAPI {peer.ApiVersion} on {peer.Platform} with {peer.Mods.Count()} mods.");
    }
    else
    {
        // most info not available if they don't have SMAPI
        this.Monitor.Log($"Found player {peer.PlayerID} running Stardew Valley without SMAPI.");
    }
}

Note: players whose connections haven't been approved by the game yet are returned too. Although you can send/receive messages through SMAPI's APIs, the game itself may not know about them yet. If you only want players who are fully connected, you can do something like this instead:

foreach (Farmer farmer in Game1.getOnlineFarmers())
{
   IMultiplayerPeer peer = this.Helper.Multiplayer.GetConnectedPlayer(farmer.UniqueMultiplayerID);
}

Send messages

You can send a message to mods on other players' computers using the SendMessage method. The destination can range from very narrow (e.g. one mod on one connected computer) to very broad (all mods on all computers).

When sending a message, you must specify three things:

  • A data model, which contains the data you want to send. This can be a simple value (like a number or string), or a class instance. When using a class instance with custom constructors, make sure it has a default constructor too.
  • A message type, so the destination mods can know which message it is. This doesn't need to be globally unique, since mods should check the originating mod ID.
  • Who should receive the message. You can specify any combination of player IDs and/or mod IDs. By default, the message is sent to all mods and players.

For example:

// broadcast a message to all mods on all computers
MyMessage message = new MyMessage(...); // create your own class with the data to send
this.Helper.Multiplayer.SendMessage(message, "MyMessageType");
// send a message to a specific mod on all computers
MyMessage message = new MyMessage(...);
this.Helper.Multiplayer.SendMessage(message, "MyMessageType", toModIDs: new[] { this.ModManifest.UniqueID });

Receive messages

You can receive messages by listening to the helper.Multiplayer.ModMessageReceived event. Within your event handler, the event arguments specify who sent the message and let you read the message into a matching data model:

public void OnModMessageReceived(object sender, ModMessageReceivedEventArgs e)
{
   if (e.FromModID == "ExpectedModID" && e.Type == "ExampleMessageType")
   {
      MyMessageClass message = e.ReadAs<MyMessageClass>();
      // handle message fields here
   }
}

See also