Hot loading manifests rules are changing!


#1

Hello modders!

I’m adding some restrictions to how manifests can be hot loaded.

When my changes get in you might see this message:
Hot loading manifests is only allowed before world generation completes -OR- for 'client_only' manifests from client lua. Ignoring hot load for: <your manifest path here>

So the new rule is you can hot load any manifest before the world generation is complete and you can hot load manifests from client side lua if that manifest has "client_only": true in it’s info block.

The motivation for this is related to multiplayer - we sync all of the mods and hot loaded manifests when new players join so that everything matches up. The use case for the client_only manifests are kingdom based UI changes like in Rayya’s Children, otherwise all players would all see the UI for the host player’s kingdom.

My guess is that most modders haven’t needed to use hot loaded manifests after world generation other than the kingdom based UI stuff - please let me know if I’m wrong about that, and if so how you’re using them!


#2

Quick question: What does hot loading mean?


#3

It means loading something dynamically. In this case, loading a manifest after the main mod has been already loaded in the game.

For example, the Rayya’s Children UI is only loaded whenever you choose to play as Rayya’s Children. That UI is hot loaded from a deferred manifest, meaning that it’s not loaded by default, but only when we tell it to.


#4

Yes exactly what Relyss said.

It looks like this:

-- hot load rayyas children ui mod
_radiant.res.apply_manifest("/rayyas_children/ui/manifest.json")

If you’ve never used apply_manifest no need to worry!


#5

I’m having a small problem with this and I’m not sure why.

So, I’m working with @DaniAngione to add compatibility between our mods.
The idea was that in his mod manifest, it would have a "server_init_script": "file(server)", declared, and its contents would be something like this:

trapper_plus = {}

function trapper_plus:_on_required_loaded()
	if archipelago_biome then
		_radiant.res.apply_manifest("/trapper_plus/mod_compatibility/archipelago_biome/manifest.json")
	end
end

radiant.events.listen_once(radiant, 'radiant:required_loaded', trapper_plus, trapper_plus._on_required_loaded)

return trapper_plus

This runs way before any world generation starts, but still shows that erro in the log:

Hot loading manifests is only allowed before world generation completes -OR- for `client_only` manifests from client lua. Ignoring hot load for:/trapper_plus/mod_compatibility/archipelago_biome/manifest.json

#6

Sorry to barge in, just wanted to add some context as well :smiley:
This is the solution that we (Bruno, actually :stuck_out_tongue: ) came up with after I failed doing a normal mixinto into his mod’s manifest.

I messaged him about it, since there are other mods that manage to mix into each other’s manifest successfully (i.e.: Archipelago Mod itself has a mix into BreweryMod’s manifest) and he found out that this happens because since the game has no proper mod order arrangement (which is good for the user, of course - makes things more simple) on the other hand the order seems to be alphabetical so my mod (starts with a T) fails to mix into his mod’s manifest since it starts with an ‘A’ :stuck_out_tongue:
He changed it to aatrapper_plus I think, and it worked :jubilant:

I know it is not the point of the thread - sorry - but I felt like pointing it out nonetheless because seems at least related in a way and any new changes could perhaps include a way to more easily patch manifests for mod interactions and compatibility; if the manifests are processed twice, it would make sense for the second processing to catch changes made by other manifests down the line, no?

Anyway, I’m not really proficient with lua and such yet, so I’m sorry if I didn’t get anything correctly :smiley:
/lurk


#7

[Update]

So, continuing my mod, one thing that was missing is that I created a different type of Smokehouse for the Rayya’s Children (that better fits their architecture) and needed to put it in the game should the player play with them. I decided to do that by creating a mixinto to the rayyas_children manifest.

Once again the “mod load order” became an issue. Trying it out with the mod named “trapper_plus” didn’t work, but changing it to “_trapper_plus” solved the issue.
Not having to arrange a load order is something good and I support it, it makes things much easier for the end user, encouraging mod usage;

On the other hand, modders should be given some form of control/bypass this without really having to rely on mod naming.
If is there one API/mod support change/etc that I could already request before 1.0/1.1 is this :merry:

How to do it is something I’m not sure of - I can come up with a couple of ways but I’m pretty sure proper engineers could figure out something;

