Modding:Modder Guide/APIs/Events

From Stardew Valley Wiki
Jump to navigation Jump to search

Creating SMAPI mods SMAPI mascot.png


Modding:Index

SMAPI provides several C# events which let your mod respond when something happens (like when the player places an object) or run code periodically (like once per update tick).

Intro

A C# event is the way that SMAPI notifies mods when something happens. You can add any number of event handlers (methods to call) when an event is raised. Event handlers are usually added in your Entry method, though you can add and remove them anytime.

For example, let's say you want to print a message when the player loads a save. First you would choose the appropriate event from the list below (SaveEvents.AfterLoad), then add an event handler, and do something in your method code:

/// <summary>The main entry point for the mod.</summary>
public class ModEntry : Mod
{
    /**********
    ** Public methods
    *********/
    /// <summary>The mod entry point, called after the mod is first loaded.</summary>
    /// <param name="helper">Provides simplified APIs for writing mods.</param>
    public override void Entry(IModHelper helper)
    {
        // SaveEvents.AfterLoad is the event
        // this.SaveEvents_AfterLoad is the method below you want to call
        SaveEvents.AfterLoad += this.SaveEvents_AfterLoad;
    }

    /// <summary>The method called after the player loads their save.</summary>
    /// <param name="sender">The event sender.</param>
    /// <param name="e">The event arguments.</param>
    private void SaveEvents_AfterLoad(object sender, EventArgs e)
    {
       this.Monitor.Log("The player loaded their game! This is a good time to do things.");
       this.Monitor.Log("Everything in the world is ready to interact with at this point.");
    }
}

Tip: you don't need to memorise the method arguments. In Visual Studio, type SaveEvents.AfterLoad += and press TAB to auto-create a method. (There doesn't seem to be an equivalent feature in MonoDevelop.)

Events

The available events are documented below.

Content

ContentEvents are raised when the game loads content from its XNB files or changes locale.

event summary
AfterLocaleChanged Raised after the content language changes.

Control

