Loading Mods and Manifest Files


#1

So I created a mod today and I wanted to load it without replacing anything in the stonehearth mod. I used an override to replace the landscaper.luac file and such to get my new entities into the game. However, it appears that I need something else to get the mod to actually load than just to stick my files in a folder in the mods directory. I believe this has something to do with the manifest file I need to create for my mod. Does anyone have a nice easy example of a manifest file that isn’t quite as complicated as the stonehearth mod one? Or alternatively, can someone tell me if there is a different reason as to why my mod might not be loading?


#2

you need to create a manifest.json in your mod that contains something like this:

{
“overrides” : {
“stonehearth/…/…/…/landscaper.luac” :“file(your mod/…/yourfile.luac)”
}
}

first part is the location of the luac file in the vanilla game. Second part the locatio of the file in your mod.
You need to tell the game that you want to overwrite the game file with your file. Hope it helps.


#3

but is the path we provide in the manifest similar to a windows path with "/"s, or is it something like stonehearth:entities:trees ?


#4

Both. In this case, the landscraper does not have an alias, so it’s the absolute path (stonehearth/services/world_generation/landscraper.luac if I’m not mistaken). You can imagine that the engine first tries to resolve your alias and then executes the replacement on the (virtual) file system.

Two things you need to realise before doing that: First, your mod won’t work with people who have extracted/decompiled their smod (which would likely be including you). Second, it’s a horrible way of modding and should be avoided.


#5

Is there another way to change which trees are generated upon loading? I would certainly love to know of one. This was my solution since I couldn’t see another way, and I didn’t just want to replace one of the existing trees with my new one.


#6

You can always use the complete path. The alias is there for when Radiant moves the file around and then it does not break your mod.

@wanderson921

What do you want to do exactly? Just replace trees?


#7

I want to add a new tree to the list of possible generated trees. This one happens to be an apple tree (yes I saw someone else did this recently, but they just replaced bushes). So I want it to be able to generate all of the trees that currently exist, AND apple trees.


#8

There isn’t an official one (yet). If you want me to, I could add an API into RP for that though. The question is just what the nicest way would be, i.e. what the system would look like.

Currently it’s evaluating the tree type (oak/juniper/none) based on elevation (and a bit of chance). This could easily be modified to allow multiple trees using RP’s proposal system. So _get_tree_type needs to be overwritten.

However, this would require you to have three variants of the trees (which would be placed by the same rules - i.e. the more space that is supposedly available, the bigger the tree). That means that likely, _get_tree_name would need to be overwritten too, so you can have just one size of tree (or perhaps even multiple).

So basically, if I installed those two events, it would look like this, as complete lua…

local MOD = class()

	local entity_name = 'my_mod:apple_tree'

	function MOD:get_tree_type(event)
		if event.elevation > MIN_ALTITUDE and event.elevation < MAX_ALTITUDE then
			table.insert(event.proposals, entity_name)
		end
	end

	function MOD:get_tree_name(event)
		if event.type == entity_name then
			table.insert(event.proposals, { name = entity_name, priority = math.huge }) -- or use random/event.size to determine a proper size
		end
	end
		
	function MOD:__init()
		radiant.events.listen(stonehearth.world_generation, 'rp:get_tree_type', self, self.get_tree_type)
		radiant.events.listen(stonehearth.world_generation, 'rp:get_tree_name', self, self.get_tree_name)
	end
		
return MOD

(Prettier gist)

Not sure if that looks okay.


#9

Then mixintos sound more useful. it adds your tree to the list which the game picks his trees from.
So you need to mixinto your_tree.qb to all the small/medium/large trees files and a mixintos to the json files to add it to the list.
If you add harvesting of the apples you need to mixinto a file with the code for generating and harvesting the apples.


#10

Wrong. There’s no list the game picks trees from; they are generated and pretty much hardcoded (~ "stonehearth:" .. ("small" or "medium" or "large") .. "_" .. ("oak_tree" or "juniper_tree")

Which means he’d end up with a bunch of apple trees running around as stonehearth:*_*_tree, which might not be desirable for other mods (which check the alias). In addition,

is somewhat impossible since he doesn’t know which tree got turned into an apple tree and which one is a default one.

Honestly, just changing the oak trees is a horrible (from a cleanliness POV) way to do it.


#11

oh, well now I feel goofy… in web terms we’re basically talking about hardcoded vs relative paths…


#12

Which is exactly what he says he wants :stuck_out_tongue_closed_eyes:
I just tell him the easy way :smile:
Sure if he wants it harvestable your way is the way to go.


#13

Not exactly. I mean, if it isn’t an alias, then yes, it’s relative to mods/ (unless it was used with file(), in which case it’s relative to the mods directory (if the file() path was absolute) or the file’s location (if the file() path was relative)). Otherwise, the alias defines the location. Aliases are kind of like URIs in that sense, not exactly hardcoded as they are resolved but static.

I’ll go on a limb and say he wants to do more than a mere model change.


#14

Yeah I noticed that the trees were hard coded in there. I assume that this will change eventually, but for now I was trying to just change the file and overwrite the original one. I can make that aspect of the mod nicer later when there are official systems to do this sort of thing (hoping this isn’t just fantasy).

Right now I have the following in my manifest file:

{
“info” : {
“name” : “AppleTree”
}
“overrides” : {
"/stonehearth/services/world_generation/landscaper.luac" :“file(landscaper/landscaper.lua)”
}
}

I then put a log in landscaper.lua file I made to check if it loaded my version and it did not (I set up the logger properly already).


#15

Remove the ‘/’ in front of “stonehearth”. Check your stonehearth.log for information. A possibility - which I doubt - would be that at this point the file was already loaded and therefore your override does nothing.

Also, this isn’t as much about “nice” as about “being uncooperative”. By replacing the file, you are changing a game file - which means another mod which might does the same (or, in RP’s case, could provide better functionality) will get “left out”.


#16

I have run through many iterations (I just tried removing the “/” again) and it did not work. I also made a very obvious change to the file by making all juniper trees into oak trees so I could easily tell if it worked regardless of if there was a problem with my apple trees.


#17

"stonehearth/services/world_generation/landscaper.lua" : "file(exit.lua)" works flawlessly in rp_test and zzz_rp (loaded before resp. after stonehearth) on an extracted version of it.

"stonehearth/services/world_generation/landscaper.luac" : "rp_test/exit.lua" works fine with the compiled one.

Again: Check your stonehearth.log.


#18

Interesting, I believe it should work (and I’m glad it worked for you), I’m just curious why it isn’t working here. I will continue trying things and see if there is something I missed.


#19

Well I feel like a dope, I forgot the “,” after the info section. I am now getting an error that says the landscaper is nil, but that is a different error entirely to debug. Thanks everyone for your help!