Latest version: ...

Dev Build
Watch this video on YouTube

Gives NPCs a schedule, they will go home at night or during bad weather. Highly configurable.

Dynamically supports anything, carefully built to avoid conflicts with an interface for adding custom rules.

Requires OpenMW 0.49 or newer!

Features

A high-level look at this mod’s main features:

Please read on for more information.

How It Works

This mod dynamically supports all content and has many internal exceptions designed to prevent breaking other mods and quests.

It works like this:

  1. When an NPC is first loaded it’s checked against several exception types
  2. Then its local doors are scanned, looking for one that matches their name
  3. The NPC’s full name will be checked, and if applicable their first and last names (or more) will be checked individually
  4. If this is found, it’s considered their home and they will navigate back to it at night time
    • There is a random chance for a (configurable) delay before the NPC walks home
  5. If this is not found (or some internal exception is hit), the NPC will instead be disabled at night time
    • There’s a rare chance these NPCs may not disable at night
    • The chance is slightly less rare for merchants
    • NPCs that get disabled/enabled will not be toggled into either state if the player is looking in their direction
  6. NPCs will also go home during bad weather
    • To achieve this an “MWScript bridge” is used to get the weather status
  7. When day time arrives, NPCs at home will exit and go back to their normal routines and disabled NPCs will be re-enabled

Please note that this method will cause your save file to grow as it loads interior cells. Those cells would normally be loaded and added to your save if you visited them, but this mod does it under the hood, without you actually visiting the cell.

The various internal exceptions are:

  1. By NPC recordId
  2. All travel merchants are excluded
  3. By quests and journal index ranges
  4. An explicit list of NPCs that shouldn’t scan doors for home
  5. By cell name or grid X/Y coordinates
    • Only cells that are explicitly whitelisted will be used by this mod!
  6. By mod plugin name
  7. By script; only NPCs with explicitly allowed scripts will be handled
  8. Various checks for things like guards, NPCs from specific modders, and other things known to be ignorable
  9. Only NPCs with “Wander” as their default AI package are considered to go home

Not every case that requires an exception has been found, if you come across something that got broken please let us know via the project issue tracker or Discord.

Generally speaking, an NPC won’t be affected by this mod unless:

How The Schedule Works

The script that gets attached to each NPC has a state machine that manages what behavior they should do and when. When the script updates, it sets the state as needed and reacts accordingly.

For further information please view the update() function in the scripts/go-home/npc.lua file.

Credits

Author: johnnyhostile

Special Thanks:

And a big thanks to the entire OpenMW and Morrowind modding communities! I wouldn’t be doing this without all of you.

Video Credits

Localization

Web

Installation

OpenMW 0.49 or newer is required!

  1. Download the mod from this URL

  2. Extract the zip to a location of your choosing, examples below:

     # Windows
     C:\games\OpenMWMods\Gameplay\GoHome
    
     # Linux
     /home/username/games/OpenMWMods/Gameplay/GoHome
    
     # macOS
     /Users/username/games/OpenMWMods/Gameplay/GoHome
    
  3. Add the appropriate data path to your opemw.cfg file (e.g. data="C:\games\OpenMWMods\Gameplay\go-home")

  4. Add content=go-home.omwaddon and content=go-home.omwscripts to your load order in openmw.cfg or enable them via OpenMW-Launcher

Configuration

Various parameters of this mod can be configured to alter its behavior. They may be changed via the script settings menu at ESC >> Options >> Scripts >> Go Home!:

Mod Settings

Please see the in game script menu for detailed descriptions (ESC >> Options >> Scripts >> Go Home!).

Delay Settings
Timing Frequency Settings

Compatibility

This mod only operates in cells that are explicitly whitelisted. Great care has gone into trying to weed out NPCs that should not be scheduled but it is likely that I missed some. Additionally: any other mod that tries to alter NPC AI may conflict with this one. Most incompatibilities should be solvable with one of the various exception methods built into the mod.

