@Plugin(id = "my-plugin")
class MyPlugin(
val server: Server,
val logger: Logger
) {
@Listener
fun onStart(event: ServerStartEvent) {
logger.info("Hello from my plugin! Running on ${server.platform.name} version ${server.platform.version}!")
}
}
Krypton is Minecraft server software, just like Paper or Sponge, but unlike both of those, it's written entirely from scratch, and doesn't depend on vanilla Minecraft.
Krypton's API is relatively new. Our aim is to make our API simple to understand, so it is easy to learn, but powerful enough to achieve complex tasks. We also provide ways to manipulate many vanilla mechanics, and many events to control what happens on the server.
In addition, though not directly encouraged, it is possible, and in fact, very easy, to depend directly on the implementation. No longer do you have to setup Paperweight or ForgeGradle or remap JARs, it is as simple as adding the server as a dependency.
Krypton is still in development, so many features are missing and many APIs may not work as intended. If a feature is broken, please report this to us.
val world = // Some world
var rail = Blocks.RAIL
// setProperty will return a BlockState with the desired property, which will always already exist
rail = rail.setProperty(Properties.RAIL_SHAPE, RailShape.ASCENDING_NORTH)
world.setBlock(3, 4, 5, rail)
var cactus = Blocks.CACTUS
// Set the age of the cactus to 5 (AGE_15 supports 0-15)
cactus = cactus.setProperty(Properties.AGE_15, 5)
world.setBlock(3, 4, 5, cactus)
// Set the hopper to enabled, making it able to move items.
val hopper = Blocks.HOPPER.setProperty(Properties.ENABLED, true)
world.setBlock(3, 4, 5, hopper)
Krypton's block system is modelled after vanilla's system, using key-value properties to differentiate between states. This system can easily be adapted to custom properties, or even custom blocks, something that is not currently possible, but may be considered in the future.
In addition, all Block and BlockState objects are immutable and constant, so they can safely be passed around, reused, and stored without worrying about them changing.
val brigadier = literalCommand("helloworld") {
executes { context ->
context.source.sendMessage(Component.text("Hello World!"))
1
}
}
commandManager.register(BrigadierCommand.of(brigadier), CommandMeta.builder("helloworld").alias("worldhello").build())
class Simple : SimpleCommand {
override fun execute(sender: Sender, args: Array<String>) {
sender.sendMessage(Component.text("Hello World!"))
}
}
commandManager.register(Simple(), CommandMeta.builder("helloworld").alias("worldhello").build())
class Raw : RawCommand {
override fun execute(sender: Sender, args: String) {
sender.sendMessage(Component.text("Hello World!"))
}
}
commandManager.register(Raw(), CommandMeta.builder("helloworld").alias("worldhello").build())
Commands are the way that all clients send instructions to servers. Krypton's command API is designed with different types of commands in mind, modelled after different systems.
The BrigadierCommand is designed to allow you to make the most use of 1.13's Brigadier command system, which has argument passing, rich highlighting and tooltips, and many other features. In addition, Krypton has a built-in DSL for working with the Brigadier API, which makes this easier to use in Kotlin.
The SimpleCommand is designed to be familiar to Bukkit developers, and provides a simple string array with the arguments contained within it.
The RawCommand is designed for custom frameworks, to allow them to do their own parsing.
val world = // Some world
val player = // Some player
val location = player.position.asVec3d()
val creeper = world.spawnEntity(EntityTypes.CREEPER, location)
creeper.explosionRadius = 4.0 // Radius, in blocks, of the explosion caused by the creeper
creeper.fuse = 100 // Time, in ticks, before the creeper will explode after it is ignited
creeper.ignite() // Starts fuse timer, exploding after fuse ticks passed
val eye = world.spawnEntity(EntityTypes.EYE_OF_ENDER, location)
eye.life = 80 // Make the eye last for 80 ticks
eye.shouldBreak = true // Make the eye break when its life expires
eye.signalTo(location.add(5.0, 8.0, 7.0)) // Make the eye travel towards the signalled point
Entities are an integral part of Minecraft. They are used not only for representing mobs, such as zombies, skeletons, pigs, cows, sheep, and more, but also for projectiles like arrows, fireballs, tridents, wither skulls, and even fishing bobbers.
Krypton's entity API is designed to support and allow manipulation of many vanilla features. Almost all properties that can be modified are modifiable in the API.
val player = // Some player
val book = ItemStack.builder()
.type(ItemTypes.WRITTEN_BOOK)
.amount(3)
.meta(WrittenBookMeta::class.java) {
title(Component.text("Krypton"))
author(Component.text("BomBardyGamer"))
}
player.inventory.setHeldItem(Hand.MAIN, item)
val head = item(ItemTypes.PLAYER_HEAD, 1) {
meta(PlayerHeadMeta::class.java) {
owner(GameProfile.of(UUID.fromString("9b967160-68ba-4992-863e-60b15d00ce38"), "BomBardyGamer"))
}
}
player.inventory.setItem(0, head)
Items in Krypton are immutable, which means they can be safely and easily shared across multiple inventories. No longer do you have to worry about cloning or risking vanilla updating an item that you thought was safe to share.
We also have a powerful item metadata system that provides all the item data in a very accessible way, while internally maintaining a simple data-driven representation, keeping them lightweight and easy to use, and storing only what you need.
If you're interested in the project, and want to keep up with its development, come join the Discord! Questions are often asked about design choices and ideas about what to support and more on there, and we can also help you get started if you are stuck.
You can also download the latest JAR from our downloads page, and it will mostly work out of the box. However, Krypton does not currently have any world generation, and as such, you will need to generate and provide your own world from vanilla, and modify the world name in the configuration with the name of the world folder, so that Krypton knows what to load.
And finally, we would like to say thank you for being interested in this project. People like you are the main drive, and really help to keep it alive.