Skip to content

Package Definition Reference

Southclaws edited this page Dec 24, 2017 · 19 revisions

Pawn Packages are described with a JSON or YAML file with the following structure:

{
    "contributors": ["array of people who contributed to this package"],
    "website": "forum topic, github page or standalone website",
    "entry": "entry point script for build (see below)",
    "output": "output amx for build (see below)",
    "dependencies": ["list of Dependencies (see below)"],
    "builds": ["list of Build Configurations (see below)"],
    "runtime": {"runtime configuration (see below)"},
    "include_path": "subdirectory that contains includes (see below)",
    "resources": ["list of Resource objects (see below)"]
}

entry and output

Entry describes the .pwn file required to compile this package and output describes where the compiled .amx file should go once it has been built.

These fields are required and there are two use cases for compiling a package:

The package is a gamemode

In this case, you would usually have your Package Definition in the root of your server directory (next to samp.json/samp.yaml and the server binaries) then your entry would be gamemodes/MyGamemodeScript.pwn:

{
    "entry": "gamemodes/MyGameModeScript.pwn",
    "output": "gamemodes/MyGameModeScript.amx"
}

The package is a library

In this case, you don't compile the library directly so don't set the .inc as the entry. Instead, you would create a tests.pwn or similar and then include your library into that file for unit testing or in-game testing.

{
    "entry": "test.pwn",
    "output": "test.amx"
}

For more information on writing packages, see the Packages page.


dependencies

This is where you list all the other packages that your script needs to compile.

Important: Dependencies do not need a pawn.json/pawn.yaml file in their repository to classify as a "Pawn Package" - it just helps a lot when sampctl is figuring out all the dependencies of a package.

A "dependency" is a User/Repo string and describes a GitHub repository. The SA:MP community has widely adopted GitHub as the location for uploading and maintaining gamemodes, includes and filterscripts so that's why sampctl uses it for package management.

Here is an example of a dependencies field for a simple package: (the entry and output fields, though required, have been ignored in this example)

{
    "dependencies": [
        "Southclaws/samp-stdlib",
        "oscar-broman/md-sort",
    ]
}

This package depends on samp-stdlib maintained by Southclaws and the md-sort library maintained by oscar-broman.

samp-stdlib is a special library that almost all Packages will need to depend on. It's the "SA:MP Standard Library" and simply contains all the .inc files that ship with the server - this includes files like a_samp.inc etc. The repository is maintained by @Southclaws and will be updated for each SA:MP server release.

For more information on dependencies, please read the Dependencies page.

builds

Builds allows complete customisation of builds for packages. By default, when you run sampctl package build, sampctl will choose some default settings based on the standards that the SA:MP community have adopted. This includes:

  • Compiler version 3.10.4 by @Zeex
  • Arguments: -;+, -(+, -\+, -d3, -Z+

The builds field is an array of Build Configurations which have the following structure:

{
    "name": "the name of the build configuration",
    "version": "the compiler version to use - default is the latest release of Zeex/pawn",
    "workingDir": "the working directory - default is the same directory as the Package Definition file",
    "args": ["list of arguments such as -l, -a, -d3, etc"],
    "input": "input .pwn file - overrides the `entry` field of the Package Definition",
    "output": "output .amx file - overrides the `output` field of the Package Definition",
    "includes": ["list of additional include directories to be turned in to -i arguments"],
    "constants": {"list of constant definitions"}
}

The name field is used to identify the build config when using the --build flag in sampctl package build. If no --build is specified and a package defines multiple build configs, the first one is chosen.

If args is set, the default is completely ignored so if you just want to add arguments to the defaults, you must manually specify the defaults too.

includes is a list of directories not a list of files. Each item in this list translates directly to a -i flag being passed to the compiler. This is useful if you want to specify a custom dependency that is not available on GitHub but still include it via #include <file> instead of #include "file".

constants allows you to pass compile-time constants. These are the same as adding #define SOMETHING to the top of your script. For example, you could have two builds, one that defines MAX_PLAYERS as 1000 and one that defines it as 10 just for development purposes which would speed up build times.


runtime

This is a Runtime Configuration and is just an instance of a samp.json/samp.yaml structure. For reference, the Runtime Configuration Reference page.

This is when you want to pass custom runtime configuration for a sampctl package run. The main use-case for this is defining plugins so you can test libraries that depend on plugins.

If you're writing a gamemode, you probably don't need to use this and can just stick with using samp.json/samp.yaml for your runtime configuration. This is aimed at library developers to give them an easy way of testing with a plugin.

For example, if you wrote a library that had the Streamer plugin as a dependency, your Package Definition would look like this:

{
    "entry": "test.pwn",
    "output": "test.amx",
    "dependencies": [
        "Southclaws/samp-stdlib",
        "samp-incognito/samp-streamer-plugin:2.8.2"
    ],
    "runtime": {
        "plugins": [
            "samp-incognito/samp-streamer-plugin:2.8.2"
        ]
    }
}

Notice how the same dependency string can be used for the dependencies field (for the include file) and the plugins field for executing the code. And as long as plugin maintainers keep their GitHub tags and releases up to date, you can use the same version tag too.


Include Path

It's common with plugins to place the Pawn .inc file into a subdirectory. If this is the case with your library, you must specify the additional path here.

For example, urShadow/Pawn.RakNet has the include file in src/ so the package definition must contain this:

{
    "include_path": "src"
}

Resources

Resources is a special field for plugin maintainers only. This allows a plugin developer to declare that their library also contains some additional files necessary for running the built .amx that uses their .inc file.

This has the following structure:

{
    "name": "a regular expression to match the filename of a GitHub release",
    "platform": "either windows or linux",
    "archive": "a boolean indicating whether or not the file is an archive or just the binary itself",
    "includes": ["list of paths to directories that contain .inc files (only if the resource is an archive)"],
    "plugins": ["list of plugin binaries - either .so or .dll (only if the resource is an archive)"],
    "files": {"any additional files (only if the resource is an archive)"}
}

The name is important, it must be a valid regular expression and it must match at least one filename from GitHub releases. This is used to find the correct file to download for the given platform. Some plugins (such as the streamer) release all their binaries in a single .zip so it's fine if two resource fields point to the same file. Please see the Streamer Plugin Package Definition for an example.

platform is simply the platform that this resource is for. Most plugins should have exactly two resource objects, one for linux and one for windows.

archive if false means that the resource just points to a raw .so or .dll file and it can simply be automatically downloaded to the plugins directory without any hassle. If it's true, the next few fields are necessary to tell sampctl where in the archive the plugin files and any other important things exist.

includes is not actually used by sampctl server * commands but actually by sampctl package ensure - it's used for plugins that release their .inc files inside the release archives instead of on the repository itself. If your .inc file is simply kept in the repository, this field is not necessary.

plugins is a list of files inside the archive that are plugin files. Most plugins should only list one file, and depending on the platform this file should be an .so for linux and a .dll for windows.

files is any other necessary files. This is rarely ever needed. An example of this is the MySQL plugin, it requires the log-core dynamic library in order to run. The structure of this field is simply a string-to-string map where the left side are paths inside the archive and the right side are paths outside relative to the server root:

{
    "files": {
        "log-core.so": "log-core.so"
    }
}

Here, the log-core.so file is simply kept in the root of the archive, and it's target location is the root of the server runtime directory.

Clone this wiki locally