Add message exchange API
Pathoschild opened this issue ยท 2 comments
Create some sort of mechanism for inter-mod communication. This has been requested a few times, but needs further research.
This was extensively discussed in the #modding
channel in the Stardew Valley Discord. Here's what we came up with.
Intent
- We want to let mods send notifications, push messages, or exchange information with other mods.
- This should be easy to understand, use, and troubleshoot for mod authors.
- We do not want a message exchange with built-in support for every possible case. That would become far too complicated and difficult to understand. Instead we should make the common cases simple, and have a mechanism to support more complicated edge cases.
Goals
We aim to support three use cases:
- Publish/subscribe: mod publishes an event that any mod can listen for.
- Push: mod creates a channel that other mods can push to, and it'll listen for data it receives.
- Exchange: any number of mods exchange information on a common channel. This would mainly handle more complex cases.
For example, mods using Advanced Location Loader might publish aFunc<Vector2, bool>
callback to anEntoarox.AdvancedLocationLoader.Intent
channel, which they use to check whether another ALL mod has 'reserved' a tile for modification. Exchanging callbacks would allow them to perform this check synchronously, without waiting for an asynchronous message.
Message exchange API
Concept
SMAPI would expose a simple message exchange API that lets mods publish messages via a channel, which is a unique ID used to publish or subscribe. Here's the most basic exchange possible:
// mod #1 listens for messages on a channel
helper.MessageExchange.Subscribe("Namespace.UniqueChannelName", this.HandleMessage);
// mod #2 publishes a message that mod #1 receives
helper.MessageExchange.Publish("Namespace.UniqueChannelName", message);
Reserving a channel
Channels may optionally be reserved, which means one mod has ownership of that channel and can specify the following:
- A contract/datatype that is accepted. Any message published with a different contract is rejected.
- Whether other mods can publish messages to it.
- Whether other mods can listen to it.
Supported operations
This API would support three operations:
- Reserve a channel and specify its metadata.
- Publish a message to a channel ID. If the channel is reserved, its options are enforced; otherwise the message is published as-is to any listener.
- Listen for messages from a channel ID. If the channel is reserved, its options are enforced; otherwise the mod just receives any message sent to that channel ID as-is.