Jump to content

Include directories


Coolcat600

Recommended Posts

Is there a way to include an entire directory?

 

I could look through the LUA files and find out myself, but I figured I"d just ask.  The theory is this: I want to create a mod that dissects various LUAs that have not been disceted and taken apart by the the end of the various updates.

 

Example: hats.lua contains all of the various hats.  If I wanted to add a hat, I would have to add the hat to that file (presumably).  Now, if I do that, my changes could get overwritten by another mod who adds a hat or modifies a hat since it does not (seem) to load functions and select individual functions and class constructors taking the "last" one from a particular file or selection of mods.

 

I could, however, construct the LUA in such a way that it contained no individual hat descriptors but instead called in a hat directory each hat would have its own LUA and thus anyone adding or modifying a hat could use this structure going forward.

 

If I can include a directory in its entirety, then I could use this call, allow other people to use my hat.lua and we'd all be able to add/change hats as we see fit as long as it remained in the same directory.

 

So, is this possible?  Is it possible to "require <directory>/<wildcard"?

Link to comment
Share on other sites

You are overthinking this going in the wrong direction. There's nothing unique about hats.lua, you can build your own hats file with the bare essentials and get all the functionality you want. Code is code, right?

 

Also, the way the game works with mods makes it impractical to have multiple mod contributions in the same directory unless you are working on a collaboration of sorts.

Link to comment
Share on other sites

@Heavenfall

 

Perhaps I simply didn't dig enough into things.  I was under the assumption that to get it to be wearable as a "hat" (on the head) that it had to be within that file.  If I can simply add a call within my mod to create a new instance of the class and the game is not expecting it to be within hat.lua then I will be able to do what I want without requiring the include.

 

And it would be being worked as a collaboration of sorts.  After the final scheduled update I would dissect the files in question and then provide a file to anyone else who wants to make their mod compatible with anything I am doing (for instance, if I want to do a hat mod and somoene else does too) that we would all simply include it in a directory that would allow a single hat.lua to call in all files from anyone who puts a file within their mod, uses my hat.lua and then includes a directive within the specific directory.

 

Essentially, providing a tool to make any mod I make be compatible with anything else.  This also translates to other things like the gamelogic.lua and others, hat.lua was simply the latest example of things that I was looking at.

 

However, given that there seems (last I looked) to be some improvements and changes to the way files are segmented and what is kept within specific folders I want to make sure that I wait until the final update so that I'm not having to chase down bugs every few weeks because a change they made broke it (I'd rather do it every few months or when new DLC is released).

 

I simply want to produce a modding environment that is not going to inherently cause a problem for other modders while at the same time providing any other modder who might want to modify the same files a way to do so without the end user having to choose which mod to load.  gamelogic.lua is a great example, as you can't simply just overwrite a single function (I think you and I have discussed that before, perhaps it was a different modder).  So, by using a directory wide include I could modify the gamelogic.lua, edit the dissected files to my liking, while allowing any other modder who wishes to modify while maintaining compatibility with mine could do so with ease as long as they do not target the specific functions I am.

 

I really wish we'd just be able to set it so that the last creation of a specific function was what was used that way if we wanted to edit a function within gamelogic.lua we'd modify just that function and that it would be the only code within the file.  The game would import that as the function, and then the rest of the data would be maintained and the game would simply use the last declaration of the function without overwriting the entire file.

 

It probably doesn't help that I don't have a firm grasp of how the game imports the mod files.  I am under the understanding that putting a mod file within my folder overwrite the entire file that I am targeting.  Thus, if I wanted to change gamelogic.lua I would have to include every function, in addition to the one I want to change, and that it would be loaded instead of the original.  This would, of course, make it wholly incompatible with any other mods that modify gamelogic.lua and given that there are a variety of functions declared within gamelogic (one dealing with time, one with death, among others) there would certainly be instances where someone would want to change one function, but not the others, and so two modders would have to work together rather than simply being able to overwrite a target function.  By dissecting the files, then including the entire directory modders have the ability to add functions and edit functions without having to worry about their mod not working with others.  It allows multiple, smaller mods to work in tandem to achieve a result that is more in line with the universe that the user wants to create rather than having it having to be a major production by a single person or group of people.

 

Anyway, I'm long winded.  Sorry.  But I think I have explained what it is that I'm trying to accomplish by having it.  Though, you never did say whether or not it was possible to include a directory with a wildcard.  I can do testing, I just didn't know if anyone knew the answer right offhand. 

Link to comment
Share on other sites

Most everything is just one prefab or another - look up this:

http://forums.kleientertainment.com/index.php?/topic/25850-wots-the-diff-prefabs-components-stategraphs-and-brains/

 

It runs through most of the basic pieces the game is built on.

Want a thing in the world? Prefab. This is most everything, from hats to sticks to pigs.

