Using Flexboxes in CSS

A joke among CSS/HTML designers is how difficult it is to simply center an item either vertically or horizontally. As simple as this sounds, there isn't a simple "position: center" type field in CSS. 

In simple cases you could simply add a 25% margin to the left side of the object, which will take 25% of the width of the outer element (or the page if none) and push the element that much from the left. Of course, that only works in simple cases. If you wanted to use a different positioning method or wanted to have another element on the left or right of the centered element it would break.

There are many different ways to center an element, each with their own pros and cons. There are so many, in fact, that someone even created a website to help you find the best method for your use case: http://howtocenterincss.com/.

I recently learned about a new multi-purpose display trick in CSS for positioning and sizing elements, called flexboxes. To use them, you would declare an outer div element as a flexbox (display: flex), making all of it's children follow the flex settings. One of my favorite features of flexboxes is the fact that you can apply all of these settings in the wrapping element instead of doing it on each individual element. 

For a use case, we'll assume a navigation bar. FIrst, let's say the outer wrapper's width goes across the entire page, and the height is relative to the elements inside. Each inside element is a simple box with padding, text, and a background. You want them to display as elements side by side, in the center, with space between each one. All of those effects can be applied in the outer flexbox, without having to touch the buttons. 

All you have to do to center the buttons is apply the justify-content: center field. If you wanted one button to be larger than the rest, but only by a percentage of the rest, you can use flex-grow on the specific element. By default, it's "1". This basically tells the element to take up as much space as one element in that flexbox. If you set it to 2, it will be twice as large as the other elements. This is extremely helpful when you have to deal with a changing navigation bar, as you don't have to worry about things breaking when buttons are added or removed.

Using SVG Graphics

 Rollup logo drawn as an SVG. Source: https://github.com/gilbarbara/logos

Rollup logo drawn as an SVG. Source: https://github.com/gilbarbara/logos

I went to a local meetup last night, with presentations on different topics around web development. One of them was on SVG graphics, and how to manipulate them with CSS.

SVG graphics aren't images, but HTML in an <svg> tag. It's supported by pretty much every browser. In the HTML that makes up the graphic, there are elements which give drawing data. For example, a rectangle that starts at x/y and goes to x/y. The primary benefit is that SVGs can scale perfectly, unlike images which can waste bandwidth if scaled down or lose quality if scaled up. For logos or anything that isn't a photo with a lot of color, SVGs are also a lot smaller in size. 

Another cool feature with SVGs is that each of the elements in the SVG can be targeted with CSS (like any other element). You can change the rotation of an element, a color, or the size of a rectangle. You can also combine it with CSS animations to animate your SVG. This makes it preferable over gifs, especially when you factor in file size and loading time. 

To design SVGs, you can use Adobe Illustrator. Otherwise, there are free online tools, like SVG-Edit.

Using Minecraft Maps as GUIs

While browsing the SpigotMC forums, I found a forum post in which the author used a combination of the input packet and custom Minecraft map rendering to create a nice looking GUI. 

 Source: https://www.youtube.com/watch?v=dkgwe-lCW-Q

Source: https://www.youtube.com/watch?v=dkgwe-lCW-Q

To use these GUIs, you hold the map in your main hand. It mounts you onto a fake entity, so the client will send movement input packets. To navigate the UI, you use the WASD keys, as well as space/shift. 

 Source:&nbsp;https://www.spigotmc.org/resources/maplands.46404/

Source: https://www.spigotmc.org/resources/maplands.46404/

He also uses it to connect placed maps in the world together to seamlessly create displays, even interactable displays. 

All of the tools for this are available in his commons library, which I plan to use myself at some point for personal projects.

42, a programming and entrepreneurial bootcamp

42.png

There's a programming bootcamp in Silicon Valley called 42. It's a 3-5 year program, during which you learn different programming languages and get work experience by going through internships with their partners.

To begin, you send in an application, answering basic questions. If accepted, you would then go to the next step, the piscine. You would go to the 42 campus sight, and for four weeks nearly 24 hours a day learning how to program with different projects. It's the most intensive part of the entire program. Only a fraction of the people who go through it will be accepted past that for the full course.

After a year, you're required to take an internship with one of their partners, usually lasting for a year. During the internship you're still a part of the program. Near the end, you would take either a full time job or internship. In between, you can take yet another internship, optionally. You can quit at any time, there isn't a specific program end date.

My Upcoming Bukkit Structure API

I've always felt that structures have never really been taken full advantage of, especially as the format and official support makes it a better alternative to WorldEdit/MCEdit schematics. It isn't in the Bukkit API yet, either, despite the fact that it would make perfect sense to access from a Spigot plugin. 

At the moment, you can use structures using DefinedStructure/DefinedStructureManager available in the Minecraft NMS source. Obviously this isn't ideal, especially as it's constantly changing. The fact that the implementation is there, though, makes it an easy candidate for adding to Spigot. 

It's easy to just add a wrapper to DefinedStructure and to replace the DefinedStructureManager with a Bukkit version, but I wanted to give more control than that. Mainly, I wanted the ability to manipulate structures while they're still in memory. For example, filling chests in a structure with loot before being pasted into the world. 

At the moment, the syntax looks like this:

structure.png

That example loads a structure from file called house.structure in the plugin folder. The Structure object holds all the blocks and other info in the structure. The next line gets a Structure.Block instance, which gets a block at a location in the structure. This block is at coordinates 0, 0, 0. Notice I also check if the block is null - this is because it's possible for a block at a location to be empty. That's not to be confused with Minecraft's air. The difference is that when the structure is placed in the world, air blocks will replace whatever is in the way, where empty blocks will not modify the world at that block position. In vanilla, there's a block called structure void which can be placed around to mark areas that should not be saved to file (empty blocks). They aren't saved in NBT anywhere.