In the event you face an incompatibility, you can:

  1. Reload your last known good save
  2. Navigate to the script settings menu, “Factory Reset” section: ESC >> Options >> Scripts >> Go Home! >> Factory Reset
  3. Do a “Factory Reset” by setting that to “Yes”
    • This will disable this mod and reset all affected NPCs to their default position and AI state. You may re-run the command at any time to re-enable the mod, but if you’ve found a problem please report it via the project issue tracker or Discord.
  4. If you wish to re-enable this mod, set that back to “No”
Adding Support For New Content

This mod is designed to be very conservative about the NPCs it affects and as such out of the box won’t affect any new content. To add support:

  1. Create an exception mod that adds cells from the new content in question to the whitelist
    • See below for a reference on both (1, 2)
  2. Run this mod with the content in question, ensure debug logging is enabled
    • ESC >> Options >> Scripts >> Go Home! >> Mod Settings >> Enable debug messages in the log
  3. Go to a cell that you wish to add support for
  4. The log will list each NPC in that cell and state whether or not it supports them
    • Modded NPCs tend to be blocked based on having MWScript attached, if that’s the case you’ll need to add their script to the script whitelist if it is not already

Depending on the content, this might be enough to support NPCs in the given cell. You’ll have to inspect the log and see what NPCs are being blocked for and whitelist accordingly.

Known Issues And Limitations

Updating This Mod

Any special requirements for updating this mod will be listed in the related changelog entry for a release.

Usually, an automated factory reset is all that needs to happen but that may not always be the case.

Updating Your Load Order With This Mod

This mod uses an NPCs internal “ID” to keep track of them. Under normal circumstances this never changes, which is why that value is used by this mod.

It is possible to inadvertantly cause this value to change if you rearrange your load order. If you absolutely need to end up in this situation, please disable this mod via a factory reset prior to doing the load order change. This should avoid any problems relating to changed IDs.

If you don’t do this, it’s possible NPCs might vanish and require manual recovery!

See How This Mod Affects An NPC

  1. Use the OpenMW feature to start a test character and spawn into Seyda Neen

  2. ESC >> Options >> Scripts >> Go Home! >> Mod Settings >> Enable debug messages in the log

  3. Restart OpenMW if this option was not already on

  4. Press F10 to view the log

  5. There will be many lines containing GoHome: , each of these will contain information about what the mod is doing, when it’s doing it

  6. When an NPC is going to be managed by this mod, there will be lines like:

     # This NPC is fully supported
     GoHome: Actor is fully routined: fargoth
    
     # This NPC is partially supported
     GoHome: Actor has no door (1): momw_greeter
    
     # These NPCs will be ignored and totally unaffected by this mod
     GoHome: Actor denied via pattern match blacklist: imperial guard
     GoHome: Actor denied via service check: darvame hleran
     GoHome: Actor denied via actor blacklist: agronian guy
    

The range of NPCs affected by this mod is rather conservative, please see the scripts/go-home/global.lua file for all black/whitelist rules.

Use The Lua Console To Check An NPC In Game

You can check the status of an NPC within this mod using console commands:

  1. Get the NPC you want to check in view
  2. Press ` to bring down the console
  3. Click on the NPC
  4. Type luas and press enter
  5. Type I.GoHome.i() and press enter
  6. Press F10 to see the log
    • There should be several lines similar to what’s shown below:

        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        Begin info For NPC: erene llenim
        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        badWeather: false
        dead: false
        defaultAIType: Wander
        defaultAIDistance: 512
        defaultAIDuration: 5
        defaultAIIdle.idle2: 60
        defaultAIIdle.idle3: 20
        defaultAIIdle.idle4: 10
        defaultAIIdle.idle5: 10
        defaultAIIdle.idle6: 0
        defaultAIIdle.idle7: 0
        defaultAIIdle.idle8: 0
        defaultAIIdle.idle9: 0
        defaultAIIsRepeat: true
        defaultCell: Seyda Neen
        defaultPosition: (-14711.654296875, -71600.7578125, 109.5315399169921875)
        defaultRotation: TransformQ{ rotation(angle=0.270796, axis=(0, 0, -1)) }
        disabledForQuest: false
        doorDestCellName: Seyda Neen, Erene Llenim's Shack
        doorDestPos: (49.215000152587890625, -107.089996337890625, 94.12799835205078125)
        doorDestRot: TransformQ{ rotation(angle=5.58331, axis=(0, 0, -1)) }
        doorPosition: (-13538.2275390625, -71932.9140625, 161.3390045166015625)
        init: true
        region: bitter coast region
        current AI pkg: Wander
        state: default
        ======== Begin global data:
        enableCheckTime: nil
        enabled (engine): true
        enabled (mod): true
        indoors: false
        init: true
        isLocal: nil
        noDoor: nil
        disabledForQuest: false
        doorExitPos: (-13488.2646484375, -72070.9140625, 164.674102783203125)
        scheduledDisable: false
        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        End info For NPC: erene llenim
        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      
        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        Begin info For NPC: imperial guard
        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        current AI pkg: Wander
        state: unmanaged
        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        End info For NPC: imperial guard
        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      
    • The erene llenim NPC indicates that this mod is handling their schedule

    • In the output above, imperial guard is not handled by this mod as indicated by the unmanaged value

  7. Press F10 again to hide the log
  8. Press ` to hide the console