Want a general pattern? Component. This is stuff like "hounded.lua" which causes the periodic dog attacks at your base camp

What different behavior in different circumstances? Stategraph & Brain

 

Your mod just defines them and adds them. They're added in different contexts (e.g. it looks for files in different places) but overall, anything you want to add (well, nearly everything) is just defined or referenced from some .lua file.

 

The core idea, and where to start? modmain.lua. Essentially this is ALL the game invokes - everything else is linked to from there. Add a brain? It knows to look in the brain folder but the name.

Link to comment
Share on other sites

I wanted to add that I overwrite only a single function with my "No Delete on Death" mod which keeps the game from deleting the save files.

 

simplex helped me get it working, the following code has been commented for better explanation.

 

GLOBAL.require "playerprofile"GLOBAL.require "playerdeaths"GLOBAL.require "saveindex"GLOBAL.require "screens/mainscreen"GLOBAL.require "screens/deathscreen"GLOBAL.require "screens/popupdialog"GLOBAL.require "screens/bigpopupdialog"GLOBAL.require "screens/endgamedialog" GLOBAL.package.loaded.gamelogic = true function GenerateFakeGameLogic()local f = GLOBAL.io.open("scripts" .. GLOBAL.package.config:sub(1,1) .. "gamelogic.lua", "r") -- Opens gamelogic.lud file into a variable.GLOBAL.assert(f, "Unable to open gamelogic.lua for reading!") local fake_game_logic, err = GLOBAL.load(function()local l = f:read()if l thenreturn l:gsub('local function OnPlayerDeath', 'function OnPlayerDeath', 1) .. "\n" -- Searches for the "OnPlayerDeath" function. Also pleaces it in a local variable.endend) f:close()--Closes the file. if not fake_game_logic then return GLOBAL.error(err) end GLOBAL.package.loaded.gamelogic = fake_game_logic() or true GLOBAL.assert( GLOBAL.OnPlayerDeath, "OnPlayerDeath is not global!" ) --The following code overwrites the OnPlayerDeath function.GLOBAL.OnPlayerDeath = (function(wilson, data) local cause = data.cause or "unknown"local will_resurrect = wilson.components.resurrectable and wilson.components.resurrectable:CanResurrect()   GLOBAL.TheMixer:PushMix("death")wilson.HUD:Hide() GLOBAL.Morgue:OnDeath({killed_by=cause, days_survived=GLOBAL.GetClock().numcycles or 0,character=GLOBAL.GetPlayer().prefab, location= (wilson.components.area_aware and wilson.components.area_aware.current_area.story) or "unknown", world=GLOBAL.GetWorld().meta.level_id or "unknown"})    local game_time = GLOBAL.GetClock():ToMetricsString()    GLOBAL.RecordDeathStats(cause, GLOBAL.GetClock():GetPhase(), wilson.components.sanity.current, wilson.components.hunger.current, will_resurrect) GLOBAL.ProfileStatsAdd("killed_by_"..cause)    GLOBAL.ProfileStatsAdd("deaths") --local res = TheSim:FindFirstEntityWithTag("resurrector")    if will_resurrect thenGLOBAL.scheduler:ExecuteInTime(4, function()  GLOBAL.TheMixer:PopMix("death")if wilson.components.resurrectable:DoResurrect() thenGLOBAL.ProfileStatsAdd("resurrections")else-- HandleDeathCleanup(wilson, data)endend)else-- HandleDeathCleanup(wilson, data)endend)end AddGamePostInit(GenerateFakeGameLogic)

 

Link to comment
Share on other sites

Most everything is just one prefab or another - look up this:

http://forums.kleientertainment.com/index.php?/topic/25850-wots-the-diff-prefabs-components-stategraphs-and-brains/

 

It runs through most of the basic pieces the game is built on.

Want a thing in the world? Prefab. This is most everything, from hats to sticks to pigs.

Want a general pattern? Component. This is stuff like "hounded.lua" which causes the periodic dog attacks at your base camp

What different behavior in different circumstances? Stategraph & Brain

 

Your mod just defines them and adds them. They're added in different contexts (e.g. it looks for files in different places) but overall, anything you want to add (well, nearly everything) is just defined or referenced from some .lua file.

 

The core idea, and where to start? modmain.lua. Essentially this is ALL the game invokes - everything else is linked to from there. Add a brain? It knows to look in the brain folder but the name.

Yes, I know that it is the case, but when I was looking for the miner helmet I noticed that all the hats seemed to be contained within a single file and so I (incorrectly) jumped to the conclusion that for a hat to be able to be in the hat slot on the character, it would be required to be in the hat lua file.  Since that is not the case, this changes things and makes things a lot easier for a few of the mods I have in mind.  

 

