plugin.yml for reference, written by me: - Pastebin - Pastebin (https) (warning, if not logged into your premium Pastebin account, this will direct you to non-https). The Importance of Headers You'll notice that I wrote "headers", or "labels", in that plugin.yml using the '#' (shift+3) character. Many people, including myself, consider including these headers to be good practice. It makes things easier to find for both yourself, and an external author who may need to modify your file. I used an ASCII Generator (warning: non-https), and the fonts "banner3" (POLLER) and "banner" (Commands, Permissions). While capitalization doesn't really matter for this, it's always nice to have the initial header in a larger font + all caps. The other minor sections should be CamelCase: - Wikipedia - Wikipedia (https) Naming Your Plugin One thing that you used to see pretty often was the usage of spaces in plugin names; to my knowledge, this is now automatically corrected by your Bukkit/Spigot jar, but it's still not a good idea to include spacing. Again, you should use CamelCase! Make sure the plugin name you select pertains to the plugin; the 'best practice' for this is to name it after your main classfile (in this case, Poller). The name is a required field. Version Definition According to the Bukkit wiki, the best version-format is "MajorRelease.MinorRelease.Build", but in my example, I choose something a little different. Personally I prefer "MajorRelease.Build", omitting the "MinorRelease" option. It's always best to use the standard, unless you've got an explicit reason not to (which I do). This field is required. Main Not much to say here, other than not to capitalize your package declaration, as is a Java-best-practice. This should be the path to your main plugin class, which extends JavaPlugin. This field is required. Load Priority The load-priority has two options, STARTUP POSTWORLD By default, POSTWORLD is used. One valid reason to set this field to STARTUP is if you needed to modify something with world-loading. POSTWORLD should be fitting for almost all of your needs, and I would advise putting features that require STARTUP to be placed in a separate plugin. This is not a required field. Database If you don't know what this is, you'll probably be fine just setting this to false. Read more about the database option on Bukkit (warning: non-https). This is not a required field. Author(s) Put your username here! Please, do not put your actual name UNLESS it is also your username. It's best if you don't use your GitHub/Bukkit/Spigot name, but rather your Minecraft one. If you decide you would rather use your GitHub username for this, please put "GitHub/<Username>" (Example: "author: GitHub/8rrico"). Your plugin may be written by multiple people. If that is the case, please use the above format, but with the field "authors:" (note the 's'). The parameters should be enclosed in square-brackets ("[value]"). Each value should be separated by a comma. (Example: "authors: [GitHub/Curspex, Omnivion, Exloki]"). Author(s) is not a required field. Using both the author/authors fields has not been tested (by me). Website Here you can link your website. While it is advised that you put a link to the official plugin website if you have one, the next best thing is to use a link to your Bukkit/Spigot plugin post. Spigot is preferred over Bukkit (duh). GitHub links are also acceptable, just as long as it's related to the plugin! I wouldn't define this as a link to Jenkins dev builds. This field is not required. Depend & SoftDepend One section I personally didn't have any use for in the above plugin.yml is (soft)depend. If your plugin requires another plugin to load/use, you must include it in the depend section. Your plugin will load after the dependency. If the dependency isn't found & loaded, your plugin won't load. This is different compared to how softdepend works, as softdepend will still allow your plugin to (attempt to) load. One valid usage of softdepend would be in a plugin that uses a hook manager to load dependencies/dependent features internally. Examples: Spoiler: image Spoiler: text Code (Text): depend: [LokiLib, CPlayers] softdepend: [CPanels] Variables (permission-message) Now we can get to the fun stuff! Most people don't know about node anchors/references using yaml. When you've got a value you'll be using over-and-over again, it's a good idea to use an anchor. In the plugin.yml above, I defined a "permission-message" option. Inside that option, I placed my anchor "&noperms". Finally, I created a string, encapsulated in quotations. I'm not actually sure if you would need the quotations without the color code symbol. Later on in the plugin (Commands section), we reference the &noperms anchor by calling *noperms. The '*' tells yaml that this is a reference, and the & says it's an anchor. You can go a lot more in-depth with anchors/nodes, but that's for a different guide. Commands If you use commands in your plugin, this field is required. Each command has several parts; usage, description, aliases, permission, and permission-message. The usage will be displayed if the command returns false. If you would like to display a message across multiple lines, use the '|' symbol (shift+\, located above the 'enter'/'return' key). <command> will be replaced with the command automagically. Description is shown in the server's help-map. Aliases is a lot like the authors field; it's an array of values. Each alias should be separated by a command, and should all be encompassed in square-brackets. Finally, permission (we already went over permission-message). This should be the required permission, which will be defined next. Permissions You should use this section if your plugin contains even a single permission check. Each node contains three options; the description, the children, and the inheritance (default). See "Commands" for a guide on the description field. Default is who should inherit the permission node; you can specify one of four values; true, false, op, not op. Using true will give the node to everyone, false to no one, op to /op's only, and not op to not-/op's only (according to the Bukkit wiki, untested on false / not op). Children contains any permissions you want the current permission to inherit. For example, you could make poller.skip inherit poller.results like this: Code (Text): poller.skip: description: Skip spammy stuff. default: op children: poller.results: true Something brought up to me in the comments which I completely forgot about is the best-practice of including a star-permission (also called an all-node). I'm going to use the mcMMO plugin as an example; Spoiler: image Spoiler: text Code (Text): mcmmo.*: default: false description: Implies all mcmmo permissions. children: mcmmo.all: true mcmmo.all: default: false description: Implies all mcmmo permissions. children: mcmmo.admin: true mcmmo.bypass.all: true mcmmo.commands.all: true mcmmo.defaults: true mcmmo.defaultsop: true mcmmo.party.all: true mcmmo.perks.all: true As you can see, mcmmo includes not only an option to use the mcmmo.* node, but also mcmmo.all, for some permission schemas that require it. This is something you should incorporate into your yml files as soon as possible, to ensure compatibility!