Java Developer
für Minecraft Server

Arbeite an Gameplay-Systemen auf einem etablierten Minecraft-Netzwerk.

Team aktuell vollständig besetzt!

MixelPixel in Zahlen

👥

208k+

Registrierte Spieler

📅

7+ Jahre

Serverbetrieb

⚙️

100+

Custom Items & Systeme

🎮

Aktive Community

Tausende Spielstunden

Deine Vorteile

💰 Faire Vergütung
603€ Minijob
⏱ Flexible Arbeitszeit
10 Stunden pro Woche
🌍 100% Remote
Arbeite von überall aus
🎮 Features für Tausende
Code, der gespielt wird!

Einige Beispiele für Systeme, die auf MixelPixel entwickelt wurden

🪙 Schwarzmarkt

Ein Auktionssystem, das jede Woche drei alte Event-Items freigibt. Gebote funktionieren serverübergreifend in Echtzeit. Realisiert mit Redis Pub/Sub und Redis-Locks.

Wiki öffnen →

📧 Mailsystem

Serverübergreifendes Mailsystem für Spieler. Nachrichten können auch an offline Spieler gesendet werden und kosten Ingame-Währung.

Wiki öffnen →

🪓 Kreative Axt

Ein Spezialitem für Builder, das viele Bauaktionen vereinfacht und beschleunigt. Technisch umgesetzt mit der FastAsyncWorldEdit API.

Wiki öffnen →

Deine Aufgaben

🧩 Gameplay-Features

Neue Spezialitems, Tools und Spielmechaniken für CityBuild.

⚙️ Server-Systeme

Weiterentwicklung bestehender Systeme wie Auktionshaus, Jobs oder Events.

💡 Community-Ideen

Umsetzung von Vorschlägen aus der Community oder dem Team - von kleinen QoL-Features bis zu neuen Spielmechaniken.

Wie wir Features bauen

@CommandDefinition(
        label = "info",
        usage = "(Player)",
        rank = PixelRank.SUPPORTER
)
public class InfoCommand extends PixelCommand<ExamplePlugin> {

    public InfoCommand(ExamplePlugin plugin) {
        super(plugin);
    }

    @Override
    public void onPlayerCommand(BukkitPixelPlayer player, String label, String[] args) {
        if (args.length != 1) {
            player.sendMessage(getPlayerUsage());
            return;
        }

        String targetName = args[0];

        PlayerHandler playerHandler = BukkitCoreLibrary.getPlayerHandler();
        BukkitPixelPlayer target = playerHandler.getPlayer(targetName);

        // online player → direct
        if (target != null) {
            sendInformation(player, target);
            return;
        }

        // offline player → async load
        DataLoader loader = DataLoaderBuilder.create(DataLoaderBuilderType.SINGLE_PLAYER)
                .name("InfoCommand")
                .addRequireds(BasePlayerData.class, RankPlayerData.class)
                .build();

        BukkitExecutor.runAsync(getPlugin(), () -> {
            try {
                BukkitPixelPlayer loaded = playerHandler.getPlayer(targetName, loader);

                BukkitExecutor.runSync(getPlugin(), () -> {
                    if (!player.isOnline()) return;

                    if (loaded == null) {
                        player.sendMessage(PLAYER_IS_NOT_REGISTERED);
                        return;
                    }

                    sendInformation(player, loaded);
                });

            } catch (Exception e) {
                player.sendMessage(DATA_LOAD_FAILED);
            }
        });
    }

    private void sendInformation(BukkitPixelPlayer player, BukkitPixelPlayer target) {
        BasePlayerData data = target.getData(BasePlayerData.class);
        player.sendMessage(target.getColoredName() + " first join: " + data.getFirstJoin());
    }
}
// basic custom item with persistent data
NamespacedKey usesKey = new NamespacedKey(plugin, "egg-uses");

ItemStack easterEgg = ItemBuilder.material(Material.EGG)
        .name("<rainbow>Easteregg</rainbow>")
        .lore(
                "<gray>A rare drop of the easter event</gray>",
                "<dark_gray>Limited uses</dark_gray>"
        )
        .glowing()
        .unbreakable(true)
        .persistentData(usesKey, PersistentDataType.INTEGER, 5)
        .maximumAmount(1)
        .build();


// enchantments (books vs normal items)
ItemStack protectionBook = ItemBuilder.enchantedBook(
        Enchantment.PROTECTION
).build();

ItemStack customEnchantItem = ItemBuilder.material(Material.DIAMOND)
        .enchantment(
                Map.of(
                        CoreEnchantment.SOUL_BOUND, 1,
                        Enchantment.FORTUNE, 10
                )
        )
        .build();


