With the new major update revision there are some breaking changes which makes the previous autoloader structure obsolete and no longer functioning.
We’ve spent alot of time to make sure we can call different methods during and after startup where it is needed, and we have moved from just calling exec function to make every mod register to a mod load list, and register each entry point in a generic setup function. This is a major step for standarization but also stability for your server as it will make it easier for mod creators to insert functionality where it is needed.
New structure
One file is all that is needed, no further db.cs or postInit.cs. With version 2.0.0, you only need to make one .cs file and name it mod.cs in your mod folder. Within this you will make all necessary registrations to our hook callback system that will execute your mod at the specified events and register your mod as loaded.
Hook overview
Hook array |
Arguments |
Description |
$LiFx::hooks::mods | This is the mod entrypoint, you have to register your mod and the setup function to this hook for it to load, see example below. | |
|
||
$LiFx::hooks::onStartCallbacks
|
%this | Executes when onStart is called by the server code and should be your main entry point for your mod to execute and load configuration. |
$LiFx::hooks::onConnectRequestCallbacks
|
%this, %gameConnection, %netaddress, %name | |
$LiFx::hooks::onPostConnectRoutineCallbacks
|
%this, %gameConnection, %netaddress, %name | |
$LiFx::hooks::onPreConnectRequestCallbacks
|
%this, %gameConnection, %netaddress, %name | |
$LiFx::hooks::onPostInitCallbacks
|
%this | Executes when onInit has ran and is where you need to register BasilMod pack commands to ensure that BasilMod syncs your server files to the client |
$LiFx::hooks::onInitServerCallbacks
|
%this | Executes after DB changes and initial load of network |
$LiFx::hooks::onInitServerDBChangesCallbacks
|
%this | Registering a function on this hook will execute your db calls just after dbi is initialized and before the server loads information from the database. |
$LiFx::hooks::onSpawnCallbacks
|
%this, %client | Will execute your registered function every time a player spawns |
$LiFx::hooks::onConnectCallbacks
|
%this, %client | Will execute one time per connecting client |
$LiFx::hooks::onDisconnectCallbacks
|
%this, %client | Will execute one time per disconnecting client |
$LiFx::hooks::onJHStartCallbacks
|
%this | Will execute registered function on JH Start event |
$LiFx::hooks::onJHEndCallbacks
|
%this | Will execute registered function on JH End event |
$LiFx::hooks::onDeathCallbacks
|
%this, %CharID, %isKnockout, %Tombstone | Executes on death event |
$LiFx::hooks::onKillCallbacks
|
%this, %CharID, %KillerID, %isKnockout, %Tombstone | Executes on kill event (reverse objects of onDeath) |
$LiFx::hooks::onSuicideCallbacks
|
%this, %CharacterID, %isKnockout, %Tombstone | Executed in case of a suicide |
$LiFx::hooks::onTick
|
%this | Call a mod function every 5 seconds |
Registering to the objects_types table
With 2.0.0 we’ve added a simplified version to release mods that add new objects to the game, which requires that you write to the objects_types table.
This is done by the autoloader if your mod has registered a objects_types object as the example below shows. We’ve added a new global function LiFx::registerObjectsTypes(object, class) that takes two arguments, an object definition that defines the row to be inserted as well as a reference to your own mod class.
It is very important that the ID you choose is unqiue and not used by any other object in the game, if you have duplicates your server will fail to start or not give you the right object in game. Please register your mod and get a id range from /info/object-id-list/ so that we can avoid having conflicting mods.
The object is predefined as ObjectsTypes from the autoloader but you can alter the contents and return your own definition:
return new ScriptObject(ObjectsTypesTavern : ObjectsTypes) { id = 2424; // this id HAS to be unique ObjectName = "Tavern"; ParentID = 72; IsContainer = 0; IsMovableObject = 0; IsUnmovableobject = 1; IsTool = 0; IsDevice = 0; IsDoor = 0; IsPremium = 0; MaxContSize = 0; Length = 0; MaxStackSize = 0; UnitWeight = 400000; BackgrndImage = ""; WorkAreaTop = 0; WorkAreaLeft = 0; WorkAreaWidth = 0; WorkAreaHeight = 0; BtnCloseTop = 0; BtnCloseLeft = 0; FaceImage = "mods\\\\ExampleMod\\\\buildings\\\\masonry\\\\residential\\\\Tavern\\\\tavern.png"; Description = "Stone Tavern"; BasePrice = 0; OwnerTimeout = 0; AllowExportFromRed = 0; AllowExportFromGreen = 0; };
Example mod
Example mod.cs:
/** * <author></author> * <url>lifxmod.com</url> * <credits></credits> * <description></description> * <license>GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007</license> */ // ---------------- hook overview // $LiFx::hooks::onSpawnCallbacks = JettisonArray("onSpawnCallbacks"); // $LiFx::hooks::onConnectCallbacks = JettisonArray("onConnectCallbacks"); // $LiFx::hooks::onConnectRequestCallbacks = JettisonArray("onConnectRequestCallbacks"); // $LiFx::hooks::onPostConnectRoutineCallbacks = JettisonArray("onPostConnectRoutineCallbacks"); // $LiFx::hooks::onPreConnectRequestCallbacks = JettisonArray("onPreConnectRequestCallbacks"); // $LiFx::hooks::onDisconnectCallbacks = JettisonArray("onDisconnectCallbacks"); // $LiFx::hooks::onDeathCallbacks = JettisonArray("onDeathCallbacks"); // $LiFx::hooks::onKillCallbacks = JettisonArray("onKillCallbacks"); // $LiFx::hooks::onSuicideCallbacks = JettisonArray("onSuicideCallbacks"); // $LiFx::hooks::onJHStartCallbacks = JettisonArray("onJHStartCallbacks"); // $LiFx::hooks::onJHEndCallbacks = JettisonArray("onJHEndCallbacks"); // $LiFx::hooks::onCharacterCreateCallbacks = JettisonArray("onCharacterCreateCallbacks"); // $LiFx::hooks::onStartCallbacks = JettisonArray("onStartCallbacks"); // $LiFx::hooks::onPostInitCallbacks = JettisonArray("onPostInitCallbacks"); // $LiFx::hooks::onInitServerCallbacks = JettisonArray("onInitServerCallbacks"); // $LiFx::hooks::onInitServerDBChangesCallbacks = JettisonArray("onInitServerDBChangesCallbacks"); // --------------- objects_types db manipulation // LiFx::registerObjectsTypes(ExampleMod::ObjectsTypesBazaar(), ExampleMod); if (!isObject(ExampleMod)) { new ScriptObject(ExampleMod) { }; } package ExampleMod { function ExampleMod::setup() { // Register callback hooks, do not run any form of code that does anything here, just queue the code LiFx::registerCallback($LiFx::hooks::onSpawnCallbacks, onSpawn, ExampleMod); LiFx::registerCallback($LiFx::hooks::onConnectCallbacks, onConnect, ExampleMod); LiFx::registerCallback($LiFx::hooks::onDisconnectCallbacks, onDisconnect, ExampleMod); LiFx::registerCallback($LiFx::hooks::onDeathCallbacks, onPlayerDeath, ExampleMod); LiFx::registerCallback($LiFx::hooks::onKillCallbacks, onPlayerKilled, ExampleMod); LiFx::registerCallback($LiFx::hooks::SuicideCallbacks , onSuicide, ExampleMod); LiFx::registerCallback($LiFx::hooks::onJHStartCallbacks, JHStart, ExampleMod); LiFx::registerCallback($LiFx::hooks::onJHEndCallbacks, JHEnd, ExampleMod); LiFx::registerCallback($LiFx::hooks::onStartCallbacks, onServerStarted, ExampleMod); LiFx::registerCallback($LiFx::hooks::onPostInitCallbacks, RegisterBasil, ExampleMod); LiFx::registerCallback($LiFx::hooks::onInitServerCallbacks, onInitServerCallbacks, ExampleMod); LiFx::registerCallback($LiFx::hooks::onInitServerDBChangesCallbacks, DbChanges, ExampleMod); LiFx::registerObjectsTypes(ExampleMod::ObjectsTypesBazaar(), ExampleMod); } function ExampleMod::onSpawn(%this, %client) { echo(%this.getName() SPC %client.getName()); } function ExampleMod::onConnect(%this, %obj) { echo(%obj.getName()); } function ExampleMod::onDisconnect(%this, %obj) { echo(%this.getName()); } function ExampleMod::onCharacterCreate(%this, %obj) { echo(%this.getName()); } function ExampleMod::onPlayerDeath(%this, %CharID, %isKnockout, %Tombstone) { echo(%this.getName() SPC %sourceObject.getName() SPC %sourceClient.getName() SPC %damageType SPC %damLoc); } function ExampleMod::onPlayerKilled(%this, %CharID, %isKnockout, %Tombstone) { echo(%this.getName() SPC %sourceObject.getName() SPC %sourceClient.getName() SPC %damageType SPC %damLoc); } function ExampleMod::onSuicide(%this, %CharID, %isKnockout, %Tombstone) { echo(%this.getName() SPC %sourceObject.getName() SPC %sourceClient.getName() SPC %damageType SPC %damLoc); } function ExampleMod::JHStart() { echo("JH Started"); } function ExampleMod::JHEnd() { echo("JH Ended"); } function ExampleMod::onServerStarted() { echo("JH Server started"); } function ExampleMod::RegisterBasil() { //BasilMod::pack_content("mods/RPClif/2D/StoneGates.png"); echo("Pack Basil"); } function ExampleMod::DbChanges() { echo("\n\nDB Changes\n\n"); } function ExampleMod::ObjectsTypesBazaar() { // this returns and writes to the dump.sql file for ease of distribution return new ScriptObject(ObjectsTypesBazaar : ObjectsTypes) { id = 2420; ObjectName = "Bazaar"; ParentID = 61; IsContainer = 0; IsMovableObject = 0; IsUnmovableobject = 1; IsTool = 0; IsDevice = 0; IsDoor = 0; IsPremium = 0; MaxContSize = 0; Length = 0; MaxStackSize = 0; UnitWeight = 5000; BackgrndImage = ""; WorkAreaTop = 0; WorkAreaLeft = 0; WorkAreaWidth = 0; WorkAreaHeight = 0; BtnCloseTop = 0; BtnCloseLeft = 0; FaceImage = "mods\\\\ExampleMod\\\\buildings\\\\construction\\\\misc\\\\BazaarHall\\\\BazaarHall.png"; Description = "Bazaar tent"; BasePrice = 0; OwnerTimeout = 0; AllowExportFromRed = 0; AllowExportFromGreen = 0; }; } }; activatePackage(ExampleMod); LiFx::registerCallback($LiFx::hooks::mods, setup, ExampleMod);