Skip to content

Repository files navigation

DSL Minigame Library for Spigot/Paper

A heavily DSL-based minigame library for Paper and Spigot, allowing you to scope chapters of your game (such as countdown, active round, between rounds, end game) into eventScope {} blocks.

The ethos of this library is to reduce heavy reliance on state, ease data movement between game modules, and to reduce cleanup code - events, scheduled tasks and coroutines are all cancelled when you leave or cancel an eventScope.

Usage

Event Scope's

All chapters of a game (such as a countdown, active game, between rounds, end game etc.) should be scoped using an eventScope {}.

Within the event scope, you can use listen<Event> {} and listenOnly<Event> {} to listen to Bukkit events within the scope.

By calling eventScope {} within an eventScope, you create a child eventScope forming a hierarchical relationship. Child eventScopes are bound to the parent, therefore if the parent eventScope is cancelled, the child eventScope will be cancelled too.

Event Scope Behaviour / Cancelling Event Scopes

When an eventScope is cancelled, any child eventScopes running will also be cancelled. For all cancelled eventScopes, listeners will be deregistered, scheduled Bukkit tasks will be cancelled, and coroutines will be stopped immediately.

To cancel an eventScope, call cancelScope() from within itself.

Bukkit Schedulers

Within an event scope, you can use launchTask(delay) { task -> ... } and launchRepeating(delay, interval) { task -> ... } which wrap Bukkit scheduler functions for launching a task later, and a repeating task respectively.

The Bukkit task object is passed in as the argument task, which allows you to cancel the task from within itself, especially useful in a repeating task if you hit a certain condition (such as run x times).

Once the eventScope is exited or cancelled, all Bukkit tasks created within the eventScope and child eventScopes are cancelled.

Launching coroutines

Although wrappers are provided for Bukkit schedulers, you may still decide to launch coroutines to run asynchronous code.

launchInScope {} provides the same functionality as Kotlin's launch {}, but will cancel the created coroutine if the parent eventScope is cancelled.

Examples

For a full example game, check out src/main/kotlin/dev/mqlvin/papergames/impl/quake/Quake.kt.

In 150 lines of logic, this demonstrates a polished Quake game involving:

  • The main Game function
  • eventScopes and child eventScopes
  • Event listeners, and common listeners such as listenAll(NoBuild, NoPvp)
  • A pregame countdown
  • Win logic for first to 10 kills or 120s elapsed (+ countdown) or players disconnect leaving 1 alive
  • Async animations using Bukkit tasks (railgun reload, invincibility)

Releases

Contributors

Languages