Skip to content

Creating Custom Extensions

Antonio edited this page Oct 12, 2022 · 17 revisions

Rem's Studio and Rem's Engine can be extended using Java plugins and mods.

Typical use-cases are optional features, which use a lot of disk space, e.g. my Tsunami Simulation with NetCDF support. Additionally, this is an easy way to build your games using Rem's Engine, and the intended way for libraries: just create a mod or plugin.

When multiplayer is supported, mods will have to be installed on server and client side, while plugins are one-sided. (like in Minecraft, except there will be plugins for clients, which will no longer be called "mods")

Using extensions

To use your custom extension, or an extension from other people, put them into your mod or plugin folders in /user/<UserName>/.config/<GameName> or C:/Users/<UserName>/.config/<GameName>.

Warning: currently, there are no safety checks on extensions, so be sure to not download malware!

Creating an extension

  1. Create a new project in an IDE of your choice.
  2. Add the Rem's Studio / Rem's Engine executable .jar file to your list of libraries.
  3. Create a main Java or Kotlin class. This class will register classes and event listeners. It additionally may load libraries and configurations dynamically. For plugins, your main class needs to inherit from me.anno.extensions.plugins.Plugin, for mods from me.anno.extensions.mods.Mod.
  4. Create a file called extension.info. This file will contain all metadata about your extension. In IntelliJ Idea, best place this file in your assets directory.
  5. Hook into one of the initialization functions to register listeners, classes and such.

Creating the extension.info

The file needs to be formatted like YAML. Effectively, it is just

key1: value1
key2: value2

Indentation is ignored and trimmed away. Lines without colon are ignored, and can be used as comments. Keys are case-insentitive.

Here is a simple example for your own extension:

// for mods use "mod-name" as key
plugin-name: My First Plugin
// decide on a uuid, so other extensions could depend on yours
uuid: me.anno.myfirstplugin
// authors can be used for multiple authors
author: Antonio Noack
// extensions can rely on others, and will not be loaded, if the dependencies are missing
// separate multiple extensions by comma
// use their UUID for their unique identifier
dependencies: me.anno.anotherplugin, me.anno.firstmod
// in the description, you can write whatever you'd like; this may be visible with commands in-game
description: this is just a sample plugin
version: 0.0.1 alpha

// and lastly the most important property; your main class
// use dots as folder/package separators
main-class: me.anno.myfirstplugin.MyFirstPlugin

Plugin Main Functions

Plugins follow the Bukkit (Minecraft) scheme:

  • onEnable(), will be called first.
  • onDisable(), will be called on shutdown or reload.

When a new instance of your class is created, no heavy function shall be executed. Plugins generally should be reloadable and swappable at runtime.

There is no guarantee for onExit() to be called after the initialization functions, because the computer may loose power, or the program just might be killed. Therefore, you should save user progress regularly.

Mod Main Functions

Mods follow the Forge (Minecraft) principles:

  • onPreInit(), called once for every mod,
  • onInit(), called after all onPreInit() calls have finished,
  • onPostInit(), called after all onInit() calls have finished,
  • onExit(), on shutdown, or potentially a heavy reload.

When a new instance of your class is created, no heavy function shall be executed.

The idea of mods is that they not necessarily need to be reloadable, and are persistent over the whole runtime of the program. Still, when onExit() is called, all resources should be freed, and in theory, the mod shall be reloadable.

There is no guarantee for onExit() to be called after the initialization functions, because the computer may loose power, or the program just might be killed. Therefore, you should save user progress regularly.

Debugging/Testing your extensions

The easiest way to test your extension, is to create a static main() function in a local file.

  1. call me.anno.extensions.ExtensionLoader.loadMainInfo() to register your mod as a local mod (no jar inside mods/plugins required).
  2. create a new me.anno.studio.rems.RemsEngine() instance, or use the me.anno.studio.rems.RemsStudio instance.
  3. call run() on this instance.
  4. now start this main()-function, and the engine should start and load your extension.

If your extension cannot be loaded for some reason, take a look at the console output, and search in there for the name of your extension (e.g. MyFirstPlugin).

Clone this wiki locally