TheMorningStar-Old_Enemy_Mod_Fix icon

Old Enemy Mod Fix

Makes old enemy mods spawn again when they install fine but never appear. Rewires the empty spawn list old-SDK enemy bundles load under REPOLib 4.x, so the enemy spawns at its normal rates.

Last updated 3 hours ago
Total downloads 11
Total rating 0 
Categories Mods Monsters AI Generated
Dependency string TheMorningStar-Old_Enemy_Mod_Fix-1.0.0
Dependants 0 other packages depend on this package

This mod requires the following mods to function

BepInEx-BepInExPack-5.4.2100 icon
BepInEx-BepInExPack

BepInEx pack for Mono Unity games. Preconfigured and ready to use.

Preferred version: 5.4.2100
Zehs-REPOLib-4.2.0 icon
Zehs-REPOLib

Library for adding content to R.E.P.O.

Preferred version: 4.2.0

README

Old Enemy Mod Fix

Makes old enemy mods spawn again when they install fine but never appear.

What it does

Enemy bundles built against an older REPOLib SDK load their spawn-object list empty under REPOLib 4.x. REPOLib sees an enemy with nothing to spawn, logs "no spawn objects found", and skips it. There is no crash, the enemy just never shows up. The prefab and setup are still in the bundle. This pulls them back out and rewires them right before registration, and the enemy spawns at its normal rates.

Installation

  1. Install BepInEx.
  2. Put OldEnemyModFix.dll in BepInEx/plugins/. Requires REPOLib.
  3. Install it next to the affected enemy mods. It contains no enemy content.

Confirmed working with

  • Rudeus-Vacuum_Enemy
  • souurdough-SpinosaurusIsCalling

Other old-SDK enemy mods with the same "no spawn objects found" log line should also work.

For developers - detailed breakdown

GUID: themorningstar.oldenemymodfix

One Harmony patch, a prefix on REPOLib.Modules.Enemies.RegisterEnemy(EnemyContent).

An old-SDK .repobundle contains an EnemyContent whose serialized _setup and _spawnObjects fields do not map to REPOLib 4.x's field layout, so both deserialize empty. The enemy prefab, a GameObject carrying an EnemyParent, and the EnemySetup ScriptableObject both still load, because the bundle's preload table pulls them into memory even though they are not top-level assets.

The prefix:

  1. Skips healthy content where Setup is non-null and SpawnObjects is non-empty, so new-SDK mods are never touched.
  2. Builds a haystack from the content's name and bundle name, for example "Vacuum Content" or "Enemy - Spinosaurus1", normalized to lowercase with spaces, dashes, and underscores stripped.
  3. Finds the prefab with Resources.FindObjectsOfTypeAll<EnemyParent>(), taking the one whose normalized enemyName is the longest token of at least three characters contained in the haystack. Longest match stops a short name from taking the wrong slot.
  4. Finds the matching EnemySetup by the same token, preferring one that already has spawn entries.
  5. Writes both into the private backing fields by reflection.

RegisterEnemy then does the rest: it registers the prefab as a network prefab and rebuilds enemySetup.spawnObjects, so the bundle's stale PrefabRefs are never read.

Identification is by name token. If the enemy's name appears nowhere in the content or bundle name, it logs a warning and skips rather than guess. It only helps mods whose plugin ran and handed REPOLib the content. A mod whose own Awake crashed before registering anything is Repo Old Mod Rescue's job.