If you’ve noticed a problem with a particular NPC, the above steps will provide information that is useful to the mod developers in troubleshooting.

You can also search by record ID which does not require the NPC to be in view:

  1. Press ` to bring down the console

  2. Click on the NPC

  3. Type luag and press enter

  4. Type I.GoHome.GetNPC("shadbak gra-burbug") and press enter (replace shadbak gra-burbug with the record ID of the NPC you want to get data for)

  5. Press F10 to see the log

    • There should be several lines similar to what’s shown below:

        Global[scripts/go-home/global.lua]:    START GoHome data dump for NPC: eldafire (id: 0x101f7c3)
        Global[scripts/go-home/global.lua]:    table: 0x555b7bfe2720 {
          indoors = false,
          doorExitPos = (-11001.119140625, -70352.7578125, 376.002471923828125),
          doorExitRot = TransformQ{ rotation(angle=3.92699, axis=(0, 0, -1)) },
          disabledForQuest = false,
          defaults = table: 0x555b7bfe2840 {
            defaultPos = (-11421.5751953125, -68237.640625, 307.895355224609375),
            defaultRot = TransformQ{ rotation(angle=3.04159, axis=(0, 0, -1)) },
            defaultCell = Seyda Neen,
          },
          scheduledDisable = false,
          actor = object0x101f7c3 (NPC, "eldafire"),
          init = true,
          enabled = true,
        }
        L0x101f7c3[scripts/go-home/npc.lua]:   table: 0x555b7ebcce90 {
          init = true,
          doorPosition = (-10934.6142578125, -70251.8125, 393.878997802734375),
          defaultAIDuration = 5,
          disabledForQuest = false,
          defaultPosition = (-11421.5751953125, -68237.640625, 307.895355224609375),
          doorDestRot = TransformQ{ rotation(angle=0, axis=(0, 0, 1)) },
          doorDestPos = (125.28800201416015625, -239.207000732421875, -41.44699859619140625),
          defaultCell = Seyda Neen,
          doorDestCellName = Seyda Neen, Eldafire's House,
          defaultRotation = TransformQ{ rotation(angle=3.04159, axis=(0, 0, -1)) },
          defaultAIType = Wander,
          defaultAIIdle = table: 0x555b761c8b40 {
            idle7 = 0,
            idle4 = 10,
            idle9 = 0,
            idle5 = 10,
            idle2 = 60,
            idle6 = 0,
            idle8 = 0,
            idle3 = 20,
          },
          defaultAIDistance = 2000,
          state = go-to-default,
          defaultAIIsRepeat = true,
          region = bitter coast region,
        }
        L0x101f7c3[scripts/go-home/npc.lua]:   END GoHome data dump for NPC: eldafire (id: 0x101f7c3)
      
  6. Press F10 again to hide the log

  7. Press ` to hide the console

Use The Lua Console To Unstick An NPC In Game

If an NPC gets stuck while pathfinding, you can try the FixMe() interface command which may unstick them:

  1. Get the NPC you want to fix in view
  2. Press ` to bring down the console
  3. Click on the NPC
  4. Type luas and press enter
  5. Type I.GoHome.FixMe() and press enter
  6. Press ` to hide the console