After making sure the block isn't empty, I check if the block type is a chest. If it is, it's safe to assume that the BlockState is a Chest as well. In Bukkit, BlockStates are not directly tied to the World, though they do have a location. That means all data in the BlockState does not update with the world, nor do modifications made to the BlockState change the block until you call the update function. It makes the perfect class to use for structures as well. Additionally, all tile entities (blocks that hold data, like chests) extend that class.

Next I declare a variable with the Chest BlockState, casting from Structure.Block#getState(). I clear the inventory, and set it to a double chest expanding left. Just like BlockStates in a Bukkit world, it needs to be updated to take effect in the structure.

Finally, I call the paste function, giving the spawn location of "world" as the paste location. I'll add more arguments later, like rotating it or whether or not to include entities.

X-Bows Keyboard

Back in October, I helped fund the Kickstarter for the X-bows keyboard. The main feature of the keyboard is that it's ergonomic. The keyboard is shaped in a way that forces you to rotate your hands, instead of positioning your hands straight from your wrists.

xbows.png

The project was funded both on Kickstarter and then later on IndieGoGo, both times surpassing their goal by about eight times. Unfortunately, due to delays with their manufacturer in China, they weren't able to ship until seven months after the expected date. 

The keys are all mechanical, and you could choose between different key types to get the right feeling of clickiness and sound. Personally I went for a more clicky sound and as much of a mechanical press effect as I could get. It feels amazing, definitely the best feeling keys I've ever typed with.

 The layout itself is difficult to work with at first, though I'm slowly getting used to it. One of the best design features was putting the shift, enter, and backspace keys in the center of the keyboard (as well as in their normal positions) so they can be used with either the index finger or thumb. It also takes advantage of the spacebar being too long in normal keyboards to split it to be used by either thumb and replaced the center with Ctrl and Shift buttons. 

The keys are all also removeable, and because they use cherry switches you can replace many of the keys with keycaps that support the switches.

I'm also taking advantage of learning a new keyboard by also trying to learn the Dvorak layout. It's pretty old, invented in 1936 after keyboards and touch typing became common practice. It places the most commonly typed keys close together, so your fingers don't have to move as much allowing for faster typing. The reason the QWERTY keyboard didn't use a similar idea was because typewriters used to jam if two keys were pressed together at the same time, which happened a lot if two keys were pressed close together at nearly the same time, The solution was to just move the common keys as far away as possible from each other. Of course, with modern keyboards this wasn't an issue.

dvorak.png

Why Most Minecraft Networks Fail

Every day a new Minecraft server is started on, usually hoping to become the next Hypixel and become a popular server. Within a month or two, though, 95% of these servers die. Mainly, it's just lack of a player base who actually would play on their network. Each of these networks usually have the following mix of gamemodes:

  • Prison (level up via mining in a prison and eventually get out by leveling to the top)
  • Factions (Start a faction/team and raid other factions, also economy based)
  • Sky Wars, Bed Wars, Egg Wars (minigames with all the same concept, where you start on sky islands, with the objective being the last team standing)
  • Creative Plots (regular vanilla creative, maybe with WorldEdit tools where you can show off your building skills)
  • Survival Games (less common than it was before, a battle royale last team standing type game)

Sometimes they will have some sort of fairly unique game, usually a very modified version of survival and normally with some RPG type gameplay. When you join these types of networks, you're also usually greeted with a large, spacious spawn area. There are NPCs which will when interacted with will teleport you to one of the above games. There's also normally a large and unnecessary scoreboard hologram/text on the HUD, with flashing or animated server logos. It seems like every network sees this as a necessity, but I find it a hindrance - especially when you see something like "Players Online: 2/500". 

It's not that the games listed above aren't fun. But when they are on literally thousands of existing networks, usually with more features or players, why would you stay on this particular one? The main issue with all of them is that they require a large and existing player base. Nobody wants to play by themselves on a grinding based game (prison) where all they can do is spend hours at a time leveling up their rank (which nobody will see) and purchase gear (which will never be used). Nor do they want to wait in a minigame lobby for half an hour just to play with three or four players in an average match of Sky Wars. Why wouldn't they want to play Prison, leveling up along with thousands of other players and testing their PvP skills to earn loot. Or they may want to play Sky Wars, so why not join Hypixel where they only have to wait 10 seconds to have a full game and play almost immediately upon joining.

But even if by some miracle (or with money, since advertising your network on launch is always an option) you do manage to keep a consistent 25+ player count (pretty good for a startup). I've found that on the average network with that many players, less than 5% (and usually around 1%) will stay for longer than ten minutes, and even less will play again after they quit for the day. 

This leads to the second problem - boring first impressions. In online marketting, the first five seconds of a user visiting your website are the most critical. This is why the website layout and loading time is so critical. For Minecraft servers, the conditions are extra harsh. You need to give the player something that is both interesting and they can interact with in their own way. On top of that, if you want them to become regular players you need to keep them on for longer than 30 minutes at a time and usually a good hour. If you can accomplish that, it's a good sign they're hooked. 

Unfortunately, you can join almost any server and recognize the same things each time. If it's a server for a single or specific game, you will have to walk through a hallway with tons of signs (hard to read, by the way) explaining how each aspect works. You must do this before you can actually play the game, otherwise nothing would make sense. 

 

Why I have started using Java over Kotlin

I've been using Kotlin regularly for all the projects I would normally have done in Java for the past six months at least. Kotlin is a JVM programming language which compiles into Java bytecode. The difference is how the syntax is written before it's compiled. Kotlin basically removes the repetitive areas in Java (notably getters and setters), enforces programming conventions, and gives a slight performance boost due to the default ways it resolves functions. It's syntax is very similar to JavaScript, and in fact can "compile" (convert) into JavaScript as well as JVM bytecode.

