Skip to content

Enterprise grade Minecraft scripting adapter for Groovy, JavaScript, and Python

License

Notifications You must be signed in to change notification settings

OkaeriPoland/okaeri-poly

Repository files navigation

Okaeri Poly

License Total lines Repo size Contributors Discord

Enterprise grade Minecraft scripting adapter for Groovy, JavaScript, and Python. Created with okaeri-platform.

Requirements

Java 17 or newer. Using GraalVM will improve performance if JavaScript backend is required. It is also recommended not to run other plugins using Groovy/Jython, with exception to plugins using Poly as a script provider and a dependency.

Supported platforms

  • Bukkit: Spigot/Paper minecraft server plugin (disclaimer: requires version 1.13 or newer)
  • Bungee: BungeeCord/Waterfall minecraft proxy plugin (incoming)

Installation

Grab latest release jar for your platform and install it like any other plugin, e.g. put in plugins/ for Spigot/Paper and BungeeCord/Waterfall servers.

Put your script files inside plugins/Poly/scripts/ directory. File extension will determine backend to be used (groovy, js, py).

Development

Command support, event listeners, and scheduler can be accessed through script object/variable helper. This ensures script unloading unregisters commands, listeners, and cancels pending tasks.

@BaseScript BukkitGroovyScript script

import eu.okaeri.poly.api.bukkit.BukkitGroovyScript
import groovy.transform.BaseScript
import org.bukkit.event.player.PlayerJoinEvent

// groovy example (with @BaseScript)
listen(PlayerJoinEvent) { event ->
    logger.info("${event.player.name} joined the game!")
}
import org.bukkit.event.player.PlayerJoinEvent

// groovy example (dynamic properties)
script.listen(PlayerJoinEvent) { event ->
    logger.info("${event.player.name} joined the game!")
}

Bukkit

Backend Helper Note
Groovy BukkitGroovyHelper Exposes additional closure based methods for even better typing support. Use is optional and BukkitScriptHelper should work too.
JavaScript BukkitScriptHelper Uses generalized helper implementation with no custom additions. All needed methods are contained in BukkitScriptHelper.
Python BukkitPythonHelper Uses python functions instead of standard methods accepting java consumers/functions due to poor interop and language limitations.

Additional global variables:

  • plugin: instance of eu.okaeri.poly.bukkit.PolyPlugin
  • logger: instance of java.util.logging.Logger
  • server: instance of org.bukkit.Server

Demo project: bukkit-example-groovy, bukkit-example-javascript

Bungee

Backend Helper Note
Groovy BungeeGroovyHelper Exposes additional closure based methods for even better typing support. Use is optional and BungeeScriptHelper should work too.
JavaScript BungeeScriptHelper Uses generalized helper implementation with no custom additions. All needed methods are contained in BungeeScriptHelper.
Python BungeePythonHelper Uses python functions instead of standard methods accepting java consumers/functions due to poor interop and language limitations.

Additional global variables:

  • plugin: instance of eu.okaeri.poly.bungee.PolyPlugin
  • logger: instance of java.util.logging.Logger
  • proxy: instance of net.md_5.bungee.api.ProxyServer

Demo project: bungee-example

Dependency

Maven

Add repository to the repositories section:

<repository>
    <id>okaeri-repo</id>
    <url>https://storehouse.okaeri.eu/repository/maven-public/</url>
</repository>

Add dependency to the dependencies section:

<dependency>
    <groupId>eu.okaeri</groupId>
    <artifactId>okaeri-poly-[platform]-api</artifactId>
    <version>1.2.3</version>
    <scope>provided</scope>
</dependency>

Gradle

Add repository to the repositories section:

maven { url "https://storehouse.okaeri.eu/repository/maven-public/" }

Add dependency to the maven section:

compileOnly 'eu.okaeri:okaeri-poly-[platform]-api:1.2.3'

IDE

IntelliJ (Groovy)

my-poly-project/
    src/
        main/
            groovy/
                script1.groovy
                script2.groovy
    pom.xml
  • Using @BaseScript (recommended):
    • Create new (maven/gradle) project or use existing project of your choice.
    • Add poly-[platform]-api as a provided dependency.
    • Add platform provided dependencies (e.g. spigot-api).
    • Use BaseScript annotation in your scripts:
    @BaseScript BukkitGroovyScript script
    
    import eu.okaeri.poly.api.bukkit.BukkitGroovyScript
    import groovy.transform.BaseScript
  • Using dynamic properties:
    • Create new (maven/gradle) project or use existing project of your choice.
    • Add poly-[platform]-api as a provided dependency.
    • Add platform provided dependencies (e.g. spigot-api).
    • Open any .groovy script with Groovy support enabled.
    • Point your cursor on the script variable.
    • Press Alt + Enter and choose Add dynamic property 'script'.
    • Set property type to matching helper type (see sections above).
    • Optionally add additional variables that are specified.

IntelliJ (JavaScript)

my-poly-project/
    src/
        script1.js
        script2.js
    okaeri-poly-[platform]-api-[target].d.ts
    okaeri-poly-graal.d.ts
  • Create new (empty) project or use existing project of your choice.
  • Download .d.ts files for graal from releases.
  • Download .d.ts for your platform (or minimal target) from releases.
  • Put .d.ts files alongside your project .js files.

Details

Otherwise, standard implementation practices/limitations apply. This software is intended for advanced users that are not afraid to explore. See provider repos for more details:

Backend comparison

Backend Performance (OpenJDK 11) Performance (GraalVM 11) IDE Support (IntelliJ) Interoperability
⭐ Groovy (w. @CompileStatic) ⭐ Excellent ⭐ Excellent ⭐ Excellent ⭐ Excellent
⭐ Groovy 🔵 Good 🔵 Good 🟢 Very good ⭐ Excellent
🔵 JavaScript (Graaljs) 🟠 Fair 🟢 Very good 🟠 Fair 🟢 Very good
🟠 Python (Jython) 🔵 Good 🔵 Good 🔴 Poor 🟠 Fair

Performance

  • Excellent: almost the same or better as native, can be used even for most demanding tasks
  • 🟢 Very good: applicable for most of the tasks (expect at least 1/4 of native performance)
  • 🔵 Good: fast enough, but requires caution in possible hotspots
  • 🟠 Fair: fast enough to be used for basic tasks
  • 🔴 Poor: hardly usable in any case

IDE support

  • Excellent: good typing support, advanced auto-completion, advanced static-analysis
  • 🟢 Very good: good typing support, auto-completion, static-analysis
  • 🔵 Good: good typing support, may include basic auto-completion and static-analysis
  • 🟠 Fair: at least some typing support and usability for target language
  • 🔴 Poor: no real integration or cannot map java types

Interoperability

  • Excellent: integrating feels like Java or better, with almost no disturbances
  • 🟢 Very good: just another day in the office with minor disturbances here and there
  • 🔵 Good: it is good enough, but may require some patience with minor problems
  • 🟠 Fair: it kinda works, but requires some tricks or pesky wrappers, major headache
  • 🔴 Poor: almost no interop or really complicated