This NPC will revert to their default state for fifteen seconds before the schedule kicks in again.

Please note that this is not guaranteed to resolve whatever issue it is that prevents the NPC from being stuck!

Please also note that this does not mean the NPC is broken; this behavior should resolve itself when the day/night cycle changes and their AI state changes. Wait for that to happen, things should go back to normal.

How To Test This Mod

If you’re trying to work with the code or just wanting to see it do what it says it should do, follow these steps to test out all of the features of this mod.

Please note that it’s recommended to enable debug logging prior to doing this, that can be done via the script settings menu at: ESC >> Options >> Scripts >> Go Home! >> Mod Settings >> Enable debug messages in the log

You may also want to reduce the various delay settings down to one second just so you can see things happen more quickly.

  1. Use the OpenMW feature to start a test character and spawn into Seyda Neen
  2. Press ` to bring down the console
  3. Type set gamehour to 22 and press enter
  4. Press ` to hide the console
  5. Several things will now happen:
    1. NPCs with a nearby home (that is, there’s a door that goes to a cell with their name in it) will begin to walk to their home after a (configurable) delay
      • These NPCs will actually be inside their home
      • At the moment I can’t change the AI package of NPCs in unloaded cells so they are just kinda standing there
    2. NPCs without such a home will be disabled when the player isn’t looking at them
    3. There’s a small (configurable) chance merchants will not go home or be disabled
  6. Press ` to bring down the console again
  7. Type set gamehour to 10 and press enter
  8. Press ` to hide the console
  9. Several things will now happen:
    1. NPCs that have a nearby home (as desribed above) will come back outside, walk to their original positions and resume their original AI package
    2. NPCs without a home will be enabled
  10. Press ` to bring down the console again
  11. Type changeweather "bitter coast region" 5 and press enter
  12. Press ` to hide the console
  13. After some time a thunderstorm will begin, then several things will happen:
    1. Same as at night, NPCs should go home or be disabled

Additional things to test:

  1. Disable “go home for bad weather” while NPCs have gone home for bad weather; they should come out and go back to their default AI package
  2. With “go home for bad weather” enabled, trigger a thunderstorm and make NPCs go home. Set the weather to clear; they should come out and go back to their default AI package
  3. Do a Factory Reset; see the mod disable. Disable it; see the mod re-enable.

See only local NPCs get enabled:

  1. Start out in Seyda Neen, run set gamehour to 22 in the console to make it night time
  2. Go to any other town (Pelagiad for example), then run set gamehour to 10 in the console to make it day time
  3. Note in the logs that non-local NPCs request enabling once and do not again until you change cells
  4. Also note that local NPCs enable as expected
Fish Bowl Test

Please note that it’s recommended to enable debug logging prior to doing this, that can be done via the script settings menu at: ESC >> Options >> Scripts >> Go Home! >> Mod Settings >> Enable debug messages in the log

A decent way to test the mod in a hands-off way is as follows:

  1. Use the OpenMW feature to start a test character and spawn into Seyda Neen
  2. Press ` to bring down the console
  3. Type set timescale to 1300 and press enter
  4. Type tcl and press enter (to disable collision, as needed)
  5. Press ` to hide the console
  6. Fly to some place near the center of Seyda Neen and just watch the log entries

You should be able to see NPCs regularly go home and come out as day and night passes or bad weather occurs. It’s a decent way to recreate a “real” scenario somewhat quickly.

Lua Exceptions Interface

Interfaces are available for all classes of exceptions, examples can be found below:

RegisterActorBlacklist

Add a specific NPC ID to the internal blacklist.

Usage:

I.GoHome.RegisterActorBlacklist({
    "Npc_ID_1",
    "Npc_ID_2",
    ...
})
RegisterGridCellWhitelist

Add a specific unnamed cell to the internal whitelist, use this for cels that are identified only by X and Y grid coordinates.

Usage:

I.GoHome.RegisterGridCellWhitelist({
    {x = -1, y = -7},
    {x = 3, y = -6},
    {x = 4, y = -5},
    {x = 4, y = -7},
    ...
})
RegisterNamedCellWhitelist