After doing a few more projects for other clients, though, I've encountered a few flaws with using Kotlin as a practice. The main flaw (which should've been fairly obvious at start) is that clients don't like it. Sure, it might mean their project gets delivered quicker and bugs are easier to fix (by the original author). But for large projects (gamemodes for example) or networks which need to constantly adapt, Kotlin is discouraged. This is because only a small percentage of Sipgot developers actually know Kotlin, thus making it difficult to find a developer willing to fix bugs in the project if the original author is no longer available.

Another annoyance are the compile times. A project can take as many as 30 seconds to build, where a Java one can be done in under 5 seconds. On top of that, projects using Kotlin also need to have the Kotlin library available at runtime. This turns a normally 2kb project into a 4mb one. 

Finally, proficiency in Java beats the same in Kotlin. Even if they aren't programmers or know any programming, most people know what Java is. Less so Kotlin, and attempting to explain it just doesn't work.

Structures, the Vanilla Minecraft Schematics

Whenever someone wanted to share a Minecraft build, it was done by either sharing the Minecraft world for someone to load up and look around at, or is a schematic file for pasting into an existing world. Schematics were largely more popular, since servers could use it in combination with WorldEdit or MCEdit to paste it into their existing server world. The schematic file format has been around for a very long time, the first occurrence I can find in MCEdit's source being in October 2011 (though it probably existed before that).

Schematics were never endorsed by Mojang, so they required 3rd party tools to use. There isn't any specific rules of what a schematic should be, though they were generally decided by how WorldEdit or MCEdit used them. The current documentation of the format can be found on the Minecraft wiki. It includes a lot of the different fields added by community tools or outdated versions of MCEdit.

Around when 1.7 was released (2013), Mojang started to move away from numeric IDs deciding what blocks existed. This was mainly due to the fact there was a limit of how many different blocks could exist, but also because it's generally bad practice to use number IDs for data. This meant they moved from "1" being a stone block in the world to "stone" being a stone block. They started enforcing this with the vanilla commands, despite the fact numeric IDs were still used internally. In 1.12, you were no longer able to use numeric IDs in commands, and in 1.13 what was referred to as The Flattening happened. 

In combination to numeric IDs, pre 1.12 versions used data IDs. They were used when there was a block type, but it had sub types. For example, you had the wood log block, but there were about six variants of that block. So for oak wood, you had wood:0, birch had wood:1, etc.In 1.13, however, they removed all of these sub-type IDs and replaced with their own dedicated materials. This meant instead of wood:0, you had oak_wood, birch_wood, etc. They then added tags to these groups to make them easily discernable without having to do a ton of extra checks.

In 1.9 (released three years ago), though, Mojang added the officially supported and used Structure file formats. They were used internally to generate some of the natural structures, for example the End Cities and end ships. At the same time, they added the user-accessible Structure Block, which allowed players to select and save areas to a file and load it up again later. Despite the fact they were officially supported and part of the game, it never seemed to catch on and seemed to be largely ignored. WorldEdit didn't add support for them, and Minecraft build databases didn't support structures as a download option. 