I still wish they would separate things out a bit more so that things like gamelogic.lua only contained the logic required to run the game.  Things like the advancing of day and night would fall in this category, and calling behaviors of creatures, but even the seasons should be out in a different file (perhaps called into the gamelogic file and possibly have a few of its functions ran) but by having the seasons, the advancement of the day and behaviors associated with each tick of the clock, the function of the weather and the actions on death separated would allow a single modder who wishes to target just one of those, and not all of them, to do so without running into compatibility issues.  The poster after you shows a way to inject and overwrite a function but I tend to try and avoid doing it that way as it is hackish and it bothers me to do it that way for some reason.  I may have to, if the files are what they are when the final update rolls out.  But I have some plans to modify portions of the game in order to make it easier for those who want it, harder for those who don't and modify various in-game items in order to bring some consistency to the items that are found within the game (For example, why are we able to refuel our lantern, but not our miner's hat?  Why is guano considered absolutely inappropriate for the creation of a farm, when you can use it as very effective fertilizer? Etc...)

 

They're rather ambitious, and so I'm not going to be doing anything until I know there will not be any major changes and I have the personal time to devote to it.  Since it is merely a hobby and not a job, I want to make sure that I won't be ignoring any of my RL duties to mod, but also want to create these mods so that other people can enjoy the game in various ways.  That, and it just gives me something to do other than browse the internet or play games.

 

I wanted to add that I overwrite only a single function with my "No Delete on Death" mod which keeps the game from deleting the save files.

 

simplex helped me get it working, the following code has been commented for better explanation.

 

GLOBAL.require "playerprofile"

GLOBAL.require "playerdeaths"

GLOBAL.require "saveindex"

GLOBAL.require "screens/mainscreen"

GLOBAL.require "screens/deathscreen"

GLOBAL.require "screens/popupdialog"

GLOBAL.require "screens/bigpopupdialog"

GLOBAL.require "screens/endgamedialog"

 

GLOBAL.package.loaded.gamelogic = true

 

function GenerateFakeGameLogic()

local f = GLOBAL.io.open("scripts" .. GLOBAL.package.config:sub(1,1) .. "gamelogic.lua", "r") -- Opens gamelogic.lud file into a variable.

GLOBAL.assert(f, "Unable to open gamelogic.lua for reading!")

 

local fake_game_logic, err = GLOBAL.load(function()

local l = f:read()

if l then

return l:gsub('local function OnPlayerDeath', 'function OnPlayerDeath', 1) .. "\n" -- Searches for the "OnPlayerDeath" function. Also pleaces it in a local variable.

end

end)

 

f:close()--Closes the file.

 

if not fake_game_logic then return GLOBAL.error(err) end

 

GLOBAL.package.loaded.gamelogic = fake_game_logic() or true

 

GLOBAL.assert( GLOBAL.OnPlayerDeath, "OnPlayerDeath is not global!" )

 

--The following code overwrites the OnPlayerDeath function.

GLOBAL.OnPlayerDeath = (function(wilson, data)

local cause = data.cause or "unknown"

local will_resurrect = wilson.components.resurrectable and wilson.components.resurrectable:CanResurrect() 

 

 

GLOBAL.TheMixer:PushMix("death")

wilson.HUD:Hide()

 

GLOBAL.Morgue:OnDeath({killed_by=cause, 

days_survived=GLOBAL.GetClock().numcycles or 0,

character=GLOBAL.GetPlayer().prefab, 

location= (wilson.components.area_aware and wilson.components.area_aware.current_area.story) or "unknown", 

world=GLOBAL.GetWorld().meta.level_id or "unknown"})

    

local game_time = GLOBAL.GetClock():ToMetricsString()

    

GLOBAL.RecordDeathStats(cause, GLOBAL.GetClock():GetPhase(), wilson.components.sanity.current, wilson.components.hunger.current, will_resurrect)

 

GLOBAL.ProfileStatsAdd("killed_by_"..cause)    

GLOBAL.ProfileStatsAdd("deaths")

 

--local res = TheSim:FindFirstEntityWithTag("resurrector")

    

if will_resurrect then

GLOBAL.scheduler:ExecuteInTime(4, function()  

GLOBAL.TheMixer:PopMix("death")

if wilson.components.resurrectable:DoResurrect() then

GLOBAL.ProfileStatsAdd("resurrections")

else

-- HandleDeathCleanup(wilson, data)

end

end)

else

-- HandleDeathCleanup(wilson, data)

end

end)

end

 

AddGamePostInit(GenerateFakeGameLogic)

My only problem with this (and it certainly not only works but maintains compatibility with other mods who modify the gamelogic.lua file), is that I don't like rewriting via a mod.  It works, but I'd rather this be the inherent functionality when developing a remake of a specific function.  Even if there is a lua (from Klei) that has a script to rewrite a function, I would personally feel better as that would make it more or less supported and less prone to break.  But I will certainly look at it.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...