View Single Post
Brad
Selfish Heathen
 
Join Date: May 2004
Location: Zone of Pain
 
2012-02-29, 00:29

Quote:
Originally Posted by 709 View Post
Maybe, if you get in a mood, Brad, you could give us ... what Bukkit does and why it's such a big deal?
Gladly!

edit: I went a little overboard. You were looking for a tl;dr version. Here it is.

TLDR:

Bukkit allows you to add plugins that can completely change the behavior of many parts of the game. Without Bukkit, Minecraft server is virtually no different from single-player Minecraft aside from the multiplayer aspect.

That said, let the rambling commence.



Minecraft multi-player server is little more than the standard single-player game that you can play alone. On a server, you really only get two additional features: chat and "op" privileged status. Op (short for operator) is a very rudimentary administrative role. The op can ban players, pardon banned players, give resources (by opaque numeric IDs), give XP, change the time and weather, teleport players, change player modes between creative and survival, and shut down the server. That's it. No más.

Bukkit aims to greatly expand that functionality. Bukkit is a fork of the Minecraft server that adds APIs to the server. The Bukkit developers took the source code for Minecraft server (I'll explain how later), modified ("forked" or "branched") key parts of the code, and repackaged it into a new executable program. "API" is short for "Application Programming Interface" and (in this context) is just fancy talk for places in the server where a plugin can attach new code while the server is running.

What kind of APIs are there? Bukkit provides two types basically. One is the "command" API that lets a developer write whole new commands (like "/wwarp world_bp"), and the other is the "event listener" API that lets a developer's plugin "listen" for something to happen (such as a player going to sleep in a bed) and then cause something new to happen (such as restoring the sleeping player's health).

The APIs that Bukkit added to Minecraft server allow a plugin to do lots and lots of things that wouldn't be possible in the regular game. There are "economy" plugins that enforce fair trade and buying/selling among the players. There's the popular "lightning-shooting" plugin. There's many-world teleportation support ala my SimpleWorldWarp. There are plugins that can alter the terrain shape or change the types of trees that grow. There are plugins that change what blocks drop, how much damage mobs can cause, and effectiveness of your tools. Etc etc.

Here's a list of events a plugin can "listen" for... just in the "Player" category:

Quote:
PlayerAnimationEvent, PlayerBedEnterEvent, PlayerBedLeaveEvent, PlayerBucketEvent, PlayerChangedWorldEvent, PlayerChatEvent, PlayerDropItemEvent, PlayerEggThrowEvent, PlayerExpChangeEvent, PlayerFishEvent, PlayerGameModeChangeEvent, PlayerInteractEntityEvent, PlayerInteractEvent, PlayerInventoryEvent, PlayerItemHeldEvent, PlayerJoinEvent, PlayerKickEvent, PlayerLevelChangeEvent, PlayerLoginEvent, PlayerMoveEvent, PlayerPickupItemEvent, PlayerQuitEvent, PlayerRespawnEvent, PlayerShearEntityEvent, PlayerToggleSneakEvent, PlayerToggleSprintEvent, PlayerVelocityEvent
None of this is normally possible in Minecraft. Bukkit makes all of this possible.

...

Some extra nerdy bits… how does Bukkit make this happen?

Minecraft is a Java app, and similarly the server is also a Java app. Tools exist that developers can use to "decompile" Java apps into editable source code. Mojang (and other closed-source developers) realized this, and they run their source code through an "obfuscator" before compiling it into an executable Java app. Obfuscated code can be decompiled, but it's a nightmare to read as a human and figure out what it means.

For instance, here's an actual obfuscated method from the Minecraft server:
Code:
public fs a(int paramInt1, int paramInt2) { if (this.c[paramInt1] != null) { if (this.c[paramInt1].a <= paramInt2) { localfs = this.c[paramInt1]; this.c[paramInt1] = null; i(); return localfs; } fs localfs = this.c[paramInt1].a(paramInt2); if (this.c[paramInt1].a == 0) this.c[paramInt1] = null; i(); return localfs; } return null; }
I have no idea what that does! All of the variable and class names are short jibberish names that are almost impossible to decipher.

Almost.

In software engineering, there are common idioms and design patterns that virtually every developer will use. There are best practices for programming games, like how to implement gravity physics, how to determine 3D line-of-sight, etc. A trained eye can pick out a few of these patterns in the code, rename a few of the obfuscated names, and suddenly you're a small fraction closer to having an understandable pile of code.

Through lots of investigating and debugging and sheer trial and error, the Bukkit devs have un-obfuscated some key parts of the server code to actually be legible. Once they have legible code that they understand, then they start modifying it, adding small bits of code called "hooks" that create the API that allow plugins to inject new code.

Why does Bukkit's official relationship with Mojang matter?

Until now, every time a new version of Minecraft server is released, the Bukkit devs have to scramble to catch up. Each new version is re-obfuscated in a different way. So, a method previously called "xfdf" might now be called "affa". This means the Bukkit devs have to mix and match new and old code to get a working product again. That can be a painstaking process, and bugs can arise as a result from imperfect merges.

Also, only a small fraction of the server has been successfully unobfuscated. There are large swaths of Minecraft/Bukkit code that still look like that snippet above. This means that there are lots of areas of the code that don't yet have API hooks that could have them. The EntityCreeper.java, for instance, has no API for adjusting the "fuse" for the creeper. I'd love be able to adjust the fuse since it seems so much shorter in SMP than SSP. Not possible without a lot more work.

Having access to the full unobfuscated codebase means the Bukkit devs don't have to scramble with each new version, and they get a clearer understanding of where and how they can add new APIs. It also means they can clean up some of the less-optimal bits that they had to commit in order to work around weird behaviors in the server they couldn't figure out or change.

tl;dr? Scroll up.

The quality of this board depends on the quality of the posts. The only way to guarantee thoughtful, informative discussion is to write thoughtful, informative posts. AppleNova is not a real-time chat forum. You have time to compose messages and edit them before and after posting.
  quote