[0.8.9][NK] Extending/overriding Core

johnycilohoklajohnycilohokla REGISTERED Posts: 283 Developer
edited December 2015 in Modding Tutorials

Overriding Files

TUG internally uses a VFS (Virtual File System) to locate files, this allows mods to override any file.

Overriding a file:
  • Make sure your mod is above "Game/Core" in /TUG/Config/mods.txt
  • Find the file you want to override
  • Take the relative path to /TUG/Game/Core/[Path]
  • Create a file in your mod (/TUG/Mods/[YourMod]/[Path])
  • Now TUG will load your file instead of the one in /TUG/Game/Core/

Important:
Overriding files should be avoided.
While it is possible to override a file, this might not be the best option, as it will leads to conflicts (2 mods overriding the same file).

For lua files there are 2 solution that can be used to override functions and prevent those conflicts.

Overriding functions

Fortunately lua classes are meta-table based, this means post-construction function overriding is possible and simple enough, it can be done by simply including the class you want override and redefining the functions.

This way of overriding functions allows multiple mod to extend the function, by creating a chain function.
-- First include the class you want to override
include("Scripts/SomeClass.lua")

-- Cache the base function
local SomeClass_SomeFunction = SomeClass.SomeFunction

-- Override the base function
SomeClass.SomeFunction = function (self, ...)
-- [Optional] Calling the base function
local ret = SomeClass_SomeFunction(self, ...)

-- Your code here
-- ...

-- return (if the function needs a return value)
return ret
end
Example:
BasePlayer:OnSuccessfulCraft
include("Scripts/Characters/BasePlayer.lua")

-- Example
local BasePlayer_OnSuccessfulCraft = BasePlayer.OnSuccessfulCraft
BasePlayer.OnSuccessfulCraft = function (self, craftedObj)
BasePlayer_OnSuccessfulCraft(self, craftedObj)
-- Your code here
end

Injecting mixins

There are 2 types of mixins, both types can be injected.

Mixins Tutorial

The constructor mixin will be suitable for most cases.
The constructor mixin will get the Constructor call.

Constructor Mixin:
-- Include the class
include("Scripts/Objects/SomeClass.lua")
-- Include the mixin
include("Scripts/Mixins/MyMixin.lua")

-- Cache the base constructor
local SomeClass_Constructor = SomeClass.Constructor
-- Override the constructor
SomeClass.Constructor = function(self, ...)
-- Call the base constructor
SomeClass_Constructor(self, ...)
-- Inject mixin
self:Mixin(MyMixin, ...)
end
There is also a way to inject a static mixin, this way is recommended if the object was already constructed.
The static mixin will not get the Constructor call.

Static Mixin:
-- Include the class
include("Scripts/Objects/SomeClass.lua")
-- Include the mixin
include("Scripts/Mixins/MyMixin.lua")

-- Inject mixin
SomeClass.StaticMixin(MyMixin)
My Blog
jc.png
  yt.png  t.png  

Comments

  • RawrRawr REGISTERED, Tester Posts: 511 Seed
    hehehe lua variable argument list syntax.
    For anyone unsure, it's the ... in a function call.
    and is then accessed as ... ...omgosh this destroys my visual understanding of dot notation for accessing variables. why lua? why!?
    Programmer, designer, artist.
  • johnycilohoklajohnycilohokla REGISTERED Posts: 283 Developer
    edited December 2015
    haha, yeah the syntax for varargs in lua is weird.
    I might do a simple tutorial on it later on, the one on lua-users.org is way too long.
    My Blog
    jc.png
      yt.png  t.png  
Sign In or Register to comment.