Skip to content

How to make a plugin

IonutParau edited this page Oct 9, 2021 · 2 revisions

What is a plugin?

A plugin is an alternative for "background mods".

They can't add cells. Any changes to cell-based stuff would be revrted if it was ran when GetPlugin was called.

How do plugins work?

Whenever GetPlugin("plugin name here") is used, it first looks if there is a plugin and then, if there is, executes it. Then it gets what the plugin returns and GetPlugin returns it as well.

Plugins are meant as API enhancements/improvements.

But wait, what if my plugin needs to be loaded before all mods?

Well, there is the toinit.txt file in the plugins folder. It is like the mods.txt of plugins. Every plugin that has its name there in a seperate line from everything else will be executed.... before mods get even loaded in the mod cache.

How do I make a plugin?

You create a file in the plugins folder. That file is your plugin. It will be loaded into memory automatically but not executed

Then, the code you write in there will be executed whenever GetPlugin is called. Its easy to make a plugin when you consider the code i nthere to be the code inside the body of a function.

Example plugin that returns a table with some basic math operations.

local myMath = {}

function myMath.add(a, b)
  return a + b
end

function myMath.add(a, b)
  return a - b
end

function myMath.multiply(a, b)
  return a * b
end

function myMath.divide(a, b)
  return a / b
end

return myMath

Then in a mod using it:

local thatMathPlugin = GetPlugin("that math plugins name")

if thatMathPlugin == nil then error("Why no math plugin :'(") end -- GetPlugin returns nil if the plugin does not exist

local someSumOfNumbers = thatMathPlugin.add(a, b)

More advanced plugins.

"What if I don't want to override love.update to get my cool custom thing when updating"

Well, there is a way. Plugin bindings.

BindPluginFunctions

Binds the currently executed plugin's function to a function identifier/name.

Example:

function myCoolUpdateFunction(dt)
  print("Time inbetween updates in seconds: " .. dt)
end

BindPluginFunctions("update", myCoolUpdateFunction)

The function identifier actually determines when the function is called. Here are the vanilla ones:

  • "update", called every love.update, but after customupdate gets called for mods. Gets the time inbetween updates in seconds.
  • "draw", called every love.draw, but before customdraw gets called for mods, so mods cna still draw on top of you. Gets time inbetween frames and frame rate.
  • "cell-update", called every time a cell updates. Gets id, x, y, and rotation. Called before any of the mod's update functions.
  • "key-down", called whenever a key is pressed. Gets the key pressed, the keycode pressed and if it was preessed last frame as well.
  • "mouse-down", called whenever a mouse button is pressed. Gets the x of the mouse, the y of the mouse, the button pressed, if it was a touch, and how many presses happened.
  • "mouse-up", called whenever a mouse button is released. Gets same arguments as "mouse-down".
  • "cell-render", called whenever a cell is rendered. Called before any of the mod's onCellDraw, so they can still draw on top. Gets id, x, y, and direction of the cell.
  • "mouse-scroll", called whenever the mouse is scrolled. Gets x and y.

As you can see, plugins get less data then mods. That is because mods are about the cells, while plugins are about the API.

Custom plugin bindings.

Let's say you want your mod to talk to a plugin for some reason. Well then, you can make your own custom plugin binding system!

All you need to do is use RunPluginBinding()

Example:

-- Something happened that we need to send to our plugins, so lets notify them with our own plugin binding!

RunPluginBinding("cool indentifier", coolArgument1, coolArgument2, coolArgument3, etc, etc, etc)

Due to how RunPluginBinding works, any parameter after the identifier is gonna get fed as a parameter into that function.

Clone this wiki locally