Concepts
This document contains all sorts of useful information for Game Engineers. This ranges from explanations on how we work, to interesting readings. All Game Engineers should read through this at least once.
Semantic Versioning
Semantic Versioning (opens in a new tab) is one of the best known version schemes, and is used by most plugins. It is recommended to use this scheme whenever necessary.
Given a version number MAJOR.MINOR.PATCH, increment the:
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards compatible manner, and
- PATCH version when you make backwards compatible bug fixes.
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
Keep a Changelog
Changelogs are extremely important. Every single change made to the server should be documented. Changelogs are not only a great tool to find out about new changes, but also make it easier to track down issues. If a bug pops up, we can quickly check the changelog to see what might have caused it.
Types of changes (as per https://keepachangelog.com/ (opens in a new tab))
Addedfor new features.Changedfor changes in existing functionality.Deprecatedfor soon-to-be removed features.Removedfor now removed features.Fixedfor any bug fixes.Securityin case of vulnerabilities.
Material Names
Materials used to be identified by a numeric ID (e.g. 22). 1.6.1 introduced namespaced IDs (e.g. minecraft:lapis_block), and ever since 1.13's flattening these are the only accepted form of ID. Bukkit accepts these in an analogous, but uppercased, format (e.g. LAPIS_BLOCK).
Although some plugins still support legacy IDs, you should never use these, as this is guaranteed to break sometime. Always use the full namespaced IDs. These can sometimes change between versions, so these links may help you:
Binary Search
You can often face unexplainable behaviour of which you can't find the cause. Me4502, one of the EngineHub (WorldEdit, WorldGuard) developers, has written an excellent blog post on this subject (opens in a new tab).
In the case that a plugin causes the issue, you'll want to narrow down which plugin is causing it. One standard method for doing this is to remove half of your plugins and testing to see if it still occurs. If it does, remove another half. Continue doing this until the issue no longer occurs. Once it has stopped, you'll know that one of the plugins in the last group you removed is the culprit.
Once you've got this smaller group of narrowed-down plugins, you can use a similar strategy on this. Re-add half of them back, and continue until it starts again. You now have a smaller group of plugins. Keep doing this until you've narrowed it down to a single plugin. This concept is known as a binary search.
This method can be used in many different scenarios. We have used it in the past to find out what was causing the resource pack not to load without OptiFine. We kept removing half of the files until the problem no longer occured. We then used the same method on that narrowed-down selection of files until we found the exact file that was causing the issue.