A new version of the mod framework was just released! This adds a bunch of new stuff mods can take advantage of:
1. Data storage! Mods can now store data in a game that will be persisted for the lifetime of that game. This allows mods to remember things, such as who is allied with who, what turn the zombies break out, or what each AI is thinking, etc.
Mods can store this data in three buckets. Mod.PublicGameData stores public information that is shared with players in the game (plus spectators), Mod.PrivateGameData is not shared with any players and is only readable by the mod, and Mod.PlayerGameData is shared only to specific players the mod deems worthy of each piece of information.
2. Custom messages! Mods can now communicate between the client and server at will, instead of having to wait for a turn to advance like before. A client can, at any time, initiate a call to the server by calling Game.SendGameCustomMessage. The server can then handle that call with the new server hook, Server_GameCustomMessage.
3. Mods can now use the new Client_GameRefresh hook to run code whenever the client gets new data about a game from the server. This includes when the Server_GameCustomMessage hook changes some stored data clients can see. See https://www.warlight.net/wiki/Mod_Hooks
4. More improvements!:
- Mods can now store tables into the Mod.Settings object, as well as the new data storage buckets.
- Mods can now see each player's income by calling the GamePlayer.Income function.
- Mods can now call Game.CreateDialog in client hooks to create new windows, similar to what the menu button did previously.
- Mods that use the Client_PresentMenuUI hook now get passed a 5th argument which is a callback to close the dialog.
I have written a new example mod, the Diplomacy mod, to show off these features. Its code can be seen here: https://github.com/FizzerWL/ExampleMods/tree/master/DiplomacyMod
The way it works is that whenever a player (A) proproses an alliace with another (B), it sends a custom message to the server. The server then writes the proposal into player B's Mod.PlayerGameData, so only they know about it.
Then, the Client_GameRefresh hook is invoked on player B's client. It can read the proposal and ask the player if they accept or not. B's client then sends another custom message, with either AcceptProposal or RejectProposal. If it's rejected, it's simply removed from B's GamePlayerData. If it's accepted, it's removed and also written into Mod.PublicGameData as an alliance.
Writing into Mod.PublicGameData invokes a refresh on all player's clients, so everyone gets a pop-up message letting them know about the alliance.
Then in the Server_AdvanceTurn_Order hook, we simply skip attacks between players who are allied (similiar to how the Safe Start mod works). Finally, in Server_AdvanceTurn_End, we remove alliances that have expired.
This is a simple example of how to write a diplomacy mod. It could be improved with many more features, such as breaking alliances, stopping cards attacks, sharing armies, etc. The possibilities are endless!