Kingdom Come: Deliverance

File information

Last updated

Original upload

Created by

dataframe - benjaminfoo

Uploaded by

dataframe

Virus scan

Safe to use

About this mod

This is a guide which describes the steps to setup the coding environment and how to develop lua-mods for KC:D.

Permissions and credits
Donations
Welcome to How-to Lua!


What is this?
This entry is not an actual mod, but a guide on how to develop Lua mods for kingdom come.

Why?
It’s a way to define, execute and evaluate logical statements (=coding), messing with the world, change parameters, etc. – and because there is no way (at least to my knowledge) – to execute custom code within the Cry Engine / KC:D as a game - this is not a mod - just a documentational resource!

Setup the environment
  • Download and install Kingdome Come: Deliverance via the platform of your choice.
  • Download the Official Kingdom Come Deliverance Modding Tools (6,4GB)
  • Extract the files of the zip into your KCD folder, so that the folder structure looks like the left side of the following image:



 
Tipp: It is possible to use only the game for Lua development, but the modding tools provide an alternative executable for KCD which contains more features related to Lua development.

4.     Next, locate the path: KingdomComeDeliverance\Bin\win64releasedll\
5.     Create a shortcut of the kingdomecome.exe, open the properties of the shortcut and add “-devmode” to the end of shortcut’s target, like in the following image:

 
6.     Now you’re good to go ?‍? – launch the game
7.     Et voila – as you can see within the main menu, thereis already something different about your game – in the top-right corner, development information can be seen:

 
As compared to the vanilla game:

 
How to Lua - 101
On the German keyboard, the circumflex-key (^) opens the developer console, press it:


 
As you can see, it’s possible to do some coding even without really playing the game – this is useful if you want to do some quick testing, etc.
 
Now,let’s do something simple – the most basic program every developer should be able to produce, is to print good old “Hello World” to a console – let’s do
this – enter #System.Log(“Hello World”) within the console and press enter:



Congratulations! You wrote and executed yourfirst Lua snippet / program within KC:D!
 
As you can see, its required to add a “#”before actual Lua code, so that the developer console can recognize it – if you don’t use a “#” before, your input gets interpreted as a engine-/game-command (something like cl_fov x to change the fov to x).
 
Develop a RBC

The next thing to do is some basic arithmetic calculations like simple additions – enter the following code:

# a = 1
# b = 2
# c = a+b
# System.Log(c)




 And voilá – you wrote your first RBC (really basiccalculator), which is able to calculate the result of 1+2 – I’m really getting hacker vibes in here.
 
Expending the RBC
So let’s say, you want to upgrade your RBC to a more useful tool which is able to add any two given numbers – for this we need a function which accepts to parameters and returns a result (disclaimer, this is not a basic lua or programming course by itself – don’t expect too much coverage on this topic) – so lets type:

function add (numberOne, numberTwo)
return numberOne+numberTwo
end


It works! As you can see, we can calladd(13,37) and the method returns 50, which is, prove me wrong but the windows calculator also proves it, 50.

We’ve to wrap add(13,37) with System.Log(…) because the add-function returns the result, but it doesn’t get printed to this console automatically this way.
 
And that’s basically it!


How to: auto-start a lua based mod
Until now, every time you want your code to get executed one has to call a method from the ingame-console - this isn't player friendly, so we need a way to call our code after the game has started and a new or existing game has been loaded - for this, one can use a scene-init listener.

Create a new text file at your mod directory and save it as "mod_startup.lua" or something, at the path:
KingdomComeDeliverance\mods\menu_template\Data\Scripts\Startup\mod_startup.lua

Add the following contents:
---
--- Entry point for the project
---

architect_init = {}


-- this listener gets called after a scene has been loaded or a new game started
-- we need to wait until the game is "ready" (not on the loading screen or some other 'invalid' state)
function architect_init:sceneInitListener(actionName, eventName, argTable)
    if actionName == "sys_loadingimagescreen" and eventName == "OnEnd" then
        Game.ShowTutorial("Ingame-Menu loaded\n", 10, false, true)
        -- execute your code here
    end
end

-- initialize the mod after the player-scene has started
UIAction.RegisterActionListener(architect_init, "", "", "sceneInitListener")

Launch your regular kc:d exe, or the one you added "-devmode" to and once you start a new game or load an existing one, you'll get greeted with the following dialog at the top right corner of your screen:


