Difference between revisions of "Modding:Migrate to SMAPI 3.0"
Pathoschild (talk | contribs) (→Event changes: + GameLoop events) |
Pathoschild (talk | contribs) (→Event changes: update) |
||
Line 107: | Line 107: | ||
| <tt>GameEvents.EighthUpdateTick</tt> | | <tt>GameEvents.EighthUpdateTick</tt> | ||
| → | | → | ||
− | | <tt>GameLoop. | + | | <tt>GameLoop.UpdateTicked</tt> |
| | | | ||
* Check if <tt>e.IsMultipleOf(8)</tt>. | * Check if <tt>e.IsMultipleOf(8)</tt>. | ||
Line 113: | Line 113: | ||
| <tt>GameEvents.FirstUpdateTick</tt> | | <tt>GameEvents.FirstUpdateTick</tt> | ||
| → | | → | ||
− | | <tt>GameLoop. | + | | <tt>GameLoop.GameLaunched</tt> |
− | | The new event is raised before the first update tick. To do something ''after'' the first update tick, use <tt>GameEvents. | + | | The new event is raised before the first update tick. To do something ''after'' the first update tick, use <tt>GameEvents.UpdateTicked</tt> with <tt>if (e.Ticks == 1)</tt>. |
|- | |- | ||
| <tt>GameEvents.FourthUpdateTick</tt> | | <tt>GameEvents.FourthUpdateTick</tt> | ||
| → | | → | ||
− | | <tt>GameLoop. | + | | <tt>GameLoop.UpdateTicked</tt> |
| | | | ||
* Check if <tt>e.IsMultipleOf(4)</tt>. | * Check if <tt>e.IsMultipleOf(4)</tt>. | ||
Line 124: | Line 124: | ||
| <tt>GameEvents.HalfSecondTick</tt> | | <tt>GameEvents.HalfSecondTick</tt> | ||
| → | | → | ||
− | | <tt>GameLoop. | + | | <tt>GameLoop.UpdateTicked</tt> |
| | | | ||
* Check if <tt>e.IsMultipleOf(30)</tt>. | * Check if <tt>e.IsMultipleOf(30)</tt>. | ||
Line 131: | Line 131: | ||
| <tt>GameEvents.OneSecondTick</tt> | | <tt>GameEvents.OneSecondTick</tt> | ||
| → | | → | ||
− | | <tt>GameLoop. | + | | <tt>GameLoop.UpdateTicked</tt> |
| | | | ||
* Check if <tt>e.IsOneSecond</tt>. | * Check if <tt>e.IsOneSecond</tt>. | ||
Line 138: | Line 138: | ||
| <tt>GameEvents.QuarterSecondTick</tt> | | <tt>GameEvents.QuarterSecondTick</tt> | ||
| → | | → | ||
− | | <tt>GameLoop. | + | | <tt>GameLoop.UpdateTicked</tt> |
| | | | ||
* Check if <tt>e.IsMultipleOf(15)</tt>. | * Check if <tt>e.IsMultipleOf(15)</tt>. | ||
Line 145: | Line 145: | ||
| <tt>GameEvents.SecondUpdateTick</tt> | | <tt>GameEvents.SecondUpdateTick</tt> | ||
| → | | → | ||
− | | <tt>GameLoop. | + | | <tt>GameLoop.UpdateTicked</tt> |
| | | | ||
* Check if <tt>e.IsMultipleOf(2)</tt>. | * Check if <tt>e.IsMultipleOf(2)</tt>. | ||
Line 151: | Line 151: | ||
| <tt>GameEvents.UpdateTick</tt> | | <tt>GameEvents.UpdateTick</tt> | ||
| → | | → | ||
− | | <tt>GameLoop. | + | | <tt>GameLoop.UpdateTicked</tt> |
| Equivalent. | | Equivalent. | ||
|- | |- | ||
Line 272: | Line 272: | ||
| <tt>SaveEvents.AfterCreate</tt> | | <tt>SaveEvents.AfterCreate</tt> | ||
| → | | → | ||
− | | | + | | <tt>GameLoop.SaveCreated</tt> |
− | | | + | | Equivalent. |
|- | |- | ||
| <tt>SaveEvents.AfterLoad</tt> | | <tt>SaveEvents.AfterLoad</tt> | ||
| → | | → | ||
− | | | + | | <tt>GameLoop.SaveLoaded</tt> |
− | | | + | | Equivalent. |
|- | |- | ||
| <tt>SaveEvents.AfterReturnToTitle</tt> | | <tt>SaveEvents.AfterReturnToTitle</tt> | ||
Line 287: | Line 287: | ||
| <tt>SaveEvents.AfterSave</tt> | | <tt>SaveEvents.AfterSave</tt> | ||
| → | | → | ||
− | | | + | | <tt>GameLoop.Saved</tt> |
− | | | + | | Equivalent. |
|- | |- | ||
| <tt>SaveEvents.BeforeCreate</tt> | | <tt>SaveEvents.BeforeCreate</tt> | ||
| → | | → | ||
− | | | + | | <tt>GameLoop.SaveCreating</tt> |
− | | | + | | Equivalent. |
|- | |- | ||
| <tt>SaveEvents.BeforeSave</tt> | | <tt>SaveEvents.BeforeSave</tt> | ||
| → | | → | ||
− | | | + | | <tt>GameLoop.Saving</tt> |
− | | | + | | Equivalent. |
|- | |- | ||
| <tt>SpecialisedEvents.UnvalidatedUpdateTick</tt> | | <tt>SpecialisedEvents.UnvalidatedUpdateTick</tt> | ||
Line 307: | Line 307: | ||
| <tt>TimeEvents.AfterDayStarted</tt> | | <tt>TimeEvents.AfterDayStarted</tt> | ||
| → | | → | ||
− | | | + | | <tt>GameLoop.DayStarted</tt> |
− | | | + | | Equivalent. |
|- | |- | ||
| <tt>TimeEvents.TimeOfDayChanged</tt> | | <tt>TimeEvents.TimeOfDayChanged</tt> |
Revision as of 04:19, 6 October 2018
This page is for modders. Players: see Modding:SMAPI compatibility instead.
This page explains how to update your mod code for compatibility with SMAPI 3.0 (release TBD).
Overview
What's changing?
Events are arguably the most important and most visible part of SMAPI, but they've stayed essentially unchanged since SMAPI 0.40. New events have been added organically since then, but the event system has always been separate from the rest of SMAPI — they're inconsistent, have some weird behaviours (like MenuEvents.MenuChanged not being raised when a menu is closed), aren't available through the same helper as every other API, and there are some glaring omissions in the available events.
SMAPI 3.0 is the release that fixes all that. This release...
- Completely rewrites the event engine to make events more efficient and enable events that weren't possible before.
- Makes events much more consistent: they're now fully compliant with the .NET design guidelines, have predictable and descriptive names, have consistent event handler signatures, and have clear documentation.
- All events are now accessible through
helper.Events
, so they're discoverable like any other SMAPI API. - Weird behaviours and overlapping events have been eliminated.
- Many new events have been added.
- Every event now has relevant event arguments.
Is this the modapocalypse?
Nope. Although this is a major change, significant effort will be undertaken to minimise the impact:
- the old events will be supported for a long time with increasingly prominent warnings in the SMAPI console about their deprecation and removal;
- pull requests will be submitted to update affected open-source mods;
- unofficial updates will be created for mods which haven't updated officially by the time SMAPI 3.0 is released;
- the changes will be actively communicated and documented to modders.
In addition, the current target is at least 95% compatibility for open-source mods before SMAPI 3.0 is released. All of this means that the 3.0 release should have minimal impact on mod compatibility, despite the scope of the changes.
How to update your mod
You don't need to comb through your code manually. SMAPI can tell you if you're using a deprecated interface:
- Use the latest SMAPI for developers download. This will show deprecation messages in the console:
- When you look at the code, you'll see a deprecation warning with a hint of how to fix it:
- You can refer to the following sections on how to replace specific interfaces.
Major changes
Event changes
The former events will be removed in SMAPI 3.0. Here's how to convert them to the new events under this.Helper.Events. This list does not cover new events in 3.0.
old event | → | new event | conversion notes |
---|---|---|---|
ContentEvents.AfterLocaleChanged | → | n/a | Mods very rarely need to handle this, since SMAPI's translation and content APIs do. Since the locale can only change on the title screen, mods that used this can check once the save is loaded instead. |
ControlEvents.ControllerButtonPressed | → | Input.ButtonPressed | Mostly equivalent.
|
ControlEvents.ControllerButtonReleased | → | Input.ButtonReleased | Mostly equivalent.
|
ControlEvents.ControllerTriggerPressed | → | Input.ButtonPressed | Mostly equivalent.
|
ControlEvents.ControllerTriggerReleased | → | Input.ButtonReleased | Mostly equivalent.
|
ControlEvents.KeyboardChanged | → | Input.ButtonPressed Input.ButtonReleased |
Not directly equivalent; may need to rewrite affected code. |
ControlEvents.KeyPressed | → | Input.ButtonPressed | Mostly equivalent.
|
ControlEvents.KeyReleased | → | Input.ButtonReleased | Mostly equivalent.
|
ControlEvents.MouseChanged | → | Input.ButtonPressed Input.ButtonReleased Input.CursorMoved Input.MouseWheelScrolled |
Not directly equivalent; may need to rewrite affected code. |
GameEvents.EighthUpdateTick | → | GameLoop.UpdateTicked |
|
GameEvents.FirstUpdateTick | → | GameLoop.GameLaunched | The new event is raised before the first update tick. To do something after the first update tick, use GameEvents.UpdateTicked with if (e.Ticks == 1). |
GameEvents.FourthUpdateTick | → | GameLoop.UpdateTicked |
|
GameEvents.HalfSecondTick | → | GameLoop.UpdateTicked |
|
GameEvents.OneSecondTick | → | GameLoop.UpdateTicked |
|
GameEvents.QuarterSecondTick | → | GameLoop.UpdateTicked |
|
GameEvents.SecondUpdateTick | → | GameLoop.UpdateTicked |
|
GameEvents.UpdateTick | → | GameLoop.UpdateTicked | Equivalent. |
GraphicsEvents.OnPostRenderEvent | → | TODO | |
GraphicsEvents.OnPostRenderGuiEvent | → | TODO | |
GraphicsEvents.OnPostRenderHudEvent | → | TODO | |
GraphicsEvents.OnPreRenderEvent | → | TODO | |
GraphicsEvents.OnPreRenderGuiEvent | → | TODO | |
GraphicsEvents.OnPreRenderHudEvent | → | TODO | |
GraphicsEvents.Resize | → | TODO | |
InputEvents.ButtonPressed | → | Input.ButtonPressed | Mostly equivalent.
|
InputEvents.ButtonReleased | → | Input.ButtonReleased | Mostly equivalent.
|
LocationEvents.BuildingsChanged | → | World.BuildingListChanged | Equivalent. |
LocationEvents.LocationsChanged | → | World.LocationListChanged | Equivalent. |
LocationEvents.ObjectsChanged | → | World.ObjectListChanged | Equivalent. |
MenuEvents.MenuChanged | → | TODO | |
MenuEvents.MenuClosed | → | TODO | |
MineEvents.MineLevelChanged | → | TODO | |
MultiplayerEvents.AfterMainBroadcast | → | TODO | |
MultiplayerEvents.AfterMainSync | → | TODO | |
MultiplayerEvents.BeforeMainBroadcast | → | TODO | |
MultiplayerEvents.BeforeMainSync | → | TODO | |
PlayerEvents.InventoryChanged | → | TODO | |
PlayerEvents.LeveledUp | → | TODO | |
PlayerEvents.Warped | → | TODO | |
SaveEvents.AfterCreate | → | GameLoop.SaveCreated | Equivalent. |
SaveEvents.AfterLoad | → | GameLoop.SaveLoaded | Equivalent. |
SaveEvents.AfterReturnToTitle | → | TODO | |
SaveEvents.AfterSave | → | GameLoop.Saved | Equivalent. |
SaveEvents.BeforeCreate | → | GameLoop.SaveCreating | Equivalent. |
SaveEvents.BeforeSave | → | GameLoop.Saving | Equivalent. |
SpecialisedEvents.UnvalidatedUpdateTick | → | TODO | |
TimeEvents.AfterDayStarted | → | GameLoop.DayStarted | Equivalent. |
TimeEvents.TimeOfDayChanged | → | TODO |
Removed CreateTransitionalContentPack
this.Helper.CreateTransitionalContentPack
was a temporary method to support mods which already accepted custom content packs in their subfolder. All such content packs should be migrated to regular SMAPI content packs. This method will be removed in SMAPI 3.0.