my solutions would be:

  • Either some sort of flag in the manifest that signals this mod needs to be loaded first; That is, mods with that flag will be run immediately after radiant mod, just like stonehearth is. Something like this:
{
   "info": {
      "name": "Mod",
      "namespace": "mod",
      "version": 3
   },
   "default_locale": "en",
   "priority": true,

Should two or more mods have this flag, then the default alphabetical order should prevail but considering that this is mostly useful for very specific cases or core/base mods, it is supposedly something that shouldn’t be so frequent.

  • Create some sort of ‘array’ that could point out manifests that your mod require to be re-loaded. Such requirement should, of course, disregard itself (and just reload aliases, mixintos, etc…) to avoid possible loops and exceptions. But basically just an array that could be used to say “hey, my mod modifies this and that, so they should probably be reloaded”

Something like this:

{
   "info": {
      "name": "Mod",
      "namespace": "mod",
      "version": 3
   },
   "default_locale": "en",
   "force_reload": [
      "rayyas_children", "archipelago_biome"
   ]

Then again, these feel like very… makeshift solutions :joy:
As I mentioned, they’re mostly simple ideas regarding something far more complex and I’m pretty sure proper engineers can think of better and more elegant solutions. I mostly just wanted to transmit the idea and the necessity of this;

Of course, for now I can just name my mod _trapper_plus and deal with this; But this could be useful in the future for a variety of reasons.

Thanks!


Requests from modders to devs for 1.0 and 1.1
#8

Especially if someone then wanted to mod your mod, then they’d have to call it __trapper_plus! I like the idea of listing dependencies somewhere, probably in the manifest, similar to how you specify “force_reload” but without doing the initial pass of loading and then reloading them: just load everything once. The order of loading could be determined by checking the manifests before fully processing them, and any infinite loops could very quickly be filtered out and the game would prompt you to cancel loading or disable one or all of the looped mods (and since none of the base mods would be requiring user mods, the base mods would never get caught in a loop).


#9

Are you trying to change the model based on the selected kingdom? Or trying to make it craftable only for them?


#10

Changing the whole recipe, there are two recipes:
one crafts the RC version and uses clay, the other uses wood and crafts the ascendancy/northern alliance version. I’m not changing the model because that would cause issues should it be a multiplayer game where there are players from both factions, I assume?

So there are two actual entities, the smokehoues and the rc_smokehouse. The trapper crafting list has a single recipe declared: “smokehouse”, but the Rayya’s children manifest mixin mixes a file into the recipes.json changing the recipe file to the RC version.

It works just fine when the mod is renamed to _trapper_plus, and doesn’t work when not; so it really is just a load order issue indeed


#11

What if you try to add a custom trapper for rayya that has that recipe? Like it does with many classes that requires different recipes


#12

That’s how I first tried it, I looked for it to see how to make them have exclusive recipes. So my first attempt actually mixed a new trapper alias in the Rayya’s Children manifest with a mixed new description and recipe list, exactly how the professions work in RC.

It also worked with the same results but also only when renaming the mod to _trapper_plus :stuck_out_tongue:

I changed to that different way because in the end it’s the same result with less files (just a recipes.json mixin instead of that and a trapper_description.json mixin)

But the load order issue happened the same - probably because to allow the trapper to be a crafter and such I also have to make a new alias for it in my own mod itself - which gets loaded afterwards


#13

In that case I think you can do like I did in the past, create all recipes as normal in your own mod, but mark the recipes as locked by default and unlock it by a campaign at the game start for that kingdom.


#14

Does the campaign has to have some sort of dialogue or can it be “invisble”?


#15

It can be just the unlock recipe node. The problem is that it triggers the popup saying you got a new recipe, unless you write your own to avoid that.


#16

Hi hi, this thread and Max have convinced me to add a

"dependencies": [
      "rayyas_children", "archipelago_biome"
   ]

Type deal to the manifest, which would just sort your mod below the mods you list. Gonna have to figure out a warning for circular dependencies.

A couple notes,

  1. The mods aren’t loaded in alphabetical order afaik, at least they are not explicitly sorted, so it’s not reliable behavior.
  2. Hotloaded manifests should work until the game starts, so maybe there’s a bug there. What are the steps to repro this?

Thanks!


#17

I think what was in the post 5 (above) can be used to reproduce it
Have a server script in the manifest, and at that script call _radiant.res.apply_manifest()


#18

Got it, thanks :slight_smile:


#19

Hey @BrunoSupremo, @DaniAngione :slightly_smiling_face:

I think your example on post 5 would work if you listened to a different event, like 'stonehearth:biome_set' for example (you don’t need to check that the chosen biome was archipelago if you don’t want to). Or is then too late for your files?

Like the error message says, the deferred manifest can be loaded if you make one of your mods client_only
too (which might not be what you want).

It’s a bit confusing that the required_loaded event is not working as intended here. Are you sure that doing the mixintos in the main manifest doesn’t work? Or do you want to hotload them because they’re many?


#20

I think that specific case is solved now for us as I won over my lazyness and implemented fish material resource for recipes instead of only uris. I think we were trying to have a filter only show up when the other mod was active, so we were making mod A insert a instruction into B, so B could change A again… Something like that… Dani, did we solve the issue?

The biome_set event only fires at the first time creating a world though (I think). So later plays in the same save would not get the extra manifest. --As explained below, this is incorrect, it does fire as expected