Introduction
My name is Emu, in the Silver Ore Team I'm "that Ikarus guy" mainly involved in programming gameplay and broad mechanics. Outside the team, I strive to document ZenGin (Gothic's engine) the results of which can be seen on the Gothic Modding Community website.
If you have been in contact with Gothic modding, you have certainly met with such terms as "script packages" or "plugins". However, what are they? To answer that question, we must return to the beginning - the release of MDK (Mod Development Kit) tools for Gothic. The possibilities for editing gameplay were impressive, but modders quickly encountered limitations related to the lack of direct influence on the game code.
And to put it in human terms, it was impossible to do much beyond what we already knew from Gothic. We are not talking about the story here but gameplay. Let's give a simple example: We want to change the time during dialogue and dress the whole thing up with nice screen dimming. An effect is known, among others, from Chronicles of Myrtana where it was used during fast travel. Having access only to editable gothic scripts something like this was impossible to realize. Fortunately, only until...
Chapter 1: The Icarus Era
A workaround for such limitations was the Ikarus scripting package, released in 2010, which exploited a vulnerability in the Daedalus parser (Gothic's scripting language) and allowed access to the game's memory. This opened up almost infinite possibilities, and the biggest drawback of Ikarus was that it could only be used after starting a new game or loading a save. What did this memory access entail? And well, it allowed access to engine objects, or execution of machine code directly on the processor and thus many other operations. One of the most important features of the Icarus was also the provision of some engine classes, so having the address of an object you could turn it into instances and access its parameters.
Gradually, new features like G1 support were added to Icarus. Not much later, in 2011, another script package LeGo was created on its basis, offering more ready-made solutions for quick implementation in modifications. Any modder could now easily add new status bars such as stamina, or add any function to the so-called GameLoop, which meant that it would be called throughout the game. However, these are just examples, the possibilities were much greater: trialogues, cursor support, function hooking, saving any information to files, creating new zCViews, or support for new data types (int64, hashtables, queue). A lot of it right? And that's not even half of the things offered by this package. Of course, not everything was available right away. Many things were added in updates, and many bugs were fixed along the way.
Many great modifications have been created using Ikarus and LeGo, and an exemplary example of the use of this technology is the Myrtana Chronicles: Archolos. However, it was not without flaws, from the very beginning the biggest issue was optimization and in particular code execution time, which was simply long…
Chapter 2: The Birth of the Union
It wasn't until 2016 that a potential rival to the Icarus monopoly emerged. AST (Agama Script Tools), which later evolved into the Union, offered much more possibilities to interfere with the game engine, and working with it was much more convenient and closer to direct editing of the game's source code. An API with access to almost all classes and functions of the engine was provided. And thanks to initialization at the start of the game it was possible to interfere with the menu. It also disposes of Icarus' biggest problem - the long time needed to execute the code. Compiled plug-ins ran at the same speed as the game code.
Unfortunately, from the beginning, the Union suffered from one big problem - the lack of ready-made solutions. Since it was a new technology, there was no database of ready-made mechanics that a modder could add to his modification. The plug-ins themselves, written in C++, scared away Sunday modders, who preferred to continue using the outdated Icarus rather than learn the new technology even though its use is simpler in many aspects.
The Union cannot be denied one thing. It contributed to fixing many engine bugs and enabled the creation of universal plug-ins, significantly upgrading gameplay and working with almost any modification. Examples include zUtilities (quicksave, time acceleration, and many other improvements), QuickLoot (quick pick up of items, or Advanced Inventory (mouse support in inventory, adding favorite items).
All right, but what about modifications that use Union? Do such exist? Yes, they do exist, but due to the previously mentioned reasons, they are rather rare. The big project that relied on Union was to be the History of Khorinis, but we all know how the story turned out. This does not mean such modifications cannot be developed, an example of which is The story of Nek.
Chapter 3: The Present Times
What is the conclusion? Icarus - the bad guy, Union - the savior? Not necessarily.
It is known that wherever possible, it is best to use Union, but currently, the best solution in my opinion is to use both systems.
Ikarus applications
Trialogues
In the original game, conversations can only be held with one person at a time. However, one of the packages included in LeGo offers features to help you get around this restriction. In The story of Nek, you might experience conversations with multiple characters simultaneously as well.
Queuing of functions in AI
That is, the so-called AI_Function allows us to add any scripted function to the AI queue of the selected NPC. This allows us to create more advanced scenes and cutscenes on the game engine. Soon this application may be supplanted by Union with the zParserExtender plugin.
func void test()
{
// Normalna Funkcja:
// Mdl_ApplyOverlayMds(hero, "HUMANS_SPRINT.MDS");
// hero czeka 2s
AI_Wait(hero, 2.0);
// Zakolejkownaie funckji żeby wykonała sie dopiero po AI_Wait
AI_Function_NS(hero, Mdl_ApplyOverlayMds, hero, "HUMANS_SPRINT.MDS");
};
Cyclic functions
As the name says, these are functions that execute every specified time (or every frame). This is made possible by the FrameFunctions package, the use of which can be seen below. Such a solution makes it possible to trigger an action without the player's intervention (e.g. talking to an NPC), for example, only based on the distance to a certain place on the map.
func void Przyklad()
{
// Funkcja wywoływana będzie 5 razy w odstępach 3000ms = 3s
FF_ApplyOnceExt(MojaFunckja, 3000, 5);
};
func void MojaFunckja()
{
Print ("Gothic jest super");
};
Union applications
Complex mechanics
More complex systems should not be written using Ikarus because, as I mentioned before, it is slow. When implementing such things as new menus or minigames, for example, it is worth betting on Union.
Hooks - changing the operation of a function
If we want to change how some engine function works, we must write a so-called ‘Hook’. Ikarus also offers such a possibility, but it is much more efficient and easier to use Union. With such a Hook, we can, for example, update the stats we added in the character menu. If you want to learn more about this technique, I invite you here.
Externals
Functions available in the Daedalus that are not defined in scripts are called externals. They are used in invocating engine code from within scripts and are a better alternative to the CALL package known from Ikarus. I will not describe their detailed operation and creation process here, so for those interested, I recommend a dedicated article. In our modification, such externals are used at every step, from picking up an item by an NPC to blocking the player from accessing the menu (during cutscenes, of course).
Chapter 4: What's next?
That's right! What's next? Will Gothic modding always be broken up into Icarus and Union again?
Recently, the situation has slowly begun to change. Ikarus stopped receiving updates some time ago. Despite the emergence of new packages such as AFSP, some modders have decided to switch to Union.
Meanwhile, the mentioned Union is doing well and it is in the process of switching to the new ‘union-api’ and 'gothic-api', simultaneously making it independent from using the Union SDK and the older C++ standard. Also, a universal loader is created to allow plugins to run with SystemPack.
With the zParserExtender plugin, Ikarus begins to lose its exclusive features. Replacing it entirely is not easy, so using both tools will be the best solution for a while. However, it can be expected that Ikarus will cease to be widely used in the future and will remain only a (not for everyone pleasant) memory.