Changes

Jump to navigation Jump to search
m
Text replacement - "''e.g.''," to "''e.g.,''"
Line 43: Line 43:     
===How do events fit into the game?===
 
===How do events fit into the game?===
Events are raised on each game tick (when the game updates its state and renders to the screen), which is 60 times per second. An event may be raised multiple times (''e.g.'', if the player pressed two keys simultaneously), but most events won't be raised 60 times per second (''e.g.'', players are unlikely to be pressing 60 buttons per second).
+
Events are raised on each game tick (when the game updates its state and renders to the screen), which is 60 times per second. An event may be raised multiple times (''e.g.,'' if the player pressed two keys simultaneously), but most events won't be raised 60 times per second (''e.g.,'' players are unlikely to be pressing 60 buttons per second).
    
Your event handlers are run ''synchronously'': the game is paused and no other mod's code will run simultaneously, so there's no risk of conflicting changes. Since code runs very quickly, players won't notice any delay unless your code is unusually slow. That said, when using frequent events like <samp>UpdateTicked</samp> or <samp>Rendered</samp>, you should cache expensive operations (like loading an asset) instead of repeating them in each tick to avoid impacting performance.
 
Your event handlers are run ''synchronously'': the game is paused and no other mod's code will run simultaneously, so there's no risk of conflicting changes. Since code runs very quickly, players won't notice any delay unless your code is unusually slow. That said, when using frequent events like <samp>UpdateTicked</samp> or <samp>Rendered</samp>, you should cache expensive operations (like loading an asset) instead of repeating them in each tick to avoid impacting performance.
Line 58: Line 58:  
Each mod is still handling the <samp>MenuChanged</samp> event for the opened menu, even though the first mod closed it. SMAPI will raise a new <samp>MenuChanged</samp> event for the closed menu on the next tick.
 
Each mod is still handling the <samp>MenuChanged</samp> event for the opened menu, even though the first mod closed it. SMAPI will raise a new <samp>MenuChanged</samp> event for the closed menu on the next tick.
   −
This rarely affects mods, but it's something to keep in mind if you need the current state (''e.g.'', check <samp>Game1.activeClickableMenu</samp> instead of <samp>e.NewMenu</samp>).
+
This rarely affects mods, but it's something to keep in mind if you need the current state (''e.g.,'' check <samp>Game1.activeClickableMenu</samp> instead of <samp>e.NewMenu</samp>).
    
==Events==
 
==Events==
Line 140: Line 140:  
  |group = Display
 
  |group = Display
 
  |name  = RenderingHud
 
  |name  = RenderingHud
  |desc  = Raised before drawing the HUD (item toolbar, clock, etc) to the screen. The vanilla HUD may be hidden at this point (''e.g.'', because a menu is open). Content drawn to the sprite batch at this point will appear under the HUD.
+
  |desc  = Raised before drawing the HUD (item toolbar, clock, etc) to the screen. The vanilla HUD may be hidden at this point (''e.g.,'' because a menu is open). Content drawn to the sprite batch at this point will appear under the HUD.
    
  |arg name 1 = <samp>e.SpriteBatch</samp>
 
  |arg name 1 = <samp>e.SpriteBatch</samp>
Line 149: Line 149:  
  |group = Display
 
  |group = Display
 
  |name  = RenderedHud
 
  |name  = RenderedHud
  |desc  = Raised after drawing the HUD (item toolbar, clock, etc) to the sprite batch, but before it's rendered to the screen. The vanilla HUD may be hidden at this point (''e.g.'', because a menu is open). Content drawn to the sprite batch at this point will appear over the HUD.
+
  |desc  = Raised after drawing the HUD (item toolbar, clock, etc) to the sprite batch, but before it's rendered to the screen. The vanilla HUD may be hidden at this point (''e.g.,'' because a menu is open). Content drawn to the sprite batch at this point will appear over the HUD.
    
  |arg name 1 = <samp>e.SpriteBatch</samp>
 
  |arg name 1 = <samp>e.SpriteBatch</samp>
Line 197: Line 197:  
  |arg name 3 = <samp>e.IsMultipleOf(int number)</samp>
 
  |arg name 3 = <samp>e.IsMultipleOf(int number)</samp>
 
  |arg type 3 = ''method'' returns <samp>bool</samp>
 
  |arg type 3 = ''method'' returns <samp>bool</samp>
  |arg desc 3 = Whether <samp>e.TicksElapsed</samp> is a multiple of the given number. This is mainly useful if you want to run logic intermittently (''e.g.'', <code>e.IsMultipleOf(30)</code> for every half-second).
+
  |arg desc 3 = Whether <samp>e.TicksElapsed</samp> is a multiple of the given number. This is mainly useful if you want to run logic intermittently (''e.g.,'' <code>e.IsMultipleOf(30)</code> for every half-second).
 
}}
 
}}
 
