Skip to content

Project Setup

Aurora Lahtela edited this page Mar 7, 2026 · 38 revisions

Plan Header

Project Set-Up

Page version: 5.7

  1. Install JDK for Java 25 (https://jdk.java.net/) so that you can compile the project. If you want to develop the React part of the project install newest node.js. (node.js is not required for building the project)

  2. Fork the Plan repository & Clone that repository to your workstation with git clone.
    Here is a Tutorial.

  3. Open /Plan/ project folder inside the repository you just downloaded in your favorite IDE.
    Most IDEs will sync the workspace and you can start working on the project.

If you're having issues join Discord or open an issue and I'll help you out.

Building and testing

To build a new plugin artifact to use on servers, use

./gradlew build

The artifact will be placed in /repo_root/Plan/builds/

To skip tests and only build new jar, use

./gradlew -x test build

To run CheckStyle checks run

./gradlew checkstyleMain checkstyleTest

Maven Local Dependencies
mavenLocal() is not included in the repositories of main build.gradle.
If you need locally installed dependencies, add it to the main build.gradle for test builds.

Testing

To run tests, use

./gradlew test
  • If you want to run MySQL tests, set up MySQL on localhost and set following environment variables: MYSQL_DB: Database name, MYSQL_USER: username, MYSQL_PASS: password, MYSQL_PORT: port of mysql server
  • If you want to run Selenium tests, set up Chromedriver and set CHROMEDRIVER environment variable as the absolute file path to the chromedriver executable (C:\chromedriver.exe for example).

Modules

The project is split into multiple modules. Shadowjar is utilized to keep Java 11 runtime compatibility even though higher Java versions are packaged in.

ModuleDescriptionJava Version
apiEasily available API that is distributed via a maven repositoryJava 8
extensionModule for registering built in extensions that use DataExtension APIJava 11
commonSystem related abstractions and main logic is in this package. Most work is done here.Java 11
bukkitBukkit/Spigot/Paper related classesJava 11
foliaFolia related classesJava 17
bungeeBungeeCord related classesJava 11
spongeSponge related classesJava 21
velocityVelocity related classesJava 21
pluginModule for shading all other modules into a single jarJava 11
fabricFabric related classes, independent jar from other platformsJava 21

Plan uses Dagger for dependency injection.

Your IDE may be complaining about DaggerPlanBukkitComponent or another Dagger###Component class not being available.
Make sure that /<module>/build/generated/ is included as a Generated Sources root.

Web Dev

React project used for frontend is in /repo_root/Plan/react/dashboard. Node 20 is used. You can set up the project with

yarn install

Install Plan on a game/proxy server and change package.json"proxy" property to match the address to the Plan webserver (so that backend requests go there). After that you can start React dev-server with

yarn start

Plan builds the React project with yarn via gradle-node-plugin during the build process and includes it in the jar automatically when you run ./gradlew build or ./gradlew shadowJar.

If you need new endpoints from Plan Webserver build a new jar, install it and restart the game/proxy server.

Swagger documentation is available at <plan address>/docs when everything is running

More

If you would like to know a bit more how the project is put together before diving in, you can check out Project Architecture

The following sections are documentation for different one-time set-up steps for the project, written down in case I need to do it again years after I forgot about it.

CI set-up

Some tests need additional resources to be run, such as MySQL test or Selenium tests. It is not expected for devs to set these up on their own machines, but they should run on the CI.

The resource information is set using environmental variables. Those can be found from https://github.com/plan-player-analytics/Plan/blob/master/Plan/common/src/test/java/utilities/CIProperties.java

Reposilite publish set-up

In order to publish artifacts to https://repo.playeranalytics.net use environment variable REPOSILITE_TOKEN.

Bintray publish set-up (Bintray has shut down)

In order to publish artifacts to Bintray, following environmental variables need to be set

build gradle config for bintray (At the time of writing this is in the API module)

bintray {
user =System.getenv('BINTRAY_USER')
key =System.getenv('BINTRAY_KEY')
pkg {
repo ='Plan-repository'
name ='Plan-API'
licenses = ['LGPL-v3.0']
vcsUrl ='https://github.com/plan-player-analytics/Plan'
issueTrackerUrl ='https://github.com/plan-player-analytics/Plan/issues'
version {
name ="$apiVersion"
desc ="Plan API version $apiVersion"
}
publications = ['BintrayPublication']
}
}
publishing {
publications {
BintrayPublication(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
mavenJava(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
}
}

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Project Setup · plan-player-analytics/Plan Wiki · GitHub
Skip to content

Project Setup

Aurora Lahtela edited this page Mar 7, 2026 · 38 revisions

Plan Header

Project Set-Up

Page version: 5.7

  1. Install JDK for Java 25 (https://jdk.java.net/) so that you can compile the project. If you want to develop the React part of the project install newest node.js. (node.js is not required for building the project)

  2. Fork the Plan repository & Clone that repository to your workstation with git clone.
    Here is a Tutorial.

  3. Open /Plan/ project folder inside the repository you just downloaded in your favorite IDE.
    Most IDEs will sync the workspace and you can start working on the project.

If you're having issues join Discord or open an issue and I'll help you out.

Building and testing

To build a new plugin artifact to use on servers, use

./gradlew build

The artifact will be placed in /repo_root/Plan/builds/

To skip tests and only build new jar, use

./gradlew -x test build

To run CheckStyle checks run

./gradlew checkstyleMain checkstyleTest

Maven Local Dependencies
mavenLocal() is not included in the repositories of main build.gradle.
If you need locally installed dependencies, add it to the main build.gradle for test builds.

Testing

To run tests, use

./gradlew test
  • If you want to run MySQL tests, set up MySQL on localhost and set following environment variables: MYSQL_DB: Database name, MYSQL_USER: username, MYSQL_PASS: password, MYSQL_PORT: port of mysql server
  • If you want to run Selenium tests, set up Chromedriver and set CHROMEDRIVER environment variable as the absolute file path to the chromedriver executable (C:\chromedriver.exe for example).

Modules

The project is split into multiple modules. Shadowjar is utilized to keep Java 11 runtime compatibility even though higher Java versions are packaged in.

ModuleDescriptionJava Version
apiEasily available API that is distributed via a maven repositoryJava 8
extensionModule for registering built in extensions that use DataExtension APIJava 11
commonSystem related abstractions and main logic is in this package. Most work is done here.Java 11
bukkitBukkit/Spigot/Paper related classesJava 11
foliaFolia related classesJava 17
bungeeBungeeCord related classesJava 11
spongeSponge related classesJava 21
velocityVelocity related classesJava 21
pluginModule for shading all other modules into a single jarJava 11
fabricFabric related classes, independent jar from other platformsJava 21

Plan uses Dagger for dependency injection.

Your IDE may be complaining about DaggerPlanBukkitComponent or another Dagger###Component class not being available.
Make sure that /<module>/build/generated/ is included as a Generated Sources root.

Web Dev

React project used for frontend is in /repo_root/Plan/react/dashboard. Node 20 is used. You can set up the project with

yarn install

Install Plan on a game/proxy server and change package.json"proxy" property to match the address to the Plan webserver (so that backend requests go there). After that you can start React dev-server with

yarn start

Plan builds the React project with yarn via gradle-node-plugin during the build process and includes it in the jar automatically when you run ./gradlew build or ./gradlew shadowJar.

If you need new endpoints from Plan Webserver build a new jar, install it and restart the game/proxy server.

Swagger documentation is available at <plan address>/docs when everything is running

More

If you would like to know a bit more how the project is put together before diving in, you can check out Project Architecture

The following sections are documentation for different one-time set-up steps for the project, written down in case I need to do it again years after I forgot about it.

CI set-up

Some tests need additional resources to be run, such as MySQL test or Selenium tests. It is not expected for devs to set these up on their own machines, but they should run on the CI.

The resource information is set using environmental variables. Those can be found from https://github.com/plan-player-analytics/Plan/blob/master/Plan/common/src/test/java/utilities/CIProperties.java

Reposilite publish set-up

In order to publish artifacts to https://repo.playeranalytics.net use environment variable REPOSILITE_TOKEN.

Bintray publish set-up (Bintray has shut down)

In order to publish artifacts to Bintray, following environmental variables need to be set

build gradle config for bintray (At the time of writing this is in the API module)

bintray {
user =System.getenv('BINTRAY_USER')
key =System.getenv('BINTRAY_KEY')
pkg {
repo ='Plan-repository'
name ='Plan-API'
licenses = ['LGPL-v3.0']
vcsUrl ='https://github.com/plan-player-analytics/Plan'
issueTrackerUrl ='https://github.com/plan-player-analytics/Plan/issues'
version {
name ="$apiVersion"
desc ="Plan API version $apiVersion"
}
publications = ['BintrayPublication']
}
}
publishing {
publications {
BintrayPublication(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
mavenJava(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
}
}

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Project Setup · plan-player-analytics/Plan Wiki · GitHub
Skip to content

Project Setup

Aurora Lahtela edited this page Mar 7, 2026 · 38 revisions

Plan Header

Project Set-Up

Page version: 5.7

  1. Install JDK for Java 25 (https://jdk.java.net/) so that you can compile the project. If you want to develop the React part of the project install newest node.js. (node.js is not required for building the project)

  2. Fork the Plan repository & Clone that repository to your workstation with git clone.
    Here is a Tutorial.

  3. Open /Plan/ project folder inside the repository you just downloaded in your favorite IDE.
    Most IDEs will sync the workspace and you can start working on the project.

If you're having issues join Discord or open an issue and I'll help you out.

Building and testing

To build a new plugin artifact to use on servers, use

./gradlew build

The artifact will be placed in /repo_root/Plan/builds/

To skip tests and only build new jar, use

./gradlew -x test build

To run CheckStyle checks run

./gradlew checkstyleMain checkstyleTest

Maven Local Dependencies
mavenLocal() is not included in the repositories of main build.gradle.
If you need locally installed dependencies, add it to the main build.gradle for test builds.

Testing

To run tests, use

./gradlew test
  • If you want to run MySQL tests, set up MySQL on localhost and set following environment variables: MYSQL_DB: Database name, MYSQL_USER: username, MYSQL_PASS: password, MYSQL_PORT: port of mysql server
  • If you want to run Selenium tests, set up Chromedriver and set CHROMEDRIVER environment variable as the absolute file path to the chromedriver executable (C:\chromedriver.exe for example).

Modules

The project is split into multiple modules. Shadowjar is utilized to keep Java 11 runtime compatibility even though higher Java versions are packaged in.

ModuleDescriptionJava Version
apiEasily available API that is distributed via a maven repositoryJava 8
extensionModule for registering built in extensions that use DataExtension APIJava 11
commonSystem related abstractions and main logic is in this package. Most work is done here.Java 11
bukkitBukkit/Spigot/Paper related classesJava 11
foliaFolia related classesJava 17
bungeeBungeeCord related classesJava 11
spongeSponge related classesJava 21
velocityVelocity related classesJava 21
pluginModule for shading all other modules into a single jarJava 11
fabricFabric related classes, independent jar from other platformsJava 21

Plan uses Dagger for dependency injection.

Your IDE may be complaining about DaggerPlanBukkitComponent or another Dagger###Component class not being available.
Make sure that /<module>/build/generated/ is included as a Generated Sources root.

Web Dev

React project used for frontend is in /repo_root/Plan/react/dashboard. Node 20 is used. You can set up the project with

yarn install

Install Plan on a game/proxy server and change package.json"proxy" property to match the address to the Plan webserver (so that backend requests go there). After that you can start React dev-server with

yarn start

Plan builds the React project with yarn via gradle-node-plugin during the build process and includes it in the jar automatically when you run ./gradlew build or ./gradlew shadowJar.

If you need new endpoints from Plan Webserver build a new jar, install it and restart the game/proxy server.

Swagger documentation is available at <plan address>/docs when everything is running

More

If you would like to know a bit more how the project is put together before diving in, you can check out Project Architecture

The following sections are documentation for different one-time set-up steps for the project, written down in case I need to do it again years after I forgot about it.

CI set-up

Some tests need additional resources to be run, such as MySQL test or Selenium tests. It is not expected for devs to set these up on their own machines, but they should run on the CI.

The resource information is set using environmental variables. Those can be found from https://github.com/plan-player-analytics/Plan/blob/master/Plan/common/src/test/java/utilities/CIProperties.java

Reposilite publish set-up

In order to publish artifacts to https://repo.playeranalytics.net use environment variable REPOSILITE_TOKEN.

Bintray publish set-up (Bintray has shut down)

In order to publish artifacts to Bintray, following environmental variables need to be set

build gradle config for bintray (At the time of writing this is in the API module)

bintray {
user =System.getenv('BINTRAY_USER')
key =System.getenv('BINTRAY_KEY')
pkg {
repo ='Plan-repository'
name ='Plan-API'
licenses = ['LGPL-v3.0']
vcsUrl ='https://github.com/plan-player-analytics/Plan'
issueTrackerUrl ='https://github.com/plan-player-analytics/Plan/issues'
version {
name ="$apiVersion"
desc ="Plan API version $apiVersion"
}
publications = ['BintrayPublication']
}
}
publishing {
publications {
BintrayPublication(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
mavenJava(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
}
}

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Project Setup · plan-player-analytics/Plan Wiki · GitHub
Skip to content

Project Setup

Aurora Lahtela edited this page Mar 7, 2026 · 38 revisions

Plan Header

Project Set-Up

Page version: 5.7

  1. Install JDK for Java 25 (https://jdk.java.net/) so that you can compile the project. If you want to develop the React part of the project install newest node.js. (node.js is not required for building the project)

  2. Fork the Plan repository & Clone that repository to your workstation with git clone.
    Here is a Tutorial.

  3. Open /Plan/ project folder inside the repository you just downloaded in your favorite IDE.
    Most IDEs will sync the workspace and you can start working on the project.

If you're having issues join Discord or open an issue and I'll help you out.

Building and testing

To build a new plugin artifact to use on servers, use

./gradlew build

The artifact will be placed in /repo_root/Plan/builds/

To skip tests and only build new jar, use

./gradlew -x test build

To run CheckStyle checks run

./gradlew checkstyleMain checkstyleTest

Maven Local Dependencies
mavenLocal() is not included in the repositories of main build.gradle.
If you need locally installed dependencies, add it to the main build.gradle for test builds.

Testing

To run tests, use

./gradlew test
  • If you want to run MySQL tests, set up MySQL on localhost and set following environment variables: MYSQL_DB: Database name, MYSQL_USER: username, MYSQL_PASS: password, MYSQL_PORT: port of mysql server
  • If you want to run Selenium tests, set up Chromedriver and set CHROMEDRIVER environment variable as the absolute file path to the chromedriver executable (C:\chromedriver.exe for example).

Modules

The project is split into multiple modules. Shadowjar is utilized to keep Java 11 runtime compatibility even though higher Java versions are packaged in.

ModuleDescriptionJava Version
apiEasily available API that is distributed via a maven repositoryJava 8
extensionModule for registering built in extensions that use DataExtension APIJava 11
commonSystem related abstractions and main logic is in this package. Most work is done here.Java 11
bukkitBukkit/Spigot/Paper related classesJava 11
foliaFolia related classesJava 17
bungeeBungeeCord related classesJava 11
spongeSponge related classesJava 21
velocityVelocity related classesJava 21
pluginModule for shading all other modules into a single jarJava 11
fabricFabric related classes, independent jar from other platformsJava 21

Plan uses Dagger for dependency injection.

Your IDE may be complaining about DaggerPlanBukkitComponent or another Dagger###Component class not being available.
Make sure that /<module>/build/generated/ is included as a Generated Sources root.

Web Dev

React project used for frontend is in /repo_root/Plan/react/dashboard. Node 20 is used. You can set up the project with

yarn install

Install Plan on a game/proxy server and change package.json"proxy" property to match the address to the Plan webserver (so that backend requests go there). After that you can start React dev-server with

yarn start

Plan builds the React project with yarn via gradle-node-plugin during the build process and includes it in the jar automatically when you run ./gradlew build or ./gradlew shadowJar.

If you need new endpoints from Plan Webserver build a new jar, install it and restart the game/proxy server.

Swagger documentation is available at <plan address>/docs when everything is running

More

If you would like to know a bit more how the project is put together before diving in, you can check out Project Architecture

The following sections are documentation for different one-time set-up steps for the project, written down in case I need to do it again years after I forgot about it.

CI set-up

Some tests need additional resources to be run, such as MySQL test or Selenium tests. It is not expected for devs to set these up on their own machines, but they should run on the CI.

The resource information is set using environmental variables. Those can be found from https://github.com/plan-player-analytics/Plan/blob/master/Plan/common/src/test/java/utilities/CIProperties.java

Reposilite publish set-up

In order to publish artifacts to https://repo.playeranalytics.net use environment variable REPOSILITE_TOKEN.

Bintray publish set-up (Bintray has shut down)

In order to publish artifacts to Bintray, following environmental variables need to be set

build gradle config for bintray (At the time of writing this is in the API module)

bintray {
user =System.getenv('BINTRAY_USER')
key =System.getenv('BINTRAY_KEY')
pkg {
repo ='Plan-repository'
name ='Plan-API'
licenses = ['LGPL-v3.0']
vcsUrl ='https://github.com/plan-player-analytics/Plan'
issueTrackerUrl ='https://github.com/plan-player-analytics/Plan/issues'
version {
name ="$apiVersion"
desc ="Plan API version $apiVersion"
}
publications = ['BintrayPublication']
}
}
publishing {
publications {
BintrayPublication(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
mavenJava(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
}
}

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Project Setup · plan-player-analytics/Plan Wiki · GitHub
Skip to content

Project Setup

Aurora Lahtela edited this page Mar 7, 2026 · 38 revisions

Plan Header

Project Set-Up

Page version: 5.7

  1. Install JDK for Java 25 (https://jdk.java.net/) so that you can compile the project. If you want to develop the React part of the project install newest node.js. (node.js is not required for building the project)

  2. Fork the Plan repository & Clone that repository to your workstation with git clone.
    Here is a Tutorial.

  3. Open /Plan/ project folder inside the repository you just downloaded in your favorite IDE.
    Most IDEs will sync the workspace and you can start working on the project.

If you're having issues join Discord or open an issue and I'll help you out.

Building and testing

To build a new plugin artifact to use on servers, use

./gradlew build

The artifact will be placed in /repo_root/Plan/builds/

To skip tests and only build new jar, use

./gradlew -x test build

To run CheckStyle checks run

./gradlew checkstyleMain checkstyleTest

Maven Local Dependencies
mavenLocal() is not included in the repositories of main build.gradle.
If you need locally installed dependencies, add it to the main build.gradle for test builds.

Testing

To run tests, use

./gradlew test
  • If you want to run MySQL tests, set up MySQL on localhost and set following environment variables: MYSQL_DB: Database name, MYSQL_USER: username, MYSQL_PASS: password, MYSQL_PORT: port of mysql server
  • If you want to run Selenium tests, set up Chromedriver and set CHROMEDRIVER environment variable as the absolute file path to the chromedriver executable (C:\chromedriver.exe for example).

Modules

The project is split into multiple modules. Shadowjar is utilized to keep Java 11 runtime compatibility even though higher Java versions are packaged in.

ModuleDescriptionJava Version
apiEasily available API that is distributed via a maven repositoryJava 8
extensionModule for registering built in extensions that use DataExtension APIJava 11
commonSystem related abstractions and main logic is in this package. Most work is done here.Java 11
bukkitBukkit/Spigot/Paper related classesJava 11
foliaFolia related classesJava 17
bungeeBungeeCord related classesJava 11
spongeSponge related classesJava 21
velocityVelocity related classesJava 21
pluginModule for shading all other modules into a single jarJava 11
fabricFabric related classes, independent jar from other platformsJava 21

Plan uses Dagger for dependency injection.

Your IDE may be complaining about DaggerPlanBukkitComponent or another Dagger###Component class not being available.
Make sure that /<module>/build/generated/ is included as a Generated Sources root.

Web Dev

React project used for frontend is in /repo_root/Plan/react/dashboard. Node 20 is used. You can set up the project with

yarn install

Install Plan on a game/proxy server and change package.json"proxy" property to match the address to the Plan webserver (so that backend requests go there). After that you can start React dev-server with

yarn start

Plan builds the React project with yarn via gradle-node-plugin during the build process and includes it in the jar automatically when you run ./gradlew build or ./gradlew shadowJar.

If you need new endpoints from Plan Webserver build a new jar, install it and restart the game/proxy server.

Swagger documentation is available at <plan address>/docs when everything is running

More

If you would like to know a bit more how the project is put together before diving in, you can check out Project Architecture

The following sections are documentation for different one-time set-up steps for the project, written down in case I need to do it again years after I forgot about it.

CI set-up

Some tests need additional resources to be run, such as MySQL test or Selenium tests. It is not expected for devs to set these up on their own machines, but they should run on the CI.

The resource information is set using environmental variables. Those can be found from https://github.com/plan-player-analytics/Plan/blob/master/Plan/common/src/test/java/utilities/CIProperties.java

Reposilite publish set-up

In order to publish artifacts to https://repo.playeranalytics.net use environment variable REPOSILITE_TOKEN.

Bintray publish set-up (Bintray has shut down)

In order to publish artifacts to Bintray, following environmental variables need to be set

build gradle config for bintray (At the time of writing this is in the API module)

bintray {
user =System.getenv('BINTRAY_USER')
key =System.getenv('BINTRAY_KEY')
pkg {
repo ='Plan-repository'
name ='Plan-API'
licenses = ['LGPL-v3.0']
vcsUrl ='https://github.com/plan-player-analytics/Plan'
issueTrackerUrl ='https://github.com/plan-player-analytics/Plan/issues'
version {
name ="$apiVersion"
desc ="Plan API version $apiVersion"
}
publications = ['BintrayPublication']
}
}
publishing {
publications {
BintrayPublication(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
mavenJava(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
}
}

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Project Setup · plan-player-analytics/Plan Wiki · GitHub
Skip to content

Project Setup

Aurora Lahtela edited this page Mar 7, 2026 · 38 revisions

Plan Header

Project Set-Up

Page version: 5.7

  1. Install JDK for Java 25 (https://jdk.java.net/) so that you can compile the project. If you want to develop the React part of the project install newest node.js. (node.js is not required for building the project)

  2. Fork the Plan repository & Clone that repository to your workstation with git clone.
    Here is a Tutorial.

  3. Open /Plan/ project folder inside the repository you just downloaded in your favorite IDE.
    Most IDEs will sync the workspace and you can start working on the project.

If you're having issues join Discord or open an issue and I'll help you out.

Building and testing

To build a new plugin artifact to use on servers, use

./gradlew build

The artifact will be placed in /repo_root/Plan/builds/

To skip tests and only build new jar, use

./gradlew -x test build

To run CheckStyle checks run

./gradlew checkstyleMain checkstyleTest

Maven Local Dependencies
mavenLocal() is not included in the repositories of main build.gradle.
If you need locally installed dependencies, add it to the main build.gradle for test builds.

Testing

To run tests, use

./gradlew test
  • If you want to run MySQL tests, set up MySQL on localhost and set following environment variables: MYSQL_DB: Database name, MYSQL_USER: username, MYSQL_PASS: password, MYSQL_PORT: port of mysql server
  • If you want to run Selenium tests, set up Chromedriver and set CHROMEDRIVER environment variable as the absolute file path to the chromedriver executable (C:\chromedriver.exe for example).

Modules

The project is split into multiple modules. Shadowjar is utilized to keep Java 11 runtime compatibility even though higher Java versions are packaged in.

ModuleDescriptionJava Version
apiEasily available API that is distributed via a maven repositoryJava 8
extensionModule for registering built in extensions that use DataExtension APIJava 11
commonSystem related abstractions and main logic is in this package. Most work is done here.Java 11
bukkitBukkit/Spigot/Paper related classesJava 11
foliaFolia related classesJava 17
bungeeBungeeCord related classesJava 11
spongeSponge related classesJava 21
velocityVelocity related classesJava 21
pluginModule for shading all other modules into a single jarJava 11
fabricFabric related classes, independent jar from other platformsJava 21

Plan uses Dagger for dependency injection.

Your IDE may be complaining about DaggerPlanBukkitComponent or another Dagger###Component class not being available.
Make sure that /<module>/build/generated/ is included as a Generated Sources root.

Web Dev

React project used for frontend is in /repo_root/Plan/react/dashboard. Node 20 is used. You can set up the project with

yarn install

Install Plan on a game/proxy server and change package.json"proxy" property to match the address to the Plan webserver (so that backend requests go there). After that you can start React dev-server with

yarn start

Plan builds the React project with yarn via gradle-node-plugin during the build process and includes it in the jar automatically when you run ./gradlew build or ./gradlew shadowJar.

If you need new endpoints from Plan Webserver build a new jar, install it and restart the game/proxy server.

Swagger documentation is available at <plan address>/docs when everything is running

More

If you would like to know a bit more how the project is put together before diving in, you can check out Project Architecture

The following sections are documentation for different one-time set-up steps for the project, written down in case I need to do it again years after I forgot about it.

CI set-up

Some tests need additional resources to be run, such as MySQL test or Selenium tests. It is not expected for devs to set these up on their own machines, but they should run on the CI.

The resource information is set using environmental variables. Those can be found from https://github.com/plan-player-analytics/Plan/blob/master/Plan/common/src/test/java/utilities/CIProperties.java

Reposilite publish set-up

In order to publish artifacts to https://repo.playeranalytics.net use environment variable REPOSILITE_TOKEN.

Bintray publish set-up (Bintray has shut down)

In order to publish artifacts to Bintray, following environmental variables need to be set

build gradle config for bintray (At the time of writing this is in the API module)

bintray {
user =System.getenv('BINTRAY_USER')
key =System.getenv('BINTRAY_KEY')
pkg {
repo ='Plan-repository'
name ='Plan-API'
licenses = ['LGPL-v3.0']
vcsUrl ='https://github.com/plan-player-analytics/Plan'
issueTrackerUrl ='https://github.com/plan-player-analytics/Plan/issues'
version {
name ="$apiVersion"
desc ="Plan API version $apiVersion"
}
publications = ['BintrayPublication']
}
}
publishing {
publications {
BintrayPublication(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
mavenJava(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
}
}

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Project Setup · plan-player-analytics/Plan Wiki · GitHub
Skip to content

Project Setup

Aurora Lahtela edited this page Mar 7, 2026 · 38 revisions

Plan Header

Project Set-Up

Page version: 5.7

  1. Install JDK for Java 25 (https://jdk.java.net/) so that you can compile the project. If you want to develop the React part of the project install newest node.js. (node.js is not required for building the project)

  2. Fork the Plan repository & Clone that repository to your workstation with git clone.
    Here is a Tutorial.

  3. Open /Plan/ project folder inside the repository you just downloaded in your favorite IDE.
    Most IDEs will sync the workspace and you can start working on the project.

If you're having issues join Discord or open an issue and I'll help you out.

Building and testing

To build a new plugin artifact to use on servers, use

./gradlew build

The artifact will be placed in /repo_root/Plan/builds/

To skip tests and only build new jar, use

./gradlew -x test build

To run CheckStyle checks run

./gradlew checkstyleMain checkstyleTest

Maven Local Dependencies
mavenLocal() is not included in the repositories of main build.gradle.
If you need locally installed dependencies, add it to the main build.gradle for test builds.

Testing

To run tests, use

./gradlew test
  • If you want to run MySQL tests, set up MySQL on localhost and set following environment variables: MYSQL_DB: Database name, MYSQL_USER: username, MYSQL_PASS: password, MYSQL_PORT: port of mysql server
  • If you want to run Selenium tests, set up Chromedriver and set CHROMEDRIVER environment variable as the absolute file path to the chromedriver executable (C:\chromedriver.exe for example).

Modules

The project is split into multiple modules. Shadowjar is utilized to keep Java 11 runtime compatibility even though higher Java versions are packaged in.

ModuleDescriptionJava Version
apiEasily available API that is distributed via a maven repositoryJava 8
extensionModule for registering built in extensions that use DataExtension APIJava 11
commonSystem related abstractions and main logic is in this package. Most work is done here.Java 11
bukkitBukkit/Spigot/Paper related classesJava 11
foliaFolia related classesJava 17
bungeeBungeeCord related classesJava 11
spongeSponge related classesJava 21
velocityVelocity related classesJava 21
pluginModule for shading all other modules into a single jarJava 11
fabricFabric related classes, independent jar from other platformsJava 21

Plan uses Dagger for dependency injection.

Your IDE may be complaining about DaggerPlanBukkitComponent or another Dagger###Component class not being available.
Make sure that /<module>/build/generated/ is included as a Generated Sources root.

Web Dev

React project used for frontend is in /repo_root/Plan/react/dashboard. Node 20 is used. You can set up the project with

yarn install

Install Plan on a game/proxy server and change package.json"proxy" property to match the address to the Plan webserver (so that backend requests go there). After that you can start React dev-server with

yarn start

Plan builds the React project with yarn via gradle-node-plugin during the build process and includes it in the jar automatically when you run ./gradlew build or ./gradlew shadowJar.

If you need new endpoints from Plan Webserver build a new jar, install it and restart the game/proxy server.

Swagger documentation is available at <plan address>/docs when everything is running

More

If you would like to know a bit more how the project is put together before diving in, you can check out Project Architecture

The following sections are documentation for different one-time set-up steps for the project, written down in case I need to do it again years after I forgot about it.

CI set-up

Some tests need additional resources to be run, such as MySQL test or Selenium tests. It is not expected for devs to set these up on their own machines, but they should run on the CI.

The resource information is set using environmental variables. Those can be found from https://github.com/plan-player-analytics/Plan/blob/master/Plan/common/src/test/java/utilities/CIProperties.java

Reposilite publish set-up

In order to publish artifacts to https://repo.playeranalytics.net use environment variable REPOSILITE_TOKEN.

Bintray publish set-up (Bintray has shut down)

In order to publish artifacts to Bintray, following environmental variables need to be set

build gradle config for bintray (At the time of writing this is in the API module)

bintray {
user =System.getenv('BINTRAY_USER')
key =System.getenv('BINTRAY_KEY')
pkg {
repo ='Plan-repository'
name ='Plan-API'
licenses = ['LGPL-v3.0']
vcsUrl ='https://github.com/plan-player-analytics/Plan'
issueTrackerUrl ='https://github.com/plan-player-analytics/Plan/issues'
version {
name ="$apiVersion"
desc ="Plan API version $apiVersion"
}
publications = ['BintrayPublication']
}
}
publishing {
publications {
BintrayPublication(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
mavenJava(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
}
}

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Project Setup · plan-player-analytics/Plan Wiki · GitHub
Skip to content

Project Setup

Aurora Lahtela edited this page Mar 7, 2026 · 38 revisions

Plan Header

Project Set-Up

Page version: 5.7

  1. Install JDK for Java 25 (https://jdk.java.net/) so that you can compile the project. If you want to develop the React part of the project install newest node.js. (node.js is not required for building the project)

  2. Fork the Plan repository & Clone that repository to your workstation with git clone.
    Here is a Tutorial.

  3. Open /Plan/ project folder inside the repository you just downloaded in your favorite IDE.
    Most IDEs will sync the workspace and you can start working on the project.

If you're having issues join Discord or open an issue and I'll help you out.

Building and testing

To build a new plugin artifact to use on servers, use

./gradlew build

The artifact will be placed in /repo_root/Plan/builds/

To skip tests and only build new jar, use

./gradlew -x test build

To run CheckStyle checks run

./gradlew checkstyleMain checkstyleTest

Maven Local Dependencies
mavenLocal() is not included in the repositories of main build.gradle.
If you need locally installed dependencies, add it to the main build.gradle for test builds.

Testing

To run tests, use

./gradlew test
  • If you want to run MySQL tests, set up MySQL on localhost and set following environment variables: MYSQL_DB: Database name, MYSQL_USER: username, MYSQL_PASS: password, MYSQL_PORT: port of mysql server
  • If you want to run Selenium tests, set up Chromedriver and set CHROMEDRIVER environment variable as the absolute file path to the chromedriver executable (C:\chromedriver.exe for example).

Modules

The project is split into multiple modules. Shadowjar is utilized to keep Java 11 runtime compatibility even though higher Java versions are packaged in.

ModuleDescriptionJava Version
apiEasily available API that is distributed via a maven repositoryJava 8
extensionModule for registering built in extensions that use DataExtension APIJava 11
commonSystem related abstractions and main logic is in this package. Most work is done here.Java 11
bukkitBukkit/Spigot/Paper related classesJava 11
foliaFolia related classesJava 17
bungeeBungeeCord related classesJava 11
spongeSponge related classesJava 21
velocityVelocity related classesJava 21
pluginModule for shading all other modules into a single jarJava 11
fabricFabric related classes, independent jar from other platformsJava 21

Plan uses Dagger for dependency injection.

Your IDE may be complaining about DaggerPlanBukkitComponent or another Dagger###Component class not being available.
Make sure that /<module>/build/generated/ is included as a Generated Sources root.

Web Dev

React project used for frontend is in /repo_root/Plan/react/dashboard. Node 20 is used. You can set up the project with

yarn install

Install Plan on a game/proxy server and change package.json"proxy" property to match the address to the Plan webserver (so that backend requests go there). After that you can start React dev-server with

yarn start

Plan builds the React project with yarn via gradle-node-plugin during the build process and includes it in the jar automatically when you run ./gradlew build or ./gradlew shadowJar.

If you need new endpoints from Plan Webserver build a new jar, install it and restart the game/proxy server.

Swagger documentation is available at <plan address>/docs when everything is running

More

If you would like to know a bit more how the project is put together before diving in, you can check out Project Architecture

The following sections are documentation for different one-time set-up steps for the project, written down in case I need to do it again years after I forgot about it.

CI set-up

Some tests need additional resources to be run, such as MySQL test or Selenium tests. It is not expected for devs to set these up on their own machines, but they should run on the CI.

The resource information is set using environmental variables. Those can be found from https://github.com/plan-player-analytics/Plan/blob/master/Plan/common/src/test/java/utilities/CIProperties.java

Reposilite publish set-up

In order to publish artifacts to https://repo.playeranalytics.net use environment variable REPOSILITE_TOKEN.

Bintray publish set-up (Bintray has shut down)

In order to publish artifacts to Bintray, following environmental variables need to be set

build gradle config for bintray (At the time of writing this is in the API module)

bintray {
user =System.getenv('BINTRAY_USER')
key =System.getenv('BINTRAY_KEY')
pkg {
repo ='Plan-repository'
name ='Plan-API'
licenses = ['LGPL-v3.0']
vcsUrl ='https://github.com/plan-player-analytics/Plan'
issueTrackerUrl ='https://github.com/plan-player-analytics/Plan/issues'
version {
name ="$apiVersion"
desc ="Plan API version $apiVersion"
}
publications = ['BintrayPublication']
}
}
publishing {
publications {
BintrayPublication(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
mavenJava(MavenPublication) {
groupId ='com.djrapitops'
artifactId ='Plan-api'
version ="$apiVersion"
artifact jar
}
}
}

Clone this wiki locally