Minestom Cellular Automata Server (Conway's Game of Life)

A Minestom server implementing Conway's Game of Life cellular automata with player interaction

java (17) 2025-12-28 AI Generated minestom cellular-automata game-of-life conway minecraft

Description

This snippet creates a Minestom server that simulates Conway’s Game of Life on a 50x50 grid. Players can interact with the simulation by placing and removing cells. The simulation runs in discrete steps rather than real-time.

Code

RAW
package com.example.minestom;import net.minestom.server.MinecraftServer;import net.minestom.server.coordinate.Pos;import net.minestom.server.entity.Player;import net.minestom.server.event.GlobalEventHandler;import net.minestom.server.event.player.PlayerBlockInteractEvent;import net.minestom.server.event.player.PlayerLoginEvent;import net.minestom.server.event.player.PlayerSpawnEvent;import net.minestom.server.instance.InstanceContainer;import net.minestom.server.instance.InstanceManager;import net.minestom.server.instance.block.Block;import net.minestom.server.timer.TaskSchedule;import java.util.HashSet;import java.util.Set;public class GameOfLifeServer {        private static final int GRID_SIZE = 50;    private static final Block ALIVE_BLOCK = Block.WHITE_WOOL;    private static final Block DEAD_BLOCK = Block.AIR;    private static final Pos GRID_START = new Pos(0, 40, 0);        private final boolean[][] grid = new boolean[GRID_SIZE][GRID_SIZE];    private final Set<Player> players = new HashSet<>();    private InstanceContainer instance;    private boolean isRunning = false;        public static void main(String[] args) {        MinecraftServer minecraftServer = MinecraftServer.init();        GameOfLifeServer server = new GameOfLifeServer();                GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();        globalEventHandler.addListener(PlayerLoginEvent.class, server::onPlayerLogin);        globalEventHandler.addListener(PlayerSpawnEvent.class, server::onPlayerSpawn);        globalEventHandler.addListener(PlayerBlockInteractEvent.class, server::onBlockInteract);                minecraftServer.start("0.0.0.0", 25565);    }        private void onPlayerLogin(PlayerLoginEvent event) {        Player player = event.getPlayer();        players.add(player);        player.sendMessage("§aWelcome to Conway's Game of Life!");        player.sendMessage("§eRight-click blocks to toggle cells. Type /start to begin simulation.");    }        private void onPlayerSpawn(PlayerSpawnEvent event) {        if (instance == null) {            InstanceManager instanceManager = MinecraftServer.getInstanceManager();            instance = instanceManager.createInstanceContainer();            instance.setGenerator(unit -> unit.modifier().fillHeight(0, 40, Block.GRASS_BLOCK));            initializeGrid();        }        event.getPlayer().setInstance(instance, GRID_START.add(0, 5, GRID_SIZE/2));    }        private void onBlockInteract(PlayerBlockInteractEvent event) {        if (isRunning) {            event.getPlayer().sendMessage("§cCannot modify grid while simulation is running!");            return;        }                Pos blockPos = event.getBlockPosition();        int x = blockPos.blockX() - GRID_START.blockX();        int z = blockPos.blockZ() - GRID_START.blockZ();                if (x >= 0 && x < GRID_SIZE && z >= 0 && z < GRID_SIZE) {            grid[x][z] = !grid[x][z];            updateBlock(x, z);        }    }        private void initializeGrid() {        // Initialize with some gliders for demonstration        // Glider 1        grid[1][2] = true;        grid[2][3] = true;        grid[3][1] = true;        grid[3][2] = true;        grid[3][3] = true;                // Glider 2        grid[10][12] = true;        grid[11][13] = true;        grid[12][11] = true;        grid[12][12] = true;        grid[12][13] = true;                // Update all blocks        for (int x = 0; x < GRID_SIZE; x++) {            for (int z = 0; z < GRID_SIZE; z++) {                updateBlock(x, z);            }        }    }        private void updateBlock(int x, int z) {        Pos pos = GRID_START.add(x, 0, z);        instance.setBlock(pos, grid[x][z] ? ALIVE_BLOCK : DEAD_BLOCK);    }        public void startSimulation() {        if (isRunning) return;        isRunning = true;                MinecraftServer.getSchedulerManager().scheduleTask(() -> {            if (!isRunning) return;                        boolean[][] newGrid = new boolean[GRID_SIZE][GRID_SIZE];                        for (int x = 0; x < GRID_SIZE; x++) {                for (int z = 0; z < GRID_SIZE; z++) {                    int neighbors = countNeighbors(x, z);                                        if (grid[x][z]) {                        // Any live cell with fewer than two live neighbors dies (underpopulation)                        // Any live cell with more than three live neighbors dies (overpopulation)                        newGrid[x][z] = neighbors == 2 || neighbors == 3;                    } else {                        // Any dead cell with exactly three live neighbors becomes a live cell (reproduction)                        newGrid[x][z] = neighbors == 3;                    }                }            }                        // Update grid and blocks            for (int x = 0; x < GRID_SIZE; x++) {                for (int z = 0; z < GRID_SIZE; z++) {                    if (grid[x][z] != newGrid[x][z]) {                        grid[x][z] = newGrid[x][z];                        updateBlock(x, z);                    }                }            }                        // Broadcast generation count            players.forEach(p -> p.sendMessage("§7Generation completed"));        }, TaskSchedule.tick(10), TaskSchedule.tick(10));    }        public void stopSimulation() {        isRunning = false;        players.forEach(p -> p.sendMessage("§aSimulation stopped. You can now modify the grid."));    }        private int countNeighbors(int x, int z) {        int count = 0;        for (int dx = -1; dx <= 1; dx++) {            for (int dz = -1; dz <= 1; dz++) {                if (dx == 0 && dz == 0) continue;                                int nx = x + dx;                int nz = z + dz;                                if (nx >= 0 && nx < GRID_SIZE && nz >= 0 && nz < GRID_SIZE && grid[nx][nz]) {                    count++;                }            }        }        return count;    }}
RAW
package com.example.minestom;import net.minestom.server.MinecraftServer;import net.minestom.server.command.CommandSender;import net.minestom.server.command.builder.Command;import net.minestom.server.command.builder.arguments.ArgumentType;public class CommandManager {        public static void registerCommands(GameOfLifeServer server) {        Command startCommand = new Command("start");        startCommand.setDefaultExecutor((sender, context) -> {            if (!(sender instanceof CommandSender)) return;            server.startSimulation();            sender.sendMessage("§aStarted Game of Life simulation!");        });                Command stopCommand = new Command("stop");        stopCommand.setDefaultExecutor((sender, context) -> {            if (!(sender instanceof CommandSender)) return;            server.stopSimulation();            sender.sendMessage("§cStopped Game of Life simulation!");        });                Command clearCommand = new Command("clear");        clearCommand.setDefaultExecutor((sender, context) -> {            if (!(sender instanceof CommandSender)) return;            if (server.isRunning()) {                sender.sendMessage("§cCannot clear while simulation is running!");                return;            }                        for (int x = 0; x < GameOfLifeServer.GRID_SIZE; x++) {                for (int z = 0; z < GameOfLifeServer.GRID_SIZE; z++) {                    server.grid[x][z] = false;                    server.updateBlock(x, z);                }            }            sender.sendMessage("§aGrid cleared!");        });                MinecraftServer.getCommandManager().register(startCommand);        MinecraftServer.getCommandManager().register(stopCommand);        MinecraftServer.getCommandManager().register(clearCommand);    }}
RAW
package com.example.minestom;public class Main {    public static void main(String[] args) {        GameOfLifeServer server = new GameOfLifeServer();        CommandManager.registerCommands(server);        GameOfLifeServer.main(args);    }}

Comments

No comments yet. Be the first to comment!