In order to make a plugin,
create a new class library in your IDE (this should be easy to figure out using the GUI)
The target framework must be compatible with .NET Framwork 3.5 (this is compatible with Unity)
(example code can be found below)
Once you compile the project, you'll find it's dll file in a directory like bin/debug/ This is the file you can drop in the Plugins folder of the Application.
Understanding class libraries
LyokoAPI comes in the form of a class library.
A class library is essentially a bunch of code that doesn't execute on it's own.
Thus, it can't be used by itself.
For C#, a library is compiled into a .dll file.
Fun fact: Windows uses dll's as well for its own use!In theory, you can use the dll's in other .NET languages like VB.NETYour Plugin must also be a class library
We recommend using the Early Access Program of JetBrains' Rider.
It's a renewable trial (lasts about a month), so it's essentially free.
To add a reference in Rider:
(Right click project) -> add reference -> add from.. -> select LyokoAPI.dll
Writing your plugin
There are of course, many ways to write a plugin,
but here is a 'template' that you can take inspiration from. See Plugin Introduction for more in-depth info.
Main class
Only ONE class per plugin should extend LyokoAPIPlugin.
publicclassMyPlugin:LyokoAPIPlugin//Extend the LyokoAPIPlugin class{publicoverride Name {get;} ="ExamplePlugin"; //set the name of the pluginpublicoverride Author {get;} ="Noob"; //set the author of the pluginprotectedoverrideboolOnEnable() {MyListener.StartListening(); //Starting to listen to events in the OnEnable() is recommendedreturntrue; //nothing went wrong, so we return true to show the plugin has been enabled properly }protectedoverrideboolOnDisable() { MyListener.StartListening() //Definitely stop listening to events OnDisable(), since code will still be run if you dont.
returntrue; //disabled succesfully, returning true. }/* * This method is run when a gamesession starts in the Application (if it has game sessions.) * */publicoverridevoidOnGameStart(bool storyMode) {MyListener.StopListening() //if your listners somehow break immersion, do this. }publicoverridevoidOnGameEnd(bool failed) {Sound sound; //fictional sound class, as an exampleif (failed) //if the player has lost the game { sound =Sounds.EPICFAIL; LyokoLogger.Log(Name, "Lol you failed you epic loser"); //this will appear in the log as "[ExamplePlugin] Lol you failed you epic loser"
}else { sound =Sounds.YAAY; }SoundPlayer.PlaySound(sound);MyListener.StartListening() //start listening because we stopped in OnGameEnd }}
Listener class
You dont need a seperate Listener class, but it looks clean and it's what we usually use internally.
publicstaticclassListener{privatestaticbool _listening =false;/* * These variables are needed to unregister events later. * We dont really recommmend this in this situation */privatestaticvar onTowerdeactivation;privatestaticvar onXanaAwaken;privatestaticvar onHijack;publicstaticvoidStartListening() {if(_listening)) { return;} //dont do anything if we're already listeningTowerActivationEvent.Subscribe(OnTowerActivation); //Give the method name without '()'. XanaDefeatEvent.Subscribe(DoAThing); //the name of the method doesn't matter as long as the return value and parameters are the same
TowerDeactivationEvent.Subscribe(tower =>KeyboardRGB.ResetColor()) //single statement lambda with one parameter XanaAwakenEvent.Subscribe(() => SoundPlayer.PlaySound(Sounds.BeethovensFifth)) //single statement lambda with no parameters
TowerHijackEvent.Subscribe((tower, oldactivator, newactivator) =>//multi statement lambda with 3 parameters {SoundPlayer.PlaySound(Sounds.Thief);OnTowerActivation(tower); //you can re-use methods if you want, they're still methods. }) _listening =true; }publicstaticvoidStopListening() { if (!_listening) {return;} //dont stop listening if we've already stopped (unregistering events that haven't been registered is harmless though)
TowerActivationEvent.Unsubcribe(OnTowerActivation);XanaDefeatEvent.Unsubcribe(DoAThing);/* * these unregister the listeners by using the delegate returned by Subscribe() */TowerDeactivationEvent.Unsubscribe(onTowerdeactivation);XanaAwakenEvent.Unsubscribe(onXanaAwaken);TowerHijackEvent.Unsubcribe(onHijack); }privatestaticvoidOnTowerActivation(ITower tower) {Color color; //fictional color classswitch(tower.Activator) {caseAPIActivator.XANA: color =Color.RED; break;caseAPIActivator.JEREMIE: color =Color.GREEN; break;caseAPIActivator.HOPPER: color =Color.WHITE; break; }KeyboardRGB.SetColor(color); //fictional KeyboardRGB class }privatestaticvoidDoAThing() {LyokoLogger.Log("ExamplePlugin","I did a thing!"); }}