> For the complete documentation index, see [llms.txt](https://lyokoapi.gitbook.io/lyokoapi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lyokoapi.gitbook.io/lyokoapi/docs/tutorials/your-first-plugin.md).

# Your First Plugin

## Creating the plugin project

In order to make a plugin, \
&#x20;create a new class library in your IDE (this should be easy to figure out using the GUI)\
&#x20;The target framework must be compatible with .NET Framwork 3.5 (this is compatible with Unity)\
&#x20;(example code can be found below)<br>

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. \
&#x20;A class library is essentially a bunch of code that doesn't execute on it's own.\
&#x20;Thus, it can't be used by itself. \
&#x20;For C#, a library is compiled into a .dll file.\
&#x20;*Fun fact: Windows uses dll's as well for its own use!*\
&#x20;*In theory, you can use the dll's in other .NET languages like VB.NET*\
&#x20;**Your Plugin must also be a class library**

### Referencing a class library

Adding a library (like LAPI) to your project is called referencing.\
&#x20;[Referencing in Visual Studio](https://learn.microsoft.com/en-us/visualstudio/ide/managing-references-in-a-project?view=visualstudio) (the 'browse' section)\
&#x20;[Referencing in Unity](https://answers.unity.com/questions/458300/how-to-use-a-external-dll.html)

We recommend using the Early Access Program of [JetBrains' Rider](https://www.jetbrains.com/rider/eap/).\
&#x20;It's a renewable trial (lasts about a month), so it's essentially free.

To add a reference in Rider:\
&#x20;(Right click project) -> add reference -> add from.. -> select LyokoAPI.dll

## Writing your plugin

There are of course, many ways to write a plugin,\
&#x20;but here is a 'template' that you can take inspiration from. See [Plugin Introduction](/lyokoapi/docs/lyokoplugin/introduction.md) for more in-depth info.

### Main class

Only ONE class per plugin should extend LyokoAPIPlugin.

```csharp
public class MyPlugin : LyokoAPIPlugin  //Extend the LyokoAPIPlugin class
{
  public override Name {get;} = "ExamplePlugin"; //set the name of the plugin
  public override Author {get;} = "Noob"; //set the author of the plugin

  protected override bool OnEnable()
  {
     MyListener.StartListening(); //Starting to listen to events in the OnEnable() is recommended
     return true; //nothing went wrong, so we return true to show the plugin has been enabled properly
  }

  protected override bool OnDisable()
  {
     MyListener.StartListening() //Definitely stop listening to events OnDisable(), since code will still be run if you dont.
     return true; //disabled succesfully, returning true.
  }
  /*
  * This method is run when a gamesession starts in the Application (if it has game sessions.)
  *
  */
  public override void OnGameStart(bool storyMode)
  {
    MyListener.StopListening() //if your listners somehow break immersion, do this.
  }

  public override void OnGameEnd(bool failed)
  {
    Sound sound; //fictional sound class, as an example
    if (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.

```csharp
public static class Listener
{
  private static bool _listening = false;
  /*
  * These variables are needed to unregister events later.
  * We dont really recommmend this in this situation
  */
  private static var onTowerdeactivation;
  private static var onXanaAwaken;
  private static var onHijack;

  public static void StartListening()
  {
    if(_listening)) { return;} //dont do anything if we're already listening

    TowerActivationEvent.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;
  }
  public static void StopListening()
  {
    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);

  }

  private static void OnTowerActivation(ITower tower)
  {
    Color color; //fictional color class
    switch(tower.Activator)
    {
      case APIActivator.XANA: color = Color.RED; break;
      case APIActivator.JEREMIE : color = Color.GREEN; break;
      case APIActivator.HOPPER : color = Color.WHITE; break;
    }
    KeyboardRGB.SetColor(color); //fictional KeyboardRGB class
  }

  private static void DoAThing()
  {
    LyokoLogger.Log("ExamplePlugin","I did a thing!");
  }




}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lyokoapi.gitbook.io/lyokoapi/docs/tutorials/your-first-plugin.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
