Jump to content

Recommended Posts

Hey there!

I've been modding DST for almost a year now, but I had to realise: I've only added extra prefabs and components to the game so far. I've never actually modified anything in-game before. I want to get out of my comfort zone, but I'm a bit unsure about how such strategies actually work.

As far as I know, the most commonly used line is the AddComponentPostInit one to change certain elements of a component. I've checked this method in some mods' coding, but I don't exactly understand their structure. What are must-have ingredients of these changes?

What's the equivalent of this for prefabs? Are they any different in their general structure?

The last thing I would like to ask is about their placement in a mod: These lines only take place in the modmain file or they need any extension in another file?

If this exact topic has been discussed in the past, feel free to navigate me to it. I've did a quick google before I've wrote the topic, but I've only found more specific questions about this area.

Thanks in advance, I'm really grateful for any help!

I'm gonna give you an answer, but don't expect everything to be correct as I don't have that much experience with it.

Spoiler

function EntityScript:AddComponent(name)
    local lower_name = string.lower(name)
    if self.lower_components_shadow[lower_name] ~= nil then
        print("component "..name.." already exists on entity "..tostring(self).."!"..debugstack_oneline(3))
    end

    local cmp = LoadComponent(name)
    assert(cmp, "component ".. name .. " does not exist!")

    self:ReplicateComponent(name)

    local loadedcmp = cmp(self)
    self.components[name] = loadedcmp
    self.lower_components_shadow[lower_name] = true

    local postinitfns = ModManager:GetPostInitFns("ComponentPostInit", name) 

    for i, fn in ipairs(postinitfns) do
        fn(loadedcmp, self) -- here the componentpostinit is added to the component
    end

    self:RegisterComponentActions(name)
end

 

This is the part in the code where the componentpostinit is added. This means, the first argument of your function is always the component itself, which is normally named self.

You have your component that is loaded and afterwards your function is added to it. That means if you have a function that is named the same as a function in the original component, it will be overwritten. This can be used by saving a function into a variable, then adding the same function again with some changes you want to make and then calling the original function. This way, you won't interrupt anything in the game.

Small example:

AddComponentPostInit("health",function(self)
	self.new_variable = "test"
end)

This just adds a new variable to the component health, which then every entity that has the component health will have.

Small example if you want to change a function within:

AddComponentPostInit("health",function(self)
	local old_setval = self.SetVal  --we save the function SetVal in a variable
    self.SetVal = function(self,val,cause,afflicter)  --we overwrite the function, we need to add the variable self before the normal variables of the function
      if self.inst.prefab == "mycharacter" then
        local new_val = val + 10
        return old_setval(self,new_val,cause,afflicter) --we call the original function, but change the value to +10
      else
        return old_setval(self,val,cause,afflicter) --if it's not our character, we let it run like normal
      end
end)

(Disclaimer: Not tested if it works :D )

This is called function hooking, a very good tutorial can be found here:

The equivalent to prefabs is prefabaddpostinit, there you also add your function to the fn() of the prefab. The difference with components is that most of them have function that are not defined locally, so you can overwrite them like I showed before.

You can also use AddClassPostConstruct, it works nearly the same, I'm unsure about the difference.

These functions only take place in the modmain, you don't need to add anything to additional files.

I hope this helps, perhaps somebody else can give a better and/or more correct explanation.

If something is unclear let me know!

  • Like 1
  • Thanks 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...