Skript Coding Conventions

Skript Coding Conventions

Why, hello there ! The idea of this thread suddenly popped in my mind, so I was like "why the fuck not", and there I am.
The aim of this thread is to suggest sane coding conventions for Skript.

NOTE : These conventions are absolutely not official, but you will probably get yelled at by people like @Snow-Pyon or @Pikachu by not respecting some of these.
These conventions are also my own, so some people like the aforementioned might get mad at me.

The conventions apply to various subjects ranging from naming to control flow structures.

WARNING : The conventions apply to the language features of bensku's latest versions, so some code structures might not even work on some old versions.

Without further bribery, let's get started.

A formal definition of hyphen-case:
Hyphen-case is used for a lot of naming in Skript, so it is important I give a formal definition of it. There doesn't seem to be a well-defined name for this case, so I'll call it hyphen-case.
Rules :

  • All words are separated by hyphens ("-")
  • All words are lowercase
  • Words that are joined words with different capitalizations (i.e "YouTube") should not be separated. "YouTube" would turn into "youtube".
  • If a number describes a word (as in a version of something, i.e "Permissions 2"), then join the number and the word it applies to together. The above example turns to "permissions2" in hyphen-case.
    However, if the version applies to two words or more (i.e "Advanced Chat 2"), then separate the words with hyphens. The second example would transform into "advanced-chat-2".

  • Some words are ambiguously hyphenated - most notably words starting with "non" - , like "non-empty", which can equally be written as "nonempty". In this case, use the non-hyphenated version ("nonempty"/"non-empty" always becomes "nonempty"). This rule does not apply for words that are unambiguously hyphenated

  • This follows the same rules as above, except that all words should be uppercase instead of lowercase

I) Naming
Naming conventions are always hot topics in any programming language, and Skript is no exception.
There is one convention that is so important I have to separate it from the rest :

  • All syntaxes (e.g all code outside of function calls, strings, variable names, comments and options) should be lowercase. This :
    If <condition>:
    # do stuff
    # do other stuff

    Is not acceptable.

Now for the rest of naming conventions :
  • Naming variables
    Undoubtedly the most important convention here.
    Set up a variable hierarchy to classify values, and separate each member with "::".
    "." is not acceptable.
    Each member of the hierarchy should be written in hyphen-case.
    Example #1:

    # We want the amount of experience a player has for the SkyBlock minigame (being one of multiple minigames)
    # Then name the variable as such
    {minigames::skyblock::%player's uuid%::experience}

    (Always use "player's uuid" for anything that persists over restarts)
    Example #2:
    # Say we want to get the chat prefix for a given group, handled by the script EzChat
    #One would name it as

    If you ever have to use a constant for one script only, prefer options to variables.
    However, if the constant is shared across multiple scripts or can be modified dynamically (e.g loading a value externally on loading), then use SCREAMING-HYPHEN-CASE.

    This hierarchy method applies to both local and global variables, except constants (as described above), which can do without any sort of hierarchy.

  • Naming functions
    Function names are written in camelCase (as Java methods)

  • Naming options
    Options should be named in PascalCase (same as camelCase, except the first letter is uppercase), like Java classes

  • Naming function parameters
    Function parameters are preferrably one word long, but in case you need multiple words, use hyphen-case.
  • Naming scripts
    Now, there are two different meanings to this :
    A. The name of the actual .sk file : use hyphen-case.
    B. The name of the scripts as in the resource name : do as you wish.

II) Control Flow :
Control flow structures are the base of how a script's structure looks. If they are not organized correctly, then code can quickly become hard to understand.
Here some rules to follow :

Conditions :

  • Always prefer "if -> else if -> else" to "if -> stop -> rest of code outside of the if"
  • In general, always try to avoid "stop"
  • Always include "if" before condition scopes
  • Never use inline conditions

Element ordering :
  • Place functions at the top of the file, preferrably grouped by purpose or sorted in alphabetical order. Since bensku's fork allows functions to be called before being declared, this is not mandatory anyway. Try to put them in the script where they are most used, and put utility functions (e.g "contains" function) in a separate script.
  • Now, for ordering regular events and commands, the you can choose between two options :
    1. Place events first, commands after
    2. Group commands and events by theme, following the first rule

  • I personally use tabs for indentation, and make sure to set tab width to "4 spaces" in my editor
    Now this is personal opinion, and I would say 2 or 4 spaces is also acceptable

Comments :
  • "#" symbols should be separated by two spaces :
    set {acceptable} to true # this is acceptable
    set {not-acceptable} to true #this is not acceptable
    set {do-not-do-dis} to true#Please do not do this

  • In-line comments should not make the reader have to scroll a lot across the line
  • Comments that separate different sections of the code should always take their own line
  • Comments should never be separated from a trigger, except for header comments. For example, command descriptions should be put right above the command declaration.
    These kind of comments should be made inline when possible.

III) Syntax-specific conventions :
These conventions only apply to specific syntaxes rather than general code constructs, so I have to make a dedicated section.

Using strings in any syntax :

  • Always use quotes, in case the value is null, then it will use "<none>" rather than outright failing.

skript-mirror custom syntaxes :
  • skript-mirror requires custom syntax to be placed before being called, so place any declaration at the top of the file, before functions. As for ordering these, there are two options :
    1. Place conditions first, effects second and expressions finally
    2. Group them by theme and follow the previous rule

  • Since custom syntaxes have to be loaded before being used, it is recommended to use a separate file that would load before any other (e.g "!!!.sk") in order to declare these

MundoSK switch/match scope :
  • A switch should always have a "true" case (== default in Java), except if all possibilities were covered by the cases, when the input can only be a defined set of values

skQuery lambdas :
  • Never use the "do" effect
  • Only use the "check" condition if there is no "else" clause to be put anywhere, and do not make a "check" condition with more than three conditions

Welp, I think I'm just about done with this. If you have any requests over what I should also include, make sure to comment on this thread !

Y O W Z A !