With the new 1.13 update removing numeric IDs, hopefully Structures will be making a comeback. The file format is clear, and supports things like entities and block NBT data. One of the main reasons it isn't really used in Spigot plugins (that instead use schematics) is because no maintained libraries support them. In an effort to fix this, I'm trying to contribute to the Spigot project (and exploiting the fact that it's open source) by adding them into the Bukkit API for use by plugins without 3rd party libraries.

CraftBukkit, Bukkit, and Spigot Differences Explained

One of the confusing things I encountered whenever trying to look behind the scenes of the Bukkit API is what CraftBukkit, Bukkit, and Spigot referred to. Recently I've been looking at the source a lot more, and am even contributing towards it as well.

Years ago, Bukkit was DMCA'd by one of it's own developers. A DMCA (Digital Millennium Copyright Act - yes I had to Google that one) is similar to being taken down for piracy, but usually applies to stolen code. Technically nothing was stolen, since the code was under the GPL license, but it didn't stop the takedown from going through, stopping Bukkit development. Development attempted to continue, but it was later found that Mojang owned Bukkit, and they shut it down.

Because of the licensing at the time, you could still fork (make a copy and independently develop) Bukkit and continue development. Before it was DMCA'd, Spigot had existed. It's mission was to make it more performance friendly, but after Bukkit went down it became the most popular and basically the only active development of Bukkit.

When someone refers to the Spigot API or Bukkit API, they usually mean the same thing. Really, though, it's the Bukkit API being developed by the Spigot team, so it's still the Bukkit API. 

Bukkit is the interface for CraftBukkit, the implementation. Bukkit provides the function parameters and documentation, but on it's own are just empty interface functions. The purpose of keeping them separate is that Bukkit only changes with feature changes and then very rarely (usually not breaking anything depending on it every update) whereas CraftBukkit must be updated for every update to support new Minecraft changes. 

Remote Debugging Spigot Plugins with IntelliJ

The most useful discovery I've ever made in programming wasn't actually a programming feature, but being able to use the debug features present in most IDEs. Debugging is one of the most difficult and mind-numbing tasks in programming, and makes up a large part of the programming process.

Debugging in the IDE usually revolves around something called breakpoints. In order to setup your IDE to work with a running program (the Spigot server for example) you simply have to add a few arguments to the script you use to start the server. In your IDE, just create a new Debug Run configuration and provide the port set in the startup parameters. You don't have to recompile your plugin to use any of the debug features.

Breakpoints allow points at which the server should stop at (freeze). In the IDE, data for that "frame" will appear, showing you the values for variables in the source at that breakpoint as well as in it's own window. This is especially useful when you don't know the specific issue you are having, and saves time (as opposed to making minor modifications at near random until it works). 

You can also "step" around frames. A frame is a set of data for the level you're looking at. For example, if you have a function calling another function which does a calculation (a + b for example) you could place a breakpoint right before returning the function result. When the program reaches that point, it will stop and the IDE will provide the values for the variables as they appeared during runtime. The frame in that case is inside the function. If you wanted to know where the function was being called from, so you could get the context, you can step out of the frame to the function that's calling it. You will then get provided with all the variable data in that function.

One of my favorite features is being able to use breakpoints in libraries, without having the original source. For example, if the player was being healed from some other plugin or source and you wanted to know why, you could add a breakpoint to the Player#setHealth() function in CraftBukkit (as decompiled by the IDE). Whenever it's called by any plugin, it will halt the program. If you have the plugin calling it added as a library you can step out of that frame and find out what the execution parameters or requirements are for that plugin to execute the function.

Another cool features is being able to update the classes during runtime. If you wanted to change something small, changing a -1 to a 1 for example, you could actually update that part of the source on the server without having to restart the server or program. It is limited, though. You cannot change any class declarations (class names, function names, parameters, class/global variables, etc). It does work well for quick testing, though. You could switch out a URL to an API endpoint to a test one (provided by something like Postman) if you wanted to test it with different endpoint results.

Finding Malicious Code in a SpigotMC Premium Plugin

As part of my job as resource staff on the SpigotMC forums, I handle resources (plugins) being reported. Most commonly they will be someone "stealing" another resource and simply reposting the same file (and sometimes even the same description) as another existing resource. Sometimes they will even report the original as the impersonation (though obviously their resource was published after theirs). Those resources are removed very quickly and the user warned (and if it continues, banned).

When checking out these reports, most of them require decompiling the plugin jar file to verify it is actually stolen or contains malicious content. You can also sell your plugins on SpigotMC (the limit being around $20 per copy), and there are specific rules for that. Before you can post your premium resource (as they're called) you must have at least 40 posts and 20 positive ratings, as well as a few published resources. This means that only dedicated members of the community can sell their plugin, not just anyone looking for a place to make money. 

Then premium plugins must be approved by staff. The rules also don't allow generic plugins, in order to keep what's being sold as high quality as possible. Notably, KitPvP gamemode plugins are given as an example of what will be denied. KitPvP is a simple game that started several years ago. Players are given kits and drop down into an arena and simply PvP to death, to be respawned and drop down again. It based around kits, starting items with different gameplay types. Unfortunately, they were fairly easy to create as plugins which led to many of the plugins being sold doing the same things, so SpigotMC require resources to be original and innovative. 

Premium resources commonly are bought, then the copy given away on pirating websites. Nearly every remotely popular plugin has been pirated this way, and there isn't much the authors can do about it. In order to prevent authors from selling plugins than later revoking access to it's features, the premium resource rules state that plugins must work without an internet connection (cannot contact the author's servers for validation) nor should any features be able to be remotely disabled. 

One resource, a gamemode type resource, was reported because it had suspicious sounding text in the description that ran something like: "If you violate these terms, do not underestimate the power of Java". I didn't personally handle the report (another staff member got to it before me), but I went ahead and decompiled the plugin anyway out of curiosity. 

It turned out to be full of malicious code, though not intentionally so. First, it wouldn't work unless you had an internet connection (would disable the plugin). But then, it also gave special abilities to players on a contributor list. Remotely, he could also delete every plugin and it's data running on the server (which is the majority of the entire server really). 

What was really strange is that he also created his own ingame GUI which allowed him to kick and ban any player on the server, as well as send back information about the machine the server was running on. The resource was removed.

Using Java Sockets to Communicate Between Servers in a Network

I recently got hired to re-write a large game in Minecraft, similar to classic Survival Games. It needs to run on a network, allowing for multiple game servers to go on as well as multiple servers to connect from.

The servers the players can connect from needed to know the game status, map, mode (there were different types/remixes of gameplay), entry fee (cost to join), current player count, and maximum player count. All these would be displayed to players when viewing the ongoing games, and would also be used to partially judge whether or not a game would be open to players.

Minus a few features, the previous installation of the game used a MySQL database to store information about the server. I felt that MySQL was the wrong way to go about storing what should be stored in memory, and instead, I went the route of using a central server from which both game servers and join-from servers could contact for data, similar to Minecraft packets.

The game network consisted of the game plugin/server, a plugin on the BungeeCord proxy network, and another for the join-from server.The game server would send data in the form of a JSON string to the Bungee socket server, which would then forward it to the join-from servers. When a player wanted to join a game, the join-from server would send a packet to the game server (forwarded from Bungee) in order to double check that the data is consistent. If it all checked out, the Bungee server would send the player from their current server (storing it so they can be moved back later) to the game server, where the game server would handle every new player joining.

Using DialogFlow Intent Detection to Get Data from a Minecraft network

I spend quite a lot of time on the Spigot developers forums, and one thread caught my attention. Coincidentally, I'm working on the same project the thread author started months ago (under a network). He was looking for some help with getting a service called DialogFlow to integrate with his Minecraft network.

DialogFlow is a service by Google which integrates with things like Google Home and Amazon Alexa to allow users to ask questions and for custom services to handle the response. The way it works is the developer creates an "intent", an action/question that a user can ask. They can then add parameters to the intent which are automatically parsed from the question and sent over to your handling server. In this case, the author wanted to allow users to ask "how many players are on server <x>?". The intent could be called "PlayerCount", and the parameter would be the server (<x>). After giving it a few training phrases (and selecting the parameter from those phrases), it gets really good at recognizing which word is the correct parameter.

Once it's parsed the question correctly, it then sends a request to your webhook. A webhook is a URL that data can be sent to by a service, usually an update or notification, which is then handled by the service. DialogFlow sends the Intent name, parameter(s), the full phrase, and other data to your webhook server, which then checks the given server player count and sends back data with whatever response you want. 

This is the first time I've done HTTP backend in Java/Kotlin, so I used a library called Spark to simplify things (as opposed to using the builtin HTTP library).

Maven Plugin for Generating Spigot's plugin.yml in Spigot plugins

When creating plugins/projects for myself, I usually create libraries that can be re-used for different parts of the plugin. For example, I recently created an annotation powered command API in Kotlin. In addition to that, I've also created an input library using the trick I described earlier. It allows me to very easily listen for player keyup/keydown events as well as attach/remove the listener/mount entity for the player, without having to write out the messy packet code every time.

I'm also a big fan of unification in my projects - if I have to write something out twice, maintenance of that code becomes twice as hard. While this specific case isn't code, it does help to easily fill in details for my plugin. 

Bukkit (and subsequently Spigot) requires all plugins to contain a plugin.yml file in the root directory of the jar.  It contains information used by the server for logging and showing information to admins. There are three required fields, as well as many others which are optional. 

The first required field is the name of the plugin, usually in the format of UpperCamelCase (no spaces). It's used as the prefix for commands registered by the command (when a prefix has to be supplied), part of every message logged by your plugin, and generally allows administrators to find problem plugins from exceptions. The second required field is package path to the plugin main class, the class which is loaded by the server and contains a few utility functions. A typical main path might look like "com.scarabcoder.example.Example" where the last section is the class name itself. The final required field is the version of the plugin, which is usually paired with the plugin name during exceptions and helps when a consumer needs to report a plugin error.

With the possible exception of the main class, all those are readily available in the Maven build file (pom.xml), and should normally match exactly. There are also other optional fields in the plugin.yml, such as description or a list of authors, all of which can be taken from the Maven build file (<description>, <developers>, etc). 

After a bit of googling around, I found a basic intro to writing a Maven plugin in Java (though I adapted it to Kotlin). I had to look around a few open source plugins to find out how to get data from the Maven build file as well as add to the final compiled package, but after an hour or so I had it working. At the moment, it generates the following plugin.yml fields:

name: Taken from the <name> specified in pom, if none is found it's taken from the artifact ID
main: Can be overriden manually, otherwise it's set to <group>.<artifiact ID>.<name> (what I would recommend the path to be for a main class file). 
version: Taken from the <version> property in <properties>
description: Taken from the <description> tag
website: Taken from the <organization> tag
developers (list): Taken from all the developers listed in <developers>

Additionally, you can specify Spigot plugins your plugin relies on inside the <configuration> tag the Maven plugin, as well as plugins it should load before or soft depends on.
 

Annotation-based Hierarchical Plugin Command API

When a player sends a chat message from the client to the server beginning with a forward-slash ("/") the server treats it as a command and is processed accordingly. In vanilla Minecraft, an example might be "/tp ScarabCoder" where the command is "tp" and the first argument (arguments normally start after the command) is the player's name. As far as simple commands like that go, it's easy enough for the server to check for a player by the name of the second argument and if it exists simply teleport the command sender to the player it found.

Sometimes, though, commands aren't that simple. A good example of a much more advanced command is the /scoreboard command in vanilla Minecraft. It handles teams, certain elements on the HUD, and a few aspects around the player. The "root" command is /scoreboard, but it can be considered to have multiple commands with every section being a different command. For example, if you wanted to modify teams in any way you would run "/scoreboard teams <arguments>" (<> is commonly used to specify an argument name) would be the command to modify teams in some way. A more complete example:

/scoreboard teams add Test
/scoreboard teams remove Test
/scoreboard teams join Test

At that point, it's just as though the first argument ("teams") is just a specifying another section inside the scoreboard command. Unfortunately, the programming behind that is not treated as such. In reality, there are a ton of "if" statements checking for each possible argument, sometimes "sections" within sections. It can quickly build up and become a mess. This is a command ("/ticket" base) which I created for a plugin which allowed users to open support tickets. This command is only the moderator side, and contains the following usages:

/ticket close <id>
/ticket tp <id>
/ticket flag <id> <flag>
/ticket comment <id> <message>

The amount of code that I had to write, however, was insane. There were a ton of "if" checks to make sure the amount of arguments passed were in the correct amount, that tickets with a given ID existed, etc. Here's a screenshot of what it looked like, with a much smaller font size. It still doesn't show the entire command class, though.

LongCommands.png

About 80% of that are "if" statements or simply parsing statements to get a ticket object out of the ids given. This is stuff that must be done repeatedly, exactly something a computer should be doing instead of me. 

I've been working on a new large gamemode in which I try to use the best possible practices and create the cleanest code, at the cost of the time it takes to learn and write that code. One thing I was settled on was developing a better API for handling large commands and sections inside those commands.

This new API uses a hierarchy to manage sections, meaning a "teams" section would be inside the "scoreboard" section, in separate classes. Inside each section is a command, which requires arguments that are actually used as arguments and not used to go into another section. For example, the team command would be treated something like this:

scoreboard
    -> teams
        -> create(name)
        -> remove(name)

Where each command is treated something like a programming function. In fact, each command in my API is actually taken from a function, meaning not only is it easy to sort out where commands are it also acts exactly like a function would. For example, inside the TeamsSection class (where all commands inside the teams class is reachable via /scoreboard teams) there would be the create function:

CreateExample.PNG

You can specify pretty much whatever you want the command to have using the annotation's (optional) parameters. When a player executes "/scoreboard teams create test", the function is called with the first argument being the player's name and the second argument being "test" (the team name). Little to no manual processing has to be done, making it extremely easy to add commands. 

It also supports custom type conversion. This means that a parameter in the command function can be an Integer, and if it isn't a message is sent to the player and the function is never called. You don't have to convert the String to a Player as a username, you don't have to make sure that a string can be converted to an integer, it's all automated. You can also add your own converters, which in the ticket example I gave above would allow you to take a Ticket object as a parameter without having to check in every function that a string can be converted to an existing Ticket object. 

The final little feature is that it registers the command with Bukkit automatically, meaning you don't need to add any of the command's details in the plugin.yml. This is especially useful, since the API also allows you to specify aliases and descriptions and it's nice to have that all in one place. 

Getting WASD Movement Control Input From the Client

Brief Overview of Packets

All communication between the player (client) and the server is done via "packets". A packet is a collection of data, with the first entry defining what sort of packet it is. For example, when an entity is spawned in the world, the server sends a Spawn Entity packet to the client and the client will render that entity at the given location with the given fields. A server that operates according the specifications expected by the vanilla (unmodified) client is referred to as a "Notchian" server. It may be modified in any way, so long as the packets are sent and received in the same way as an unmodified server. This means that a server with Spigot plugins might not be considered vanilla (unmodified) but would still technically be a Notchian server. 

There's a public packet specification wiki updated by members of the community and by the Mojang team (unofficially) that contains an updated list of every type of packet and other useful information (inventory slot IDs, some NBT data documentation, etc), called Wiki.vg.

This means that everything a plugin can do is limited by what the client can understand. The server can send anything to the client that's supported as listed by the packet wiki, however. A mod, however, modifies the client and in most cases the server (to add support for whatever is modified in the client). If a new block is created, the modified server will send world data with that block, but unless the client already contains data in the form of a modification for that block (textures, models, etc) it will either ignore it or simply crash.

Getting Movement Controls

When the client moves the player, the updated location and velocity is sent to the server. The controls are handled by the client, and the position updating is actually done clientside. Of course, the server can send a packet back to cancel the position change on the client and simply not store the new position, but by default this isn't the case. That's why "hacks" are possible - they simply modify the client to send things such as staying in the air instead of following gravity (once again, done clientside) to the server. Anticheats will double check the data to make sure it's following (loosely) the same mechanics as a vanilla client. 

One feature which most plugin developers/server modifiers wish for on the client is the ability to get the exact WASD key presses. You could check if the player moves on a block in a certain block, but cancelling that move on the client will look strange as their viewpoint is shifted back to the starting point. 

One example where you may want to get just the movement controls without actually moving the player or doing your own movement calculations is a custom vehicle. In this case, we could say a helicopter. You can send entity packets to the client to create a sort of helicopter out of entity models by positioning them correctly, but controls will be tricky. You could send a flight mode enabled packet to the client and allow them to move in all six directions and simply move the entities along with the player, but unfortunately the delay between the client moving clientside and the entities' position being updated to the client will create an ugly delay (lagspikes, for example, could make the entities seem a little "jumpy").

There is another method of getting a player's movement controls. In vanilla Minecraft, there are vehicle entities such as the horse or minecart. When a player is mounted on a vehicle, movement controls are sent to the server to process and move the vehicle accordingly. This is because vehicles usually have different movement needs. A minecart, for example, must follow the tracks set down. It *can* be done clientside, but because of the many calculations needed it's much more efficient to simply take user input (that's important) and update the velocity of the vehicle from that. 

What's interesting, however, is that whenever the client is mounted on *any entity*, it sends these movement control packets to the server whether or not it means anything in vanilla Minecraft. Movement packets will be sent whether you're sitting on a horse or an armorstand (the client can be mounted on any entity, not just vehicles). The packet for this is listed on the technical wiki as "Steer Vehicle", and is also known as the "input" packet. It contains the following data:

Packets.png

The first two fields are the forward/backward and left/right fields. The last tells you if the action is the player jumping (pressing space, used by horses usually) or unmounting (player dismounting is handled serverside). From this packet, you can tell the WASD controls and get the space/shift keys aswell. 

To apply this to the helicopter example above, you can send spawn entity packet with an invisible armorstand, then another packet to mount the player on that entity. Once done, the client will send a movement packet every tick. From there you can listen for those packets either via ProtocolLib's API or injecting your own listener (I prefer injection, especially so that an external dependency isn't required). Get the forward/backward and left/right fields from the packet, and update the position of the helicopter entities and the mount entity, resulting in a synchronized client & entity movement feel. 

I first found this little trick from the Spigot forums. One user had used a custom map renderer to allow you to move a rendered screen on a wall using the WASD controls. I plan to use a combination of these features to move a 2D game screen in an upcoming game I've been working on.

MySQL: The Magically Perfect Data Storage Method for Performance

Let me walk you through a nightmare scenario that I experienced earlier this week when fixing some bugs on an older project from another developer. The project was fairly simple. It allowed players playing on the network to claim a location where they and their team members could quickly teleport back to at any time but could be destroyed by anyone else. It also included a moderator feature which allowed staff to see the history of a team's home locations, useful when they use it to get to otherwise unreachable areas (homes could be claimed anywhere a player could reach, even places they couldn't actually get to otherwise).

Here is how he had his MySQL database setup:

Team ID [PRIMARY] | Clan Data [TEXT]

Two columns. The first was the ID of the team from the 3rd-party teams plugin, the second was a nightmare of deserialized objects with character separators. Each home object had the following data:

  1. Clan name
  2. Location (x, y, z, and world name)
  3. The player who set it down (the ID of)
  4. The player who destroyed it, if destroyed
  5. The date it was set down (millisecond timestamp)

It was put into a serializable string, resembling something like this:

"5:3:7:world_146727_null_1517941648916"

And added to whatever was in the clan data column. After a few days, you would get something like this:

"5:3:7:world_146727_null_1517941648916|5:3:7:world_146727_null_1517941648916|5:3:7:world_146727_null_1517941648916|5:3:7:world_146727_null_1517941648916|5:3:7:world_146727_null_1517941648916"

Of course, because there was only one column, it meant that everything from the database was loaded into memory on server start. The project was fairly old (about a year and a half old), so there were 6,000 rows in the table, 90% of which were no longer used. On top of all that, the MySQL database wasn't part of the same machine as the server the plugin was running on.

Why would someone do all that? Couldn't they obviously see that it was horribly performance & resource intensive, that a flat-file storage method would have worked much better with the same method?

The truth is, people (new developers especially) see MySQL as somehow extremely quick at delivering data and being very performance friendly. The administrator - or whoever is installing/setting up the plugin - will see that it uses MySQL and automatically assume that it will work much better than using YAML or JSON flat-file. I don't doubt that this developer didn't know MySQL well, and may even have learned it on the spot just because the job description asked for some MySQL experience. 

That being said, here is how I would (and did) set up the MySQL table format:

ID (primary, unique, auto-incrementing) | clan ID | x | y | z | world | date (timestamp) | setter UUID | destroyer UUID (null if active)

The primary difference (which actually called for a rewrite of the entire project) is that each home has a separate row. This made it easy to just grab the active home, or grab just the homes created since a certain date (as was required by the staff history command). I could also very quickly write a statement to remove homes that were inactive and created before a certain date. For example:

DELETE FROM homes WHERE date < 1517941648916 AND destroyer != NULL

With the previous table format, this would have been impossible without downloading all the data in the database. 

(Tutorial) How to create cooldowns with Spigot

Before you start (prerequisites)

You don't need to have any extensive Java experience, but it helps to understand how some of the basic features work. The main point of this tutorial is to go over the method and it's implementation, not how Java features like Singletons work.
 

How we want it to work 

For these examples, we will use the command /cooldown as the feature. It can only be used once every 15 seconds.
 

(Pitfall) Method #1: Using Runnable Timer Tasks

Before we get into the most common and performance friendly cooldown system, I want to cover a commonly suggested method that you should avoid. It's suggested fairly often because of how simple it seems at first.

In this method, your plugin has a Singleton cooldown manager:

public class CooldownManager {

    private HashMap<UUID, Integer> cooldowns = new HashMap<>();

    public static final int DEFAULT_COOLDOWN = 15;

    public void setCooldown(UUID player, Integer time){
        if(time == null)
            cooldowns.remove(player);
        else
            cooldowns.put(player, time);
    }

    public int getCooldown(UUID player){
        return (cooldowns.get(player) == null ? 0 : cooldowns.get(player));
    }

    private CooldownManager(){}

    public static final CooldownManager INSTANCE = new CooldownManager();

}

It contains the basic methods for setting, getting, and removing from a cooldown map. Next we have the Command Executor:

public class CooldownCommand implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        //Player only command
        if(sender instanceof Player){
            Player p = (Player) sender;
            int timeLeft = CooldownManager.INSTANCE.getCooldown(p.getUniqueId());
            //If the cooldown has expired
            if(timeLeft == 0){
                //Use the feature
                p.sendMessage(ChatColor.GREEN + "Feature used!");
                //Start the countdown task
                CooldownManager.INSTANCE.setCooldown(p.getUniqueId(), CooldownManager.DEFAULT_COOLDOWN);
                new BukkitRunnable() {
                    @Override
                    public void run() {
                        int timeLeft = CooldownManager.INSTANCE.getCooldown(p.getUniqueId());
                        if(timeLeft == 0){
                            CooldownManager.INSTANCE.setCooldown(p.getUniqueId(), null);
                            this.cancel();
                            return;
                        }
                        CooldownManager.INSTANCE.setCooldown(p.getUniqueId(), --timeLeft);
                    }
                }.runTaskTimer(SpaceRaiders.Companion.getPlugin(), 20, 20);

            }else{
                //Hasn't expired yet, shows how many seconds left until it does
                p.sendMessage(ChatColor.RED.toString() + timeLeft + " seconds before you can use this feature again.");
            }
        }else{
            sender.sendMessage("Player-only command");
        }

        return true;
    }

}

 

