🎮 Akincraft Modding Guide

Learn how to create your own custom features and content

Getting Started with Modding

Before You Start

Development Workflow

💡 Pro Tip: Follow this workflow for smooth development:
  1. Create a new branch: git checkout -b feature/my-custom-feature
  2. Make your changes to the source code
  3. Build and test: ./gradlew run (Java) or cmake --build . (C++)
  4. Commit frequently: git add . and git commit -m "Description"
  5. Push to remote when ready

Project Setup

cd akincraft
# For Java development
cd java
./gradlew build
./gradlew run

# For C++ development
cd cpp
mkdir -p build && cd build
cmake ..
cmake --build .
./akincraft_cpp

Popular Modding Projects

1️⃣ Add a New Block Type

Difficulty: Easy | Time: 15 minutes

What you'll learn: How to extend the block system and add custom blocks to your world
Steps:
  1. Define your block:
    // In BlockType.h (C++) or BlockType enum (Java)
    public enum BlockType {
        // ... existing types
        AMETHYST(50),
        CRYSTAL(51);
    }
  2. Set block properties:
    // In your rendering/block manager code
    BlockProperties props = new BlockProperties();
    props.hardness = 1.5f;
    props.isOpaque = true;
    props.color = new Color(0x9966FF);  // Purple
    props.isBreakable = true;
  3. Add to world generation:
    // In terrain generation code
    if (y >= 20 && y <= 40) {
        if (random.nextFloat() < 0.02f) {
            chunk.setBlock(x, y, z, BlockType.AMETHYST);
        }
    }
  4. Build and run the game - your new block should appear!
💡 Tips: Start with a unique color so you can easily spot your block. Use hardness values between 0.5 and 5.0 for most ore blocks.

2️⃣ Create a Custom Mob

Difficulty: Medium | Time: 30 minutes

What you'll learn: Entity system and simple AI behavior
Code Template:
// Create a new file: src/CustomMob.java
public class Slime extends Entity {
    private float bounceTimer = 0;
    private float bounceSpeed = 0.5f;
    
    public Slime(Vector3f position) {
        super(position);
        this.health = 20;
        this.speed = 0.1f;
    }
    
    @Override
    public void update(float deltaTime) {
        // Bouncing behavior
        bounceTimer += deltaTime;
        if (bounceTimer > 1.5f) {
            this.velocity.y = bounceSpeed;
            bounceTimer = 0;
        }
        
        // Horizontal movement (random wander)
        if (bounceTimer % 0.5f < deltaTime) {
            this.velocity.x = (float) Math.random() * 0.2f - 0.1f;
            this.velocity.z = (float) Math.random() * 0.2f - 0.1f;
        }
        
        // Apply gravity
        Physics.applyGravity(this, deltaTime);
        
        // Update position
        position = position.add(velocity);
    }
    
    @Override
    public void render() {
        // Render your slime here
    }
}
Register your mob in the world:
// In EntityManager.java or World.java
public void spawnSlimes(World world) {
    for (int i = 0; i < 20; i++) {
        Vector3f randomPos = world.getRandomGroundPosition();
        world.entityManager.addEntity(new Slime(randomPos));
    }
}

3️⃣ Design a New Biome

Difficulty: Medium | Time: 45 minutes

What you'll learn: Procedural generation and biome systems
Create your biome class:
// Create: src/CrimsonBiome.java
public class CrimsonBiome extends Biome {
    public CrimsonBiome() {
        this.name = "Crimson Wastes";
        this.temperature = 1.5f;      // Very hot
        this.humidity = 0.0f;         // Very dry
        this.baseHeight = 70;
        
        // Crimson color palette
        this.skyColor = new Color(0xFF4444);
        this.foliageColor = new Color(0xCC0000);
        
        // Blocks found in this biome
        this.blockPalette = new BlockType[] {
            BlockType.STONE,
            BlockType.DIRT,
            BlockType.SAND,
            BlockType.LAVA,
            BlockType.CRIMSON_WOOD,  // Custom block
        };
    }
    
    @Override
    public void generateTerrain(Chunk chunk, NoiseGenerator noise) {
        for (int x = 0; x < 16; x++) {
            for (int z = 0; z < 16; z++) {
                // Terrain is more rocky and barren
                int height = (int) (noise.noise(x * 0.1f, z * 0.1f) * 20 + 70);
                
                for (int y = 0; y < height; y++) {
                    if (y < height - 2) {
                        chunk.setBlock(x, y, z, BlockType.STONE);
                    } else {
                        chunk.setBlock(x, y, z, BlockType.SAND);
                    }
                }
            }
        }
    }
}
Register in biome manager:
BiomeManager biomes = new BiomeManager();
biomes.register(new CrimsonBiome(), 0.8f, 0.0f);  // temperature, humidity

4️⃣ Implement a Crafting Recipe

Difficulty: Easy | Time: 10 minutes

What you'll learn: Inventory and crafting systems
// Add this to your crafting recipe list
CraftingRecipe amethystSword = new CraftingRecipe(
    new ItemStack[][] {
        { new ItemStack(ItemType.AMETHYST), empty, empty },
        { new ItemStack(ItemType.AMETHYST), empty, empty },
        { new ItemStack(ItemType.STICK), empty, empty }
    },
    new ItemStack(ItemType.AMETHYST_SWORD, 1)
);

// Register the recipe
craftingManager.registerRecipe(amethystSword);

// Now players can craft this by arranging items in this pattern

5️⃣ Add Weather Effects

Difficulty: Hard | Time: 1 hour

What you'll learn: Game systems and visual effects
// Create: src/WeatherSystem.java
public class WeatherSystem {
    public enum WeatherType {
        CLEAR, RAIN, THUNDERSTORM, SANDSTORM
    }
    
    private WeatherType currentWeather = WeatherType.CLEAR;
    private float weatherDuration = 0;
    private float weatherTimer = 0;
    
    public void update(float deltaTime) {
        weatherTimer += deltaTime;
        
        if (weatherTimer >= weatherDuration) {
            changeWeather();
            weatherTimer = 0;
        }
    }
    
    private void changeWeather() {
        WeatherType[] types = WeatherType.values();
        currentWeather = types[(int)(Math.random() * types.length)];
        weatherDuration = 60 + Math.random() * 300;  // 1-5 minutes
        
        applyWeatherEffects();
    }
    
    private void applyWeatherEffects() {
        switch(currentWeather) {
            case RAIN:
                // Add rain particles
                // Reduce visibility
                // Spawn water
                break;
            case THUNDERSTORM:
                // Add lightning
                // Add thunder sounds
                // Spawn mobs
                break;
            case SANDSTORM:
                // Add sand particles
                // Reduce visibility more
                // Damage player over time
                break;
        }
    }
}