-
Notifications
You must be signed in to change notification settings - Fork 34
Package Definition Reference
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": "if your .inc files aren't in the repo root, specify the path here",
"resources": ["list of Resource objects (see below)"]
}
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:
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"
}
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.
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 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.
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.
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 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.