The code-listing above can be used as a starting point when developing lua based mods - add your custom lua code after -- execute your code here in line 13 to autostart your code - i've provided files one can use to start right in.



Hooking the Entity-Lifecycle
Executing code for changing parameters at runtime once is useful, but what if we want to execute code no only once, but continuously / as per every frame of the game? Maybe you want to raycast continuously in order to check if a player "sees" something, or check for a condition every second, update a value, etc. - this can be implemented by using an entity.

As quoted from the official documentation of the Cry Engine:
Entities represent elements in the world that can move, act and behave logically in the world - as opposed to a rock that won't change over time.


The Cry Engine contains an ECS (entity component system), where entities, for example, the player, are made of different components. Then there are systems which update the components of every entity for example every frame (just to cover the basics of an ECS, you don't need to understand this, but if you're interested read the wikipedia article for example, its a really interesting topic).

An entity, contains of at least two files, an *.ent file, and a lua file - the first file defines the entity itself and references the lua file, the second contains the actual implementation logic of the entity - and thats where the lifecycle comes into play - one method of this lifecylce is the "update" method, which gets called every frame (think of frames per second / fps) - this way we can execute code continuously!

Define an Entity
In your mod's data directory (under \KingdomComeDeliverance\mods\<your_mod_name>\Data\) create a directory which is called "Entities", and create a file called DemoEntity.ent within the Entities folder for example and add the following content:
<Entity
        Name="DemoEntity"
        Script="Scripts/Entities/Mod_DemoEntity.lua"
/>

Store the file at \KingdomComeDeliverance\mods\<your_mod_name>\Data\Entities\DemoEntity.ent. This will "register" a new entity-class (DemoEntity) within the engine, but at this point, we can't do anything with it, because we need to add the implementation of the entity. The file structure now looks like this:




Add the implementation to our Entity definition
Add another file, the lua implemention, at \KingdomComeDeliverance\mods\mod_template_entity_lifecycle\Data\Scripts\Entities\Mod_DemoEntity.lua, add the following content - I've added comments to almost every line, the important part is the DemoEntity.Client:OnUpdate() function - this will get executed by the engine itself, for every frame - simply add your code to this method to execute it every frame.

---
--- The DemoEntity contains its own lifecycle, this way you can hook into the update method and call your logic every frame
---
DemoEntity = {
    Client = {},
    Server = {},
    Properties = {
        bSaved_by_game = 0,
        -- Warning:
        -- should the entity saved within a savegame?
        -- If a user deletes your mod and uses the last save game, the engine will quit and shows an error, that this entity is missing
        -- This can be solved by simply dont saving the entity within the savestate of the game
        Saved_by_game = 0,
        bSerialize = 0
    },
    States = {  },
}


-- this is called every frame given the entity has been spawned
function DemoEntity.Client:OnUpdate()

    -- this will print the given string to the console == the console of the user gets spammed, don't do this when releasing a mod, but its helpful while in testing :)
    System.LogAlways("DemoEntity onUpdate has been called!")

end

-- this is called when the player saves or updates a save state - storing values for your entities
function DemoEntity:OnSave(tbl)
    System.LogAlways("DemoEntity OnSave")
end;

-- this is called when the player loads a save state - use this for restoring values when a game gets loaded
function DemoEntity:OnLoad(tbl)
    System.LogAlways("DemoEntity OnLoad")
end;

-- this is called once, use this for initializing stuff
function DemoEntity:OnReset()
    System.LogAlways("DemoEntity OnReset")

    self:Activate(1);
    -- self:SetCurrentSlot(0);
    -- self:PhysicalizeThis(0);
end;

-- this is called once, use this for initializing stuff
function DemoEntity.Server:OnInit()
    System.LogAlways("DemoEntity OnInit")

    if (not self.bInitialized) then
        self:OnReset()
        self.bInitialized = 1
    end
    


end;

-- this is called once, use this for initializing stuff
function DemoEntity.Client:OnInit()
    System.LogAlways("DemoEntity OnInit")

    if (not self.bInitialized) then
        self:OnReset()
        self.bInitialized = 1
    end ;

end;

-- this is called when the player saves or updates a save state - storing values for your entities
function DemoEntity:OnPropertyChange()
    self:OnReset();
    System.LogAlways("DemoEntity opc")
end;

function DemoEntity:OnAction(action, activation, value)
end

