Skip to content

Modern Pawn

Southclaws edited this page Mar 29, 2018 · 10 revisions

This document is a brief overview of good practices to keep in mind while writing Pawn.

Pawn the language evolved in the SA:MP community, and the introduction of Packages, dependency management and instant running of code with sampctl has made some interesting patterns possible.

Because of how Pawn Packages have changed the way I personally write and think about Pawn code, I'm referring to the style defined here as "Modern Pawn".

For examples of Pawn packages following good practice, please see this list.

Batteries #included!

When writing a library, always assume the user has no other packages installed. This forces you to #include everything you need into your library. And yes, even a_samp.

This means that:

  1. People reading your code can quickly see what includes you're using. If you include something and it's not in your Package definition file, or vice versa, you know something is wrong with your dependencies.

  2. Your library compiles on its own. This is important for the next section, your library should be able to compile alone purely for testing purposes. This means it should have all the necessary #include lines inside it.

Entry Scripts

This is why having an entry defined is so important, even if it contains no runnable code it serves as proof that your code at least compiles. You should be writing tests into your package entry script though, for more information on that, read the Testing Pawn Code page.

Use sampctl package init to automatically generate an entry point or define one yourself, check out the Package documentation for details. A bare-bones entry script can look like this:

#include "my-library.inc"

main() {}

However, be aware of the effects not using functions - if a function is never called, it's never compiled. This means functions can contain errors and you might not catch them. So if you just want to ensure that, simply call each function at least once. (Example)

If you use y_testing, it now has support for a dummy function for this purpose. It's good to get started and catch errors early on but you really should be writing proper tests. Either unit tests or in-game demo tests.

Runtime Modes

Runtime modes allow packages to specify how they should be run. You can either run a package as a server, so it runs forever (until you close it) or you can run only the main() or y_testing functions so you can quickly test code.

See the Runtime Modes page for more info.

Readme

Your readme is your library's primary source of documentation. If you want a template, check this or use sampctl package init to bootstrap a new package and generate a readme file.

In short, your readme should contain:

  • at least some description of what your library does
  • installation instructions - usually as simple as sampctl package install <username>/<project>
  • documentation for functions, or if the code has comments, direct users there
  • what sampctl package run does - run unit tests or prompt user to connect as a player

Public Repositories

Naming

It doesn't matter what you name your repositories, but if like me you have non-SA:MP related projects it's good to prefix your Pawn packages with pawn- or samp- and keep everything lowercase, hyphenated: samp-ini, samp-logger, samp-object-loader etc.

Regardless of the name, you should make the name match the #include <> path. So, if your project is called samp-coconut the include should be #include <coconut> (without the samp- prefix).

This means the user can easily make the connection between sampctl package install User/LIBRARY and #include <LIBRARY>.

Be sure to tag your repositories with pawn-package to indicate it's a valid Pawn Package.

Versioning

sampctl encourages the use of semantic versioning as it allows logical greater-than/less-than checks against version constraints in dependencies lists.

git tags are how you version code. You can make use of the GitHub releases feature to create tags easily through the web interface.

You can also easily release new versions of your libraries by using sampctl package release which will generate a list of version numbers you can choose from for the next release.

Private Repositories

Since the sampctl 1.6 branch, private repositories are supported via SSH. HTTP Basic Auth is currently not supported, if you desire this feature then please open an issue or seek an existing issue.

To add a private repository as a dependency, simply add the SSH URL as a dependency:

sampctl package install git@gitlab.com:Southclaws/pawn-private.git

This format also fully supports versioning suffixes such as :, @ and #.

Clone this wiki locally