{{/event
 
{{/event
Line 210: Line 210:  
  |arg name 3 = <samp>e.IsMultipleOf(int number)</samp>
 
  |arg name 3 = <samp>e.IsMultipleOf(int number)</samp>
 
  |arg type 3 = ''method'' returns <samp>bool</samp>
 
  |arg type 3 = ''method'' returns <samp>bool</samp>
  |arg desc 3 = Whether <samp>e.TicksElapsed</samp> is a multiple of the given number. This is mainly useful if you want to run logic intermittently (''e.g.'', <code>e.IsMultipleOf(120)</code> for every two seconds).
+
  |arg desc 3 = Whether <samp>e.TicksElapsed</samp> is a multiple of the given number. This is mainly useful if you want to run logic intermittently (''e.g.,'' <code>e.IsMultipleOf(120)</code> for every two seconds).
 
}}
 
}}
 
{{/event
 
{{/event
Line 705: Line 705:  
  |group = Specialised
 
  |group = Specialised
 
  |name  = LoadStageChanged
 
  |name  = LoadStageChanged
  |desc  = Raised when the low-level stage in the game's loading process has changed, for mods which need to run code at specific points in the loading process. The available stages or when they happen might change without warning in future versions (''e.g.'', due to changes in the game's load process), so '''mods using this event are more likely to break or have bugs'''. Most mods should use the [[#Game loop|game loop events]] instead.
+
  |desc  = Raised when the low-level stage in the game's loading process has changed, for mods which need to run code at specific points in the loading process. The available stages or when they happen might change without warning in future versions (''e.g.,'' due to changes in the game's load process), so '''mods using this event are more likely to break or have bugs'''. Most mods should use the [[#Game loop|game loop events]] instead.
    
  |arg name 1 = <samp>e.NewStage</samp>
 
  |arg name 1 = <samp>e.NewStage</samp>
Line 747: Line 747:  
  |arg name 3 = <samp>e.IsMultipleOf(int number)</samp>
 
  |arg name 3 = <samp>e.IsMultipleOf(int number)</samp>
 
  |arg type 3 = ''method'' returns <samp>bool</samp>
 
  |arg type 3 = ''method'' returns <samp>bool</samp>
  |arg desc 3 = Whether <samp>e.TicksElapsed</samp> is a multiple of the given number. This is mainly useful if you want to run logic intermittently (''e.g.'', <code>e.IsMultipleOf(30)</code> for every half-second).
+
  |arg desc 3 = Whether <samp>e.TicksElapsed</samp> is a multiple of the given number. This is mainly useful if you want to run logic intermittently (''e.g.,'' <code>e.IsMultipleOf(30)</code> for every half-second).
 
}}
 
}}
 
|}
 
|}
Line 753: Line 753:  
==Advanced==
 
==Advanced==
 
===Change monitoring===
 
===Change monitoring===
You may want to handle a change that doesn't have its own event (''e.g.'', an in-game event ends, a letter is added to the mailbox, etc). You can usually do that by handling a general event like [[#GameLoop.UpdateTicked|<samp>UpdateTicked</samp>]], and detecting when the value(s) you're watching changed. For example, here's a complete mod which logs a message when an in-game event ends:
+
You may want to handle a change that doesn't have its own event (''e.g.,'' an in-game event ends, a letter is added to the mailbox, etc). You can usually do that by handling a general event like [[#GameLoop.UpdateTicked|<samp>UpdateTicked</samp>]], and detecting when the value(s) you're watching changed. For example, here's a complete mod which logs a message when an in-game event ends:
 
<syntaxhighlight lang="c#">
 
<syntaxhighlight lang="c#">
 
/// <summary>The main entry point for the mod.</summary>
 
/// <summary>The main entry point for the mod.</summary>
Line 795: Line 795:  
SMAPI calls event handlers in the same order they're registered by default, so the first event handler registered is the first to receive the event each time. This isn't always predictable, since it depends on mod load order and when each mod registers their handlers. This order is also an implementation detail, so it's not guaranteed.
 
SMAPI calls event handlers in the same order they're registered by default, so the first event handler registered is the first to receive the event each time. This isn't always predictable, since it depends on mod load order and when each mod registers their handlers. This order is also an implementation detail, so it's not guaranteed.
   −
If you need more control over the order, you can specify an event priority using the <code>[EventPriority]</code> attribute: <samp>Low</samp> (after most handlers), <samp>Default</samp>, <samp>High</samp> (before most handlers), or a custom value (''e.g.'', <samp>High + 1</samp> is higher priority than <samp>High</samp>). '''You should only do this if strictly needed'''; depending on event handler order between mods is fragile (''e.g.'', the other mod might change its priority too).
+
If you need more control over the order, you can specify an event priority using the <code>[EventPriority]</code> attribute: <samp>Low</samp> (after most handlers), <samp>Default</samp>, <samp>High</samp> (before most handlers), or a custom value (''e.g.,'' <samp>High + 1</samp> is higher priority than <samp>High</samp>). '''You should only do this if strictly needed'''; depending on event handler order between mods is fragile (''e.g.,'' the other mod might change its priority too).
    
<syntaxhighlight lang="c#">
 
<syntaxhighlight lang="c#">
105,703

edits

Navigation menu