// player head (online player)
ItemStack playerHead = ItemBuilder.skull(player)
        .name(player.getName() + "'s head")
        .build();


// async skull loading (by any player name)
String playerName = "_Monty_";

BukkitExecutor.runAsync(plugin, () -> {
    try {
        SkullUtil.SkullData skullData = SkullUtil.getSkullData(playerName);

        BukkitExecutor.runSync(plugin, () -> {
            ItemStack customHead = ItemBuilder.material(Material.PLAYER_HEAD)
                    .anvilName(playerName + "'s head")
                    .skullTexture(skullData)
                    .build();

            player.sendMessage("Loaded custom head for " + playerName);
        });

    } catch (Exception ignored) {}
});
public class ExampleInventory extends PixelPrivateInventory<ExamplePlugin> {

    public ExampleInventory(ExamplePlugin plugin, Component title, InventoryType type, int size) {
        super(plugin, title, type, size);
    }

    @Override
    public void setItems() {
        setItem(0, createItem(Material.DIAMOND, "<aqua>Reward</aqua>"));
        setItem(1, createItem(Material.BARRIER, "<red>Close</red>"));
    }

    @Override
    public void onClickInventory(InventoryClickEvent event) {
        event.setCancelled(true);

        ItemStack item = event.getCurrentItem();
        if (item == null || item.getType() == Material.AIR) return;

        BukkitPixelPlayer player = getPlayer();

        if (event.getSlot() == 0) {
            player.addOrDropItem(
                    ItemBuilder.material(Material.DIAMOND)
                            .name("<green>Reward claimed</green>")
                            .build()
            );

            player.playGenericClickSound();
        }

        if (event.getSlot() == 1) {
            player.closeInventory();
        }
    }

    private ItemStack createItem(Material material, String name) {
        return ItemBuilder.material(material)
                .name(name)
                .glowing()
                .build();
    }
}

// opening
inventoryHandler.openInventory(
        plugin,
        player,
        ExampleInventory.class,
        "Example GUI",
        9
);
public class SendBroadcastPacket extends PixelJedisPacket {

    @Serial
    private static final long serialVersionUID = 0L;

    private final String gson;

    public SendBroadcastPacket(Component component) {
        this.gson = ComponentUtil.toGson(component);
    }

    public String getGson() {
        return gson;
    }
}

public class SendBroadcastListener extends PixelJedisPacketListener {

    @JedisPacketListenerDefinition
    public void onBroadcast(SendBroadcastPacket packet) {
        Component component = ComponentUtil.fromGson(packet.getGson());

        PlayerHandler playerHandler = BukkitCoreLibrary.getPlayerHandler();
        for (BukkitPixelPlayer player : playerHandler.getOnlinePlayers()) {
            player.sendMessage(component);
        }
    }
}

// packet sending
redisHandler.sendServerPacket(
        PixelServerCategory.CITY_BUILD,
        new SendBroadcastPacket(
                ComponentBuilder.create("Server-wide message")
                    .hover("Just a test message!")
                    .build()
        )
);
Consistent API Builder-based Cross-server ready

Tech Stack


Java
papermc
Paper API

Git / GitLab

Gradle

Redis

MariaDB

Dein Profil

🔞 Mindestalter 18
🤝 Teamfähigkeit
🧠 Problemlösungsfähigkeit
🎧 Kommunikationsfähigkeit
1+ Jahr Java Erfahrung
papermc Paper API Erfahrung
Git Erfahrung
SQL Kenntnisse

Erwartungen & Arbeitsweise

🧑‍💻

Eigenständiges Arbeiten

Du arbeitest weitgehend selbstständig an Features, triffst eigene technische Entscheidungen und bringst deine Ideen aktiv ein.

Git Workflow

Die Entwicklung erfolgt über Feature Branches und Merge Requests mit Code Reviews.

Unsere Core API ist ausführlich in einer MkDocs-Wiki dokumentiert. Weitere Systeme werden schrittweise ergänzt.

🧪

Lokale Entwicklungsumgebung

Mit unserer Docker-basierten Entwicklungs-umgebung (MPCKER) kannst du Änderungen lokal umsetzen und testen - vollständig unabhängig vom Livebetrieb.

💬

Direkte Kommunikation

Absprachen, Fragen und Feedback erfolgen unkompliziert und auf kurzen Wegen über Discord.

👨‍💻

Aktuell suchen wir keine Developer

Unser Entwicklerteam ist momentan vollständig besetzt. Daher nehmen wir derzeit keine neuen Bewerbungen an. Sobald wieder eine Stelle frei wird, kannst du dich hier bewerben.