Add a specific named cell to the internal whitelist.

Usage:

I.GoHome.RegisterNamedCellWhitelist({
    "Cell Name One",
    "Cell Name Two",
    "Another Cell Name",
    ...
})
RegisterNoFindHome

Add a specific actor ID to the internal list of NPCs that shouldn’t have a home. Useful for when mods add a home for an NPC that they can’t successfully navigate to.

Usage:

I.GoHome.RegisterNoFindHome({
    "Actor_ID_1",
    "Actor_ID_2",
    ...
})
RegisterModBlacklist

Add a specific mod plugin to the internal list of mods to ignore. Note that mods such as Friends and Foes and Repopulated Morrowind won’t necessarily be stopped via this method (instead they will be blocked by script or some other means).

Usage:

I.GoHome.RegisterModBlacklist({
    "Mod One.esp",
    "Mod Two.omwaddon",
    ...
})
RegisterQuestExceptions

Tell this mod to ignore a specific NPC during specific journal indexes.

Usage:

I.GoHome.RegisterQuestExceptions({
    fargoth = {quest = "MS_Lookout", before = 20, after = 40},
    ["npc ID"] = {quest = "JournalID", before = 10, after = 55},
    ...
})
RegisterScriptWhitelist

Tell this mod to add a script name to its internal script whitelist.

Usage:

I.GoHome.RegisterScriptWhitelist({
    "Script_Name_1",
    "Script_Name_2",
    "Script_Name_3",
    ...
})
Adding Exceptions Via The Console

It may be useful to add an exception while playing for quick testing purposes. This can be done via the console:

  1. Press ` to bring down the console
  2. Type luag and press enter
  3. Type I.GoHome.RegisterNamedCellWhitelist("Some Cell To Whitelist") and press enter
    • Use another interface function from above as needed for the situation
  4. If you’re already in that cell, exit and re-enter to apply this mod to it
  5. Check the logs for information about affected NPCs

Please note that it’s recommended to enable debug logging prior to doing this, that can be done via the script settings menu at: ESC >> Options >> Scripts >> Go Home! >> Mod Settings >> Enable debug messages in the log

Creating An Exception Mod

The interface functions described above can be used in a 3rd party mod to extend this mod’s internal exceptions without directly modifying its source code.

To do this, two files are needed:

  1. YourAddonName.omwscripts with the following contents:
GLOBAL: scripts/YourAddonName/global.lua
  1. scripts/YourAddonName/global.lua with the following contents:
local GoHome = require("openmw.interfaces").GoHome

if not GoHome then
    error("ERROR: Go Home! is not installed!")
end

GoHome.RegisterNamedCellWhitelist({
        "New Cell name",
        "Another cell name",
        ...
})

GoHome.RegisterModBlacklist({
        "Conflicting mod.esp",
        "Another conflicting mod.esp",
        ...
})

File layout:

.
├── YourAddonName.omwscripts
└── scripts
    └── YourAddonName
        └── global.lua

Note you should change YourAddonName to match your mod’s name and the IDs used to match the IDs you want to add.

The GoHome variable gives you direct access to the Go Home! interface. You can use whatever script and path names you like, but it must be a global script.

Global Lua Interface

Use these from a global script or after doing luag in the in-game console:

IsActive()

Is this mod active and scheduling NPCs? Returns a boolean, true or false if it is or isn’t, respectively.

Usage:

I.GoHome.IsActive()
GetNPC(recordId)

Print a dump of all NPC data associated with the given recordId to the console. Useful for troubleshooting.

Usage:

I.GoHome.GetNPC("shadbak gra-burbug")
ShowAll()

Print a dump of all global data to the console. Useful for troubleshooting.

Usage:

I.GoHome.ShowAll()

Player Lua Interface

Use this by typing luap in the in-game console:

ShowLocalNPCs()

Shows all global data from the mod for nearby NPCs.

Usage:

I.GoHome.ShowLocalNPCs()

Report A Problem

If you’ve found an issue with this mod, or if you simply have a question, please use one of the following ways to reach out:

Planned Features