DemoEntity.Server.TurnedOn = {
    OnBeginState = function(self)
        BroadcastEvent(self, "TurnOn")
    end,
    OnUpdate = function(self, dt)
        --[[ do something every frame, like rendering, ai, ..]]
    end,
    OnEndState = function(self)

    end,
}

DemoEntity.Server.TurnedOff = {
    OnBeginState = function(self)
        BroadcastEvent(self, "TurnOff")
    end,
    OnEndState = function(self)

    end,
}

DemoEntity.FlowEvents = {
    Inputs = {
        TurnOn = { DemoEntity.Event_TurnOn, "bool" },
        TurnOff = { DemoEntity.Event_TurnOff, "bool" },
    },
    Outputs = {
        TurnOn = "bool",
        TurnOff = "bool",
    },
}

The file structure now looks like this:


Now we've created a entity definition, and an entity implementation - but this won't do anything, because the entity isn't spawned automatically - so as the last step, we need to spawn our entity via lua, with the following code:
demoEntityParams = {}
demoEntityParams.class = "DemoEntity"
demoEntityParams.name = "DemoEntity_Instance"
demoEntityEntity = System.SpawnEntity(demoEntityParams)
System.LogAlways("Spawning DemoEntity")

Simply copy the whole code, open the developer console within the game, type a single #, paste the code (via ctrl+v) into the console and hit enter (the code will overlap the valid console user-interface, but it still gets executed fine) - as I've added a simple log statement within the update method, you can see the developer console get spammed with the message "DemoEntity onUpdate has been called!" - this step however suffers from the same problem like the initial mod does - a user has to manually execute this code in order to make use of our funtionality, because to circumvent this, you simple can spawn the entity within the startup - just as explained before, use the mod_startup.lua file (I've also provided a download for this) and spawn the entity with it:

---
--- Entry point for the project
---

demo_mod_startup = {}


-- this listener gets called after a scene has been loaded or a new game started
-- we need to wait until the game is "ready" (not on the loading screen or some other 'invalid' state)
function demo_mod_startup:sceneInitListener(actionName, eventName, argTable)
    if actionName == "sys_loadingimagescreen" and eventName == "OnEnd" then
        
        Game.ShowTutorial("Ingame-Menu with entity loaded!", 10, false, true)
        
        if demoEntity == nil then
            demoEntityParams = {}
            demoEntityParams.class = "DemoEntity"
            demoEntityParams.name = "DemoEntity_Instance"
            demoEntityEntity = System.SpawnEntity(demoEntityParams)
            System.LogAlways("Spawning DemoEntity")
        end
        
    end
end

-- initialize the mod after the player-scene has started
UIAction.RegisterActionListener(demo_mod_startup, "", "", "sceneInitListener")

This way, the entity will get spawned after the user has created or loaded a game state - and thats it! Now you're able to do anything the LUA-API of KC:D has to offer - for example moving the player's transform given by dedicated rules, raycast every second in order to position something somewhere (spawning an entity at the players look position - feel free to experiment :-) !

I've provided another basic mod template, which includes the automatic startup of the code and the spawning of a self defined entity - feel free to learn or use it as a template / starting point for your mod!

The file- and directory structure should look like this:

KingdomComeDeliverance\mods\mod\<name_of_your_mod>\
Data\       
--- Entities\
------ DemoEntity.ent        - the definition of our entity
--- Scripts\            
------ Entities\
--------- Mod_DemoEntity.lua - the implementation of our entity
------ Startup\
--------- mod_startup.lua    - the startup script which spawns our entity
mod.manifast                 - contains information about the name, description and other infos about your mod



Tips & Tricks
  • If you're using the official modding tools (you have extracted the 6,4GB sdk into your KC:D folder), take a look at the \KingdomComeDeliverance\Data_reference\Scripts - directory - every Lua-file in the game is available there and makes a great learning resource
  • If you aren't using the official modding tools, take a look at the file \KingdomComeDeliverance\Data\Scripts.pak this is a regular archive which contains all scripts, just like the one explained above
  • Take a look at all the lua for example, especially the *Util.lua files contain fun and interesting bits
  • Take a look at other mods, you'll gain alot of knowledge from others work, don't forget to credit them if you use part of there work




Fun Stuff
As KC:D uses the CryEngine, there are still some 'leftovers' available to use in KC:D from different titles like Crysis, etc. - for example - the Frost-Post-Processing Effect - simply open the console, enter #System.SetScreenFx("ScreenFrost_Amount", 1) and see yourself - nano-suite activated! ->  





Additional Material