ControlEvents are raised when the player uses a controller, keyboard, or mouse. They're raised before the game handles the input, so it's possible to selectively prevent the game from responding to it. (That's beyond the scope of this guide, but it involves overwriting Game1.oldKBState, Game1.oldMouseState, and Game1.oldPadState.)

Most of these events are split into two variants, XPressed and XReleased. The Pressed variant is raised when the player presses the button (holding the button down only triggers the event once), and the Released variant is raised when they release it.

The following describes the upcoming SMAPI 2.6, and may change before release.
Note: mods won't receive input sent to the chatbox, or the toggle-chatbox key.
event summary
ControllerButtonPressed
ControllerButtonReleased
Raised after the player pressed/released a button on a gamepad or controller. These events aren't raised for trigger buttons.
ControllerTriggerPressed
ControllerTriggerReleased
Raised after the player pressed/released a trigger button on a gamepad or controller.
KeyPressed
KeyReleased
Raised after the player pressed/released a keyboard key.
KeyboardChanged Raised after the game's KeyboardState changed. That happens when the player presses or releases a key.
MouseChanged Raised after the game's MouseState changed. That happens when the player moves the mouse, scrolls the mouse wheel, or presses/releases a button.

Game

GameEvents are raised when the game changes state.

event summary
FirstUpdateTick Raised after the game first updates its state. This happens once per game session (unrelated to loading saves).
UpdateTick Raised when the game updates its state (≈60 times per second).
SecondUpdateTick Raised every other tick (≈30 times per second).
FourthUpdateTick Raised every fourth tick (≈15 times per second).
EighthUpdateTick Raised every eighth tick (≈8 times per second).
QuarterSecondTick Raised every 15th tick (≈4 times per second).
HalfSecondTick Raised every 30th tick (≈twice per second).
OneSecondTick Raised every 60th tick (≈once per second).

Graphics

GraphicsEvents are raised during the game's draw loop, when the game is rendering content to the window.

event summary
OnPreRenderEvent
OnPostRenderEvent
Raised before and after drawing the world to the screen.
OnPreRenderGuiEvent
OnPostRenderGuiEvent
When a menu is open (Game1.activeClickableMenu != null), raised before and after drawing that menu to the screen. This includes the game's internal menus like the title screen.
OnPreRenderHudEvent
OnPostRenderHudEvent
Raised before and after drawing the HUD (item toolbar, clock, etc) to the screen. The HUD is available at this point, but not necessarily visible. (For example, the event is called even if a menu is open.)
Resize Raised after the game window is resized.

Input

InputEvents are raised when the player uses a controller, keyboard, or mouse.

The following describes the upcoming SMAPI 2.6, and may change before release.
Note: mods won't receive input sent to the chatbox, or the toggle-chatbox key.
event summary
ButtonPressed
ButtonReleased
Raised after the player pressed/released a keyboard, mouse, or controller button. The event arguments include:
  • the button pressed (as an SButton constant);
  • whether the input counts as a 'click' (including the controller equivalent);
  • the cursor position on the screen;
  • the tile under the cursor;
  • the 'grab tile' (i.e. the tile the game considers to be clicked).

You can also...

  • get the equivalent XNA button constants using button.TryGetKeyboard(…) and button.TryGetController(…);
  • prevent the game (but not other mods) from handling the input using eventArgs.SuppressButton().

Location

LocationEvents are raised when the player transitions between game locations, a location is added or removed, or the objects in the current location change.

In SMAPI 2.5.5 or earlier:

event summary
CurrentLocationChanged Raised after the player warps to a new location. Handlers are given the previous and new locations as arguments.
LocationObjectsChanged Raised after the list of objects in the current location changes (e.g. an object is added or removed). Handlers are given the new list of objects as an argument.
LocationsChanged Raised after a game location is added or removed. Handlers are passed the new list of locations as an argument.
The following describes the upcoming SMAPI 2.6, and may change before release.

In SMAPI 2.6 or later:

event summary
LocationsChanged Raised after a game location is added or removed (including building interiors). Handlers are passed lists of added/removed locations.
BuildingsChanged Raised after buildings is added/removed in any location. Handlers are given the location, and lists of added/removed buildings.
ObjectsChanged Raised after objects are added/removed in any location (including building interiors). Handlers are given the location, and lists of added/removed objects.

Menu

MenuEvents are raised when a game menu is opened or closed (including internal menus like the title screen).

event summary
MenuChanged Raised after a game menu is opened or replaced with another menu. This event is not invoked when a menu is closed. Handlers are given the previous menu (if any) and new menu (if any).
MenuClosed Raised after a game menu is closed. Handlers are given the previous menu.

Mine

MineEvents are raised when something happens in The Mines.

event summary
MineLevelChanged Raised after the player warps to a new level of the mine. Handlers are passed the previous and new mine level as arguments.

Multiplayer

The following describes the upcoming SMAPI 2.6, and may change before release.

MultiplayerEvents are raised during the multiplayer sync process. These are specialised events; most mods shouldn't use these directly.

event summary
BeforeMainSync
AfterMainSync
Raised before and after the game fetches data from other players and syncs the world to match.
BeforeMainBroadcast
AfterMainBroadcast
Raised before/after the game sends world data to other players. This event is raised for the main world broadcast, but a few specialised broadcasts (particularly sprite broadcasts) occur outside this event.

Player

PlayerEvents are raised when the player data changes.

event summary
InventoryChanged Raised after the current player's inventory changes in any way (added or removed item, sorted, etc).
LeveledUp Raised after the current player levels up a skill. This happens as soon as they level up, not when the game notifies the player after their character goes to bed.
Warped
The following describes the upcoming SMAPI 2.6-beta.7, and may change before release.
Raised after the current player moves to a new location.

Save

SaveEvents are raised when the player saves or loads the game.

event summary
BeforeCreate
AfterCreate
Raised before and after the game creates the save file (after the new-game intro). The save won't be written until all mods have finished handling this event.
AfterLoad Raised after the player loads a saved game (or starts a new save). The world is ready for mods to modify at this point.
BeforeSave
AfterSave
Raised before and after the game updates the save file. Not raised for the initial creation. The save won't be written until all mods have finished handling this event.
AfterReturnToTitle Raised after the player exits to the title screen.

Time

TimeEvents are raised when the in-game date or time changes.

event summary
AfterDayStarted Raised after the game begins a new day, including when loading a save.
TimeOfDayChanged Raised after the in-game clock changes.

Specialised

SpecialisedEvents serve specialised edge cases and should not be used by most mods. Mods using specialised events will be flagged in the SMAPI console as potentially impacting the game stability.

expand for details 
event summary
UnvalidatedUpdateTick Raised after the game updates its state (≈60 times per second), regardless of normal SMAPI validation. This event is not thread-safe and may be invoked while game logic is running asynchronously. Changes to game state in this method may crash the game or corrupt an in-progress save. Do not use this event unless you're fully aware of the context in which your code will be run. Using this event will trigger a warning in the SMAPI console.

Events (SMAPI 3.0)

The following describes the upcoming SMAPI 3.0, and may change before release.

SMAPI 3.0 will introduce a new event system that's much more powerful, flexible, and consistent. You can try these events now in SMAPI 2.6+, but these are preview prototypes and may change at any time. See Modding:Migrate to SMAPI 3.0 for details.

Game loop

this.Helper.Events.GameLoop has events linked to the game's update loop. The update loop runs roughly ≈60 times/second to run game logic like state changes, action handling, etc. These can be useful, but you should consider more semantic events like Input if possible.

event summary
[[#{{{group}}}.Launched|#]]Launched Raised after the game is launched, right before the first update tick. This happens once per game session (unrelated to loading saves). All mods are loaded and initialised at this point, so this is a good time to set up mod integrations.
[[#{{{group}}}.Updating
Updated|#]]
<span id="{{{group}}}.Updating
Updated">Updating
Updated
Raised before/after the game performs its overall update tick (≈60 times per second).

Event arguments:

event arg type description
e.Ticks int The number of ticks elapsed since the game started, including the current tick.
e.IsOneSecond bool Whether e.TicksElapsed is a multiple of 60, which happens approximately once per second.
e.IsMultipleOf(int number) method returns bool Whether e.TicksElapsed is a multiple of the given number. This is mainly useful if you want to run logic intermittently (e.g. e.IsMultipleOf(30) for every half-second).

Input

this.Helper.Events.Input has events raised when the player uses a controller, keyboard, or mouse in some way. Can be used with the input API to access more info or suppress input.

event summary
[[#{{{group}}}.ButtonPressed
ButtonReleased|#]]
<span id="{{{group}}}.ButtonPressed
ButtonReleased">ButtonPressed
ButtonReleased
Raised after the player pressed/released a keyboard, mouse, or controller button. This includes mouse clicks.

Event arguments:

event arg type description
e.Button SButton The button pressed or released.
e.Cursor ICursorPosition The cursor position and grab tile.
e.IsDown method returns bool Indicates whether a given button is currently pressed.
e.IsSuppressed method returns bool A method which indicates whether a given button was suppressed by a mod, so the game itself won't see it. Note: mods won't receive input sent to the chatbox.
[[#{{{group}}}.CursorMoved|#]]CursorMoved Raised after the player moves the in-game cursor.

Event arguments:

event arg type description
e.OldPosition ICursorPosition The previous cursor position and grab tile.
e.NewPosition ICursorPosition The current cursor position and grab tile.
[[#{{{group}}}.MouseWheelScrolled|#]]MouseWheelScrolled Raised after the player scrolls the mouse wheel.

Event arguments:

event arg type description
e.Position ICursorPosition The current cursor position and grab tile.
e.Delta int The amount by which the mouse wheel was scrolled since the last update.
e.OldValue
e.NewValue
int The previous and current scroll value, cumulative since the game started. Mods should generally use e.Delta instead.

World

this.Helper.Events.World has events raised when the in-game world changes in some way.

event summary
[[#{{{group}}}.LocationListChanged|#]]<span id="{{{group}}}.LocationListChanged">LocationListChanged Raised after a game location is added or removed (including building interiors).

Event arguments:

event arg type description
e.Added IEnumerable<GameLocation> A list of locations added since the last update tick.
e.Removed IEnumerable<GameLocation> A list of locations removed since the last update tick.
[[#{{{group}}}.BuildingListChanged|#]]<span id="{{{group}}}.BuildingListChanged">BuildingListChanged Raised after buildings are added/removed in any location.

Event arguments:

event arg type description
e.Location GameLocation The location which changed.
e.Added IEnumerable<Building> A list of buildings added since the last update tick.
e.Removed IEnumerable<Building> A list of buildings removed since the last update tick.
[[#{{{group}}}.DebrisListChanged|#]]<span id="{{{group}}}.DebrisListChanged">DebrisListChanged Raised after debris is added/removed in any location (including dropped or spawned floating items).

Event arguments:

event arg type description
e.Location GameLocation The location which changed.
e.Added IEnumerable<Debris> A list of debris added since the last update tick.
e.Removed IEnumerable<Debris> A list of debris removed since the last update tick.
[[#{{{group}}}.LargeTerrainFeatureListChanged|#]]<span id="{{{group}}}.LargeTerrainFeatureListChanged">LargeTerrainFeatureListChanged Raised after large terrain features (like bushes) are added/removed in any location.

Event arguments:

event arg type description
e.Location GameLocation The location which changed.
e.Added IEnumerable<LargeTerrainFeature> A list of large terrain features added since the last update tick.
e.Removed IEnumerable<LargeTerrainFeature> A list of large terrain features removed since the last update tick.
[[#{{{group}}}.NpcListChanged|#]]<span id="{{{group}}}.NpcListChanged">NpcListChanged Raised after NPCs are added/removed in any location (including villagers, horses, Junimos, monsters, and pets).

Event arguments:

event arg type description
e.Location GameLocation The location which changed.
e.Added IEnumerable<NPC> A list of NPCs added since the last update tick.
e.Removed IEnumerable<NPC> A list of NPCs removed since the last update tick.
[[#{{{group}}}.ObjectListChanged|#]]<span id="{{{group}}}.ObjectListChanged">ObjectListChanged Raised after objects are added/removed in any location (including machines, furniture, fences, etc). For floating items, see DebrisListChanged.

Event arguments:

event arg type description
e.Location GameLocation The location which changed.
e.Added IEnumerable<KeyValuePair<Vector2, Object>> A list of tile coordinate + object pairs added since the last update tick.
e.Removed IEnumerable<KeyValuePair<Vector2, Object>> A list of tile coordinate + object pairs removed since the last update tick.
[[#{{{group}}}.TerrainFeatureListChanged|#]]<span id="{{{group}}}.TerrainFeatureListChanged">TerrainFeatureListChanged Raised after terrain features are added/removed in any location (including trees, hoed dirt, and flooring). For bushes, see LargeTerrainFeatureListChanged.

Event arguments:

event arg type description
e.Location GameLocation The location which changed.
e.Added IEnumerable<KeyValuePair<Vector2, TerrainFeature>> A list of tile coordinate + terrain feature pairs added since the last update tick.
e.Removed IEnumerable<KeyValuePair<Vector2, TerrainFeature>> A list of tile coordinate + terrain feature pairs removed since the last update tick.