SMAPI - Stardew Modding API

SMAPI - Stardew Modding API

971k Downloads

Revamp SMAPI startup process

Pathoschild opened this issue ยท 6 comments

commented

Revamp the SMAPI startup process to simplify mod development, ensure that core components are ready when mods are called, and eliminate or reduce SEHException errors some players get.

Background

Mods are currently initialised before the game is started, at which point many of the core components (like content managers) aren't ready. This leads to some significant issues:

  • New modders are often confused when they access core components in Entry and get errors like NullReferenceException.
  • Mods often register for an event like GameEvents.UpdateTick to continuously check whether the things they need are ready. This is very inefficient and unnecessary work for the developer.
  • SMAPI can't provide APIs for many core components through the IModHelper, since that's initialised before the mod (which is initialised before many core components). This notably impacts the content API planned for SMAPI 2.0.

Initialising everything before the game is ready can also lead to SEHException errors for some players.

commented

Current init order

Here's the current init order. Everything happens before the game is started.

  1. Handle command-line arguments.
  2. Read settings from StardewModdingAPI.config.json.
  3. Init before game starts:
    1. log file + monitor;
    2. mod registry;
    3. deprecation manager;
    4. API shims;
    5. console redirection;
    6. game version check;
    7. file paths;
    8. exception handlers.
  4. Override Game1 and hook events.
  5. Load mods.
  6. Start console listener.
  7. Start game.

Proposed init order

Here's the init order I propose. Only core SMAPI init happens before the game starts; everything else (including mods) happens after the game's Initialize/LoadContent phase.

  1. Handle command-line arguments.
  2. Init before game starts:
    1. log file + monitor;
    2. file paths;
    3. game version check;
    4. exception handlers.
  3. Override Game1 and hook events.
  4. Start game.
  5. Init after game starts (blocking):
    1. settings from StardewModdingAPI.config.json;
    2. deprecation manager;
    3. mod registry;
    4. API shims;
    5. console redirection;
    6. mods;
    7. console listener.

Main effect

For most mods, this will have two visible effects:

  • GameEvents.Initialize and GameEvents.LoadContent no longer exist.
  • Most mod initialisation can now happen in their Entry method, instead of needing a separate event like UpdateTick.

For most players, this should have no visible effect. For players who get SEHException errors, this should eliminate or significantly reduce their frequency.

commented

@Entoarox and @TehPers: you both have mods that hook into the game initialisation, so your feedback would be appreciated. All mods would now be loaded after the Initialize/LoadContent phase, but you could still ensure your mods are loaded before others (just like you do now). Will that cause any problems for you?

commented

I dont see any obvious problems... If I am correct, the new order essentially has all mods Entry happen directly after LoadContent?

commented

The game's Initialize/LoadContent phases are intertwined (e.g. LoadContent happens partway through Initialize), but mods would be loaded immediately after the combined Initialize/LoadContent phase.

commented

I see no issues with this, assuming it's still possible to handle content that is loaded without needing to access every variable in the game that contains an asset in it. It'd definitely clean up the update tick code since you'd no longer need to check if the game has been fully initialized.

commented

Done in develop for the next SMAPI release.