Weaver: A Game Engine for GNU/Linux

Documentation Tutorial Examples Download

Weaver Plugins

A plugin is a shared library loaded dinamically while a Weaver game is running, not during compilation. At least when a game is compiled to a Linux executable. If the game is compiled for the web browser, the plugins still work, but are injected in the game code during compilation. And perhaps isn't correct calling them "plugins" in this case.

Plugins allow you to modify and extend your games while they are running.

To create a new plugin, use the command:

weaver --plugin PLUGIN_NAME

Where PLUGIN_NAME is made of alphanumeric characters. When you run this command inside a weaver project directory, it creates the file plugin/PLUGIN_NAME.c. This is the plugin you should edit. Inside the file, you can read after the copyright comment:

#include "../src/weaver/weaver.h"

void _init_plugin_PLUGIN_NAME(W_PLUGIN){

}

void _fini_plugin_PLUGIN_NAME(W_PLUGIN){

}

void _run_plugin_PLUGIN_NAME(W_PLUGIN){

}

void _enable_plugin_PLUGIN_NAME(W_PLUGIN){

}

void _disable_plugin_PLUGIN_NAME(W_PLUGIN){

}

Don't change those function signatures. You can edit this file to add other functions if you wish, but don't add global variables in the file. The global state will be lost each time the plugin is reloaded. It's also not safe to call extern functions, because a lot of them use global variables, including functions like malloc.

These are harsh restrictions, but fortunally you can use all the Weaver functions, those beginning with the "W". Walloc is ok. Only those functions marked in the reference as not thread-safe shouldn't be accessed by plugins.

Those 5 functions in your plugin file are how the Weaver game will interact with the plugin. They are:

The Weaver program identify plugins using unique numbers. If you want to know the id number of your plugin, you can call the function W.get_plugin, passing it's name as a string. The function return sthe pligin id.

If you have a plugin id number, you can enable it with W.enable_plugin, passing it's id number as argument. When the plugin is enabled, it's function _enable_PLUGIN_NAME runs and then it's function _run_plugin_PLUGIN_NAME executes in each iteration of the main loop.

If you want to disable a plugin, pass it's number id to W.disable_plugin. When the plugin is disabled, it's function _disable_plugin_PLUGIN_NAME runs and then it's function _run_plugin_PLUGIN_NAME stops to run each iteration of the main loop.

If you just want to ask if a plugin is enabled, use the function W.is_plugin_enabled.

You can also reload the plugin passing it's id to W.reload_plugin. If the plugin wasn't modified this function does nothing. If you changed the plugin, then it's reloaded from the disk with the modifications. This is the function which can be run periodically if you want to develop part of your game with interactive programming.

As a plugin can't use global variables, it can have problems storing it's data. It can uses your game specific interface W.game, but sometimes you want to create some generic plugin not specific for only one game with one W.game struct. The solution is using W.set_plugin_data and W.get_plugin_data to store and retrieve data. These functions should be used inside a plugin, which should allocate it's own data and use these functions as a way to remember and access it, even if the plugin is reloaded.

You can create plugins which can enable themselves during initalization with this code:

void _init_plugin_PLUGIN_NAME(W_PLUGIN){
  int my_id = W.get_plugin("PLUGIN_NAME");
  W.enable_plugin(my_id);
}

If you want to prevent self-enabling plugins, define the macro W_PREVENT_SELF_ENABLING_PLUGINS in conf/conf.h.