(Register the command executor)
As you can tell, it seems very simple. The main part of this section is that it decreases the time left before they can use the feature again every second, in the BukkitRunnable task timer. It will work just fine as it is now.

This method, however, has some major issues. For one, you should always avoid using runnables, as async tasks will create a thread for each task. Second, this means if you have several hundred players online, you will have the map updating many, many times a second (assuming the players are using it). For minigames with multiple cooldown features, there can be as many as a hundred tasks running at once, and it can become quite a mess internally.

One of the largest drawbacks, however, is that you can only track seconds with this method (at the smallest). You can't track anything smaller, and if you wanted to you would have to change the time unit to 1/10s of a second or less, and it would need to be updated 10 times more often.
 

Method #2: Using Timestamps

Rather than updating a variable every second or more, you can actually just save the last time a player used a feature, then subtract it from the current time to get how long ago the player used the feature. From there, it's simple to make sure it has been more than x time. It looks something like this:

if (current time) - (the time the featured was last used) > (delay) [do feature, update last used time]

For accurate time tracking, we can use a feature in programming known as a timestamp. Timestamps are just like what they sound like - a stamp of the time it was used at. The most accurate type is to use System time milliseconds. Basically, the timestamp is in milliseconds. More technically, how many milliseconds have passed since January 1 1960 (known as epoch). You can use the function System.currentTimeMillis() to get the current timestamp in milliseconds.

