Skip to content

Beginning

Brov3r edited this page Aug 18, 2024 · 7 revisions

Getting started with modifications

General concepts

Avrix is a loader of user files (modifications) packaged in a jar archive. Here and in the future, the concept of plugin will be used to define these modifications. The loader architecture is designed in such a way that one plugin can contain several entry points for one of the sides of the environment (client or server), in other words, one plugin for either the server or the client.

You should keep in mind that each plugin is loaded "in isolation", but all classes are contained in the same repository, which allows you to call classes of one plugin from another through services.

Creating a Project

Create build.gradle

You can start from scratch or based on example plugin. Here we will only describe creating a project from scratch.

To do this, you need to create a new Java project in your IDE. Important, it must be based on JDK 17, you can download it here, since Project Zomboid is written specifically on this version and otherwise your plugin simply will not run. We recommend using Gradle as a builder, for example version 8.5.

Create a build.gradle file and fill it with the following:

/**
 * Gradle plugins
 */
plugins {
    id 'com.github.johnrengelman.shadow' version '8.1.1'
    id 'java'
}

group = 'com.example.plugin'
version = '1.0'

/**
 * Path to the compiled Jar file
 */
def buildPath = System.getenv('BUILD_PATH') ?: 'build';

/**
 * Repositories for project dependencies
 */
repositories {
    mavenCentral()
}

/**
 * Replacing data with current ones
 */
processResources {
    filesMatching('**/metadata.yml') {
        filter {
            it.replace('%PROJECT_VERSION%', version)
        }
    }
}

/**
 * Project Dependencies
 */
dependencies {
    /**
     * Project Zomboid
     * You can download these dependencies on the Avrix releases page (https://github.com/Brov3r/Avrix/releases)
     */
    compileOnly files('./libs/ProjectZomboid-core-41.78.16.jar')
    compileOnly files('./libs/ProjectZomboid-libs-41.78.16.jar')

    /**
     * Utils
     * Javassist is used for patching 
     */
    compileOnly('org.javassist:javassist:3.30.2-GA')

    /**
     * Avrix Loader
     * You can download these dependencies on the Avrix releases page (https://github.com/Brov3r/Avrix/releases)
     */
    compileOnly files('./libs/Avrix-Core-1.3.0.jar')
}

/**
 * Creating a Jar file
 */
shadowJar {
    archiveFileName.set("${rootProject.name}-${version}.jar")
    destinationDirectory.set(file(buildPath))

    manifest {
        attributes(
                'Implementation-Title': rootProject.name,
                'Implementation-Version': version,
        )
    }
}

In the project dependencies, you must specify the current version of Atrix, Project Zomboid and Javassist, always in the "compileOnly" format, since they are needed only for compilation, everything else will be found at runtime.

Create metadata.yml

In the resource root of the project, for example, src/main/java/resources/, create a file metadata.yml:

name: "Example plugin"
id: "example-plugin"
description: "Example plugin description."
author: "Brov3r"
version: "%PROJECT_VERSION%" # Do not change it, as it is inserted automatically when building the project
environment: "server" # or client, or both
license: "MIT"
contacts: "https://github.com/brov3r/"
patches:
  - "com.example.plugin.patches.PatchGameServer"
entrypoints:
  - "com.example.plugin.Main"
dependencies:
  pz-core: ">=41.78.16"
  avrix-loader: ">=1.3.0"

where:

name - plugin name.

description - plugin description.

id - unique plugin ID.

version - plugin version, dynamically installed by Gradle.

author - list of authors of the project.

license - project license.

environment - the environment for which the plugin is intended (client, server or both).

entrypoints - a list of entry points, there may be several. Each class must be extended from the Avrix Plugin class.

patches - a list of patches (they make changes to game files). Extends the ClassTransformer class from the Avrix package.

dependencies - list of project dependencies. Specifying pz-core and avrix-loader is mandatory. Possible conditions >=, <=, <, >, =.

Note

To get metadata from the plugin, you can call the getMetadata() method

Project structure

The project structure should look something like this:

PluginProject
└── libs
    └── Avrix-Core-x.x.x.jar
    └── ...
└── src
    └── main
        └── java
            └── ...
        └── resources
            └── metadata.yaml
            └── ...
    └── ...
└── build.gradle
└── settings.gradle
└── LICENSE
└── ...

After completing all the steps described above, you can start writing a plugin.

Entry points

Client and server entry points should always inherit from Plugin in the Avrix package. Approximate view of the entry point:

/**
 * Main entry point of the example plugin
 */
public class Main extends Plugin {
     /**
     * Constructs a new {@link Plugin} with the specified metadata.
     * Metadata is transferred when the plugin is loaded into the game context.
     *
     * @param metadata The {@link Metadata} associated with this plugin.
     */
    public Main(Metadata metadata) {
        super(metadata);
    }

    /**
     * Called when the plugin is initialized.
     * <p>
     * Implementing classes should override this method to provide the initialization logic.
     */
    @Override
    public void onInitialize() {}
}

Each entry point contains 1 methods by default: onInitialize.

onInitialize - always executed when the plugin is loaded by the game/server, executed once.