We'll use the CooldownManager from earlier, with two changes. int (or Integer) type can't store a variable of that size, millisecond timestamps are stored in Long type variables. Simply replace occurrences of "Integer" or "int" with "Long" in the manager class. Second, instead of returning "0" if the map doesn't contain the cooldown timestamp, we have to use Long.valueOf(0):

return (cooldowns.get(player) == null ? Long.valueOf(0) : cooldowns.get(player));

With this method, our CooldownCommand class should look like this:

Code (Text):

public class CooldownCommand implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        //Player only command
        if(sender instanceof Player){
            Player p = (Player) sender;
            //Get the amount of milliseconds that have passed since the feature was last used.
            Long timeLeft = System.currentTimeMillis() - CooldownManager.INSTANCE.getCooldown(p.getUniqueId());
            if(TimeUnit.MILLISECONDS.toSeconds(timeLeft) >= CooldownManager.DEFAULT_COOLDOWN){
                p.sendMessage(ChatColor.GREEN + "Featured used!");
                CooldownManager.INSTANCE.setCooldown(p.getUniqueId(), System.currentTimeMillis());
            }else{
                p.sendMessage(ChatColor.RED.toString() + TimeUnit.MILLISECONDS.toSeconds(timeLeft) + " seconds before you can use this feature again.");
            }
        }else{
            sender.sendMessage("Player-only command");
        }

        return true;
    }

}


 

Already much shorter, and the variable is only updated when the feature is actually used!
You'll notice I used a Java util method you may not have seen before - TimeUnit. TimeUnit is extremely helpful, especially if you don't want to convert time units yourself. In the above example, we used TimeUnit.MILLISECONDS to tell TimeUnit the input variable will be in milliseconds, then used toSeconds() to get the output in seconds.

With a bit more math, you can convert to hours, subtract the hours from the initial variable, then convert the remainder to seconds. It does take some playing around with to get it down to perfection. There may be some available libraries or functions by other users that does this for you, however.

Making Time Calculations with Java Timestamps: The best performance-friendly solution to cooldowns

Awhile ago, while trying to become more active in the Spigot community offering help and discussing different methods of accomplishing things, I email subscribed to the Plugin Development section. I now get an email for every post, which occurs atleast once every few minutes. This means I'll probably have to get a new hard drive months before I normally would've, but atleast I can catch posts that are intriguing or spark a train of thought in some way.

For some strange reason, atleast one post a day is someone trying to add a cooldown effect to some tool or ability - basically, a player must wait x seconds before being able to use a feature again. 

 People don't seem to be able to use the search feature on the Spigot Forums before posting.

People don't seem to be able to use the search feature on the Spigot Forums before posting.

I can't help myself from responding to them as I see them, so instead I'm making this handy-dandy post with everything you need to know about how to create cooldowns, common pitfalls to avoid, and case examples.

Option #1: Repeating or delayed tasks

This is what I see getting most suggested after using timestamps. Basically, when the player uses the feature for the first time, a variable is set putting a player's UUID and the amount of seconds until they can use that feature again into a map, and a repeating task is started using Bukkit's Scheduler. In that task, the variable is decreased by 1 every second. If the player tries to use the feature, it will get the seconds from the list and if it's more than 0 it'll tell the player it has to wait <x> seconds. 

Why this is an awful method

When using countdowns of any kind, it's always tempting to use repeating tasks. It looks like it makes sense, right? In reality, it's not very performance friendly. First, it's not a good idea to have too many tasks running at a time, as a thread is created for every task. Second, you're changing a variable every second. That doesn't affect performance too much, but there are methods that are much more performance friendly. The main issue, though, is that tasks are just a little weird to deal with anyway. They need to be cancelled when no longer used, and a whole class is needed aswell, with a reference to either the task ID or it's actual object (thought it can also be cancelled from within the task itself). Using tasks should be a last resort, they just aren't a very code-clean method.

Option #2: Timestamps

The only reason you don't see timestamps as a solution to time tracking is that they can be a little difficult to wrap your noggin around the first time you hear about it - it's a little less beginner friendly, but much, much cleaner once you get the concept.

What are timestamps?

Timestamps are very simple by themselves. Simply put, it's the amount of milliseconds that have passed since January 1st, 1970. It's used by all systems. For example, your system clock runs off of that timestamp, and simply translates that into whatever format it requires. You can get the current system timestamp by using System.currentTimeMillis(). As the variable won't fit in an int type variable, it must be stored as a Long.

How it works

When a player uses the feature, their ID and the timestamp at that time is stored in a map inside a manager class. When a player attempts to use the feature again, you can use the equation <currentTimestamp> - <lastFeatureUseTimestamp> to get how many milliseconds have passed since the feature has been last used. From there, you can convert that into whatever time format you want to check it against the required time before the player can use it again.

In order to make time conversions easier, Java has a util class called TimeUnit. To convert milliseconds to seconds, for example, you can use the method TimeUnit.MILLISECONDS.toSeconds(<ms>). 

As you can tell, it is very performance friendly, so much more so than the previous method with repeating tasks. The variable is only set once, and it's even only checked or changed when the player attempts to use the feature. 

Potential issues and how to fix/avoid them

The only issue with this method is that it becomes a memory leak. It's very easy to solve, however, with these two fixes:

  1. On PlayerQuitEvent, remove them from the cooldown manager map
  2. If they use the feature and the cooldown has expired, remove them from the map

You'll notice how much easier it is to handle cooldowns, and with this method you also have the option to display it in whatever format you want.