Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: 17
java-version: 21
- name: Cache SonarCloud packages
uses: actions/cache@v3
with:
Expand Down
134 changes: 134 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

CaveBlock is a BentoBox GameMode Addon for Minecraft (Bukkit/Spigot). It creates underground cave-based survival worlds where players mine, explore, and build within a solid stone environment. Players get an island (cave) carved out of solid rock rather than placed in an ocean.

## Build Commands

```bash
mvn clean package # Build the plugin JAR
mvn test # Run tests (surefire)
mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=BentoBoxWorld_CaveBlock # CI build with SonarCloud
```

Java 21 is required. The output JAR goes to `target/`.

## Architecture

**Entry point chain:** `CaveBlockPladdon` (Bukkit plugin entry) → `CaveBlock` (BentoBox `GameModeAddon`)

**Key components:**
- `CaveBlock.java` — Main addon lifecycle (`onLoad`, `onEnable`, `createWorlds`). Creates 3 world generators (normal, nether, end) and registers flags/listeners.
- `Settings.java` — 50+ annotated config fields implementing BentoBox's `WorldSettings`. Maps to `config.yml`.
- `generators/ChunkGeneratorWorld.java` — Core chunk generator. Fills world with stone/netherrack/endstone, supports two modes: legacy (custom ore placement) and new (vanilla-like with `NewMaterialPopulator`).
- `generators/populators/` — `MaterialPopulator` (legacy ore placement), `NewMaterialPopulator` (vanilla-style), `EntitiesPopulator` (mob spawning), `FlatBiomeProvider` (biome distribution).
Comment thread
tastybento marked this conversation as resolved.
Outdated
- `listeners/CustomHeightLimitations.java` — Prevents players from going above the configured world depth. Respects `SKY_WALKER_FLAG` and creative/op bypass.

**BentoBox framework patterns to follow:**
- Addons use `GameModeAddon` lifecycle, not Bukkit's `JavaPlugin` directly
- Configuration uses BentoBox's annotation-based `@ConfigEntry` and `@ConfigComment` system
- Commands extend BentoBox's `CompositeCommand` hierarchy
- Flags (feature toggles) are created via `Flag.Builder` and registered in `onEnable()`
- Player-facing strings come from locale files in `src/main/resources/locales/`

## Key Dependencies (provided scope — server supplies at runtime)

- `paper-api` 1.21.11 — Paper API
- `bentobox` 2.7.1-SNAPSHOT — BentoBox framework
Comment thread
tastybento marked this conversation as resolved.
Outdated

## Branches

- `master` — release branch (removes `-SNAPSHOT` suffix via Maven profile)
- `develop` — development branch

## Dependency Source Lookup

When you need to inspect source code for a dependency (e.g., BentoBox, addons):

1. **Check local Maven repo first**: `~/.m2/repository/` — sources jars are named `*-sources.jar`
2. **Check the workspace**: Look for sibling directories or Git submodules that may contain the dependency as a local project (e.g., `../bentoBox`, `../addon-*`)
3. **Check Maven local cache for already-extracted sources** before downloading anything
4. Only download a jar or fetch from the internet if the above steps yield nothing useful

Prefer reading `.java` source files directly from a local Git clone over decompiling or extracting a jar.

In general, the latest version of BentoBox should be targeted.

## Project Layout

Related projects are checked out as siblings under `~/git/`:

**Core:**
- `bentobox/` — core BentoBox framework

**Game modes:**
- `addon-acidisland/` — AcidIsland game mode
- `addon-bskyblock/` — BSkyBlock game mode
- `Boxed/` — Boxed game mode (expandable box area)
- `CaveBlock/` — CaveBlock game mode
- `OneBlock/` — AOneBlock game mode
- `SkyGrid/` — SkyGrid game mode
- `RaftMode/` — Raft survival game mode
- `StrangerRealms/` — StrangerRealms game mode
- `Brix/` — plot game mode
- `parkour/` — Parkour game mode
- `poseidon/` — Poseidon game mode
- `gg/` — gg game mode

**Addons:**
- `addon-level/` — island level calculation
- `addon-challenges/` — challenges system
- `addon-welcomewarpsigns/` — warp signs
- `addon-limits/` — block/entity limits
- `addon-invSwitcher/` / `invSwitcher/` — inventory switcher
- `addon-biomes/` / `Biomes/` — biomes management
- `Bank/` — island bank
- `Border/` — world border for islands
- `Chat/` — island chat
- `CheckMeOut/` — island submission/voting
- `ControlPanel/` — game mode control panel
- `Converter/` — ASkyBlock to BSkyBlock converter
- `DimensionalTrees/` — dimension-specific trees
- `discordwebhook/` — Discord integration
- `Downloads/` — BentoBox downloads site
- `DragonFights/` — per-island ender dragon fights
- `ExtraMobs/` — additional mob spawning rules
- `FarmersDance/` — twerking crop growth
- `GravityFlux/` — gravity addon
- `Greenhouses-addon/` — greenhouse biomes
- `IslandFly/` — island flight permission
- `IslandRankup/` — island rankup system
- `Likes/` — island likes/dislikes
- `Limits/` — block/entity limits
- `lost-sheep/` — lost sheep adventure
- `MagicCobblestoneGenerator/` — custom cobblestone generator
- `PortalStart/` — portal-based island start
- `pp/` — pp addon
- `Regionerator/` — region management
- `Residence/` — residence addon
- `TopBlock/` — top ten for OneBlock
- `TwerkingForTrees/` — twerking tree growth
- `Upgrades/` — island upgrades (Vault)
- `Visit/` — island visiting
- `weblink/` — web link addon
- `CrowdBound/` — CrowdBound addon

**Data packs:**
- `BoxedDataPack/` — advancement datapack for Boxed

**Documentation & tools:**
- `docs/` — main documentation site
- `docs-chinese/` — Chinese documentation
- `docs-french/` — French documentation
- `BentoBoxWorld.github.io/` — GitHub Pages site
- `website/` — website
- `translation-tool/` — translation tool

Check these for source before any network fetch.

## Key Dependencies (source locations)

- `world.bentobox:bentobox` → `~/git/bentobox/src/`
109 changes: 90 additions & 19 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,18 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
<java.version>21</java.version>
<!-- Non-minecraft related dependencies -->
<junit.version>5.10.2</junit.version>
<mockito.version>5.11.0</mockito.version>
<mock-bukkit.version>v1.21-SNAPSHOT</mock-bukkit.version>
<!-- More visible way how to change dependency versions -->
<spigot.version>1.21.3-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>2.7.1-SNAPSHOT</bentobox.version>
<paper.version>1.21.11-R0.1-SNAPSHOT</paper.version>
<bentobox.version>3.14.1-SNAPSHOT</bentobox.version>
<!-- Revision variable removes warning about dynamic version -->
<revision>${build.version}-SNAPSHOT</revision>
<!-- This allows to change between versions and snapshots. -->
<build.version>1.20.1</build.version>
<build.version>1.21.0</build.version>
<build.number>-LOCAL</build.number>
<sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
Expand Down Expand Up @@ -94,8 +98,8 @@

<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>bentoboxworld</id>
Expand All @@ -105,13 +109,18 @@
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url>
</repository>
<!-- MockBukkit snapshots -->
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>${spigot.version}</version>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>${paper.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand All @@ -120,6 +129,39 @@
<version>${bentobox.version}</version>
<scope>provided</scope>
</dependency>
<!-- MockBukkit -->
<dependency>
<groupId>com.github.MockBukkit</groupId>
<artifactId>MockBukkit</artifactId>
<version>${mock-bukkit.version}</version>
<scope>test</scope>
</dependency>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -153,12 +195,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
<version>3.4.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<version>3.3.1</version>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>blu</nonFilteredFileExtension>
Expand All @@ -168,25 +210,54 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<version>3.13.0</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<version>3.5.2</version>
<configuration>
<includes>
<include>**/*Test.java</include>
<include>**/*Test?.java</include>
<include>**/*Test??.java</include>
</includes>
<argLine>
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.math=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.util.stream=ALL-UNNAMED
--add-opens java.base/java.text=ALL-UNNAMED
--add-opens java.base/java.util.regex=ALL-UNNAMED
--add-opens java.base/java.nio.channels.spi=ALL-UNNAMED
--add-opens java.base/sun.nio.ch=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
--add-opens java.base/sun.nio.fs=ALL-UNNAMED
--add-opens java.base/sun.nio.cs=ALL-UNNAMED
--add-opens java.base/java.nio.file=ALL-UNNAMED
--add-opens java.base/java.nio.charset=ALL-UNNAMED
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
--add-opens java.logging/java.util.logging=ALL-UNNAMED
--add-opens java.base/java.lang.ref=ALL-UNNAMED
--add-opens java.base/java.util.jar=ALL-UNNAMED
--add-opens java.base/java.util.zip=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<version>3.4.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.0</version>
<version>3.11.2</version>
<configuration>
<failOnError>false</failOnError>
<additionalJOption>-Xdoclint:none</additionalJOption>
Expand All @@ -206,7 +277,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
Expand All @@ -219,17 +290,17 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<version>3.1.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<version>3.1.3</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.10</version>
<version>0.8.12</version>
<configuration>
<append>true</append>
<excludes>
Expand Down
16 changes: 9 additions & 7 deletions src/main/java/world/bentobox/caveblock/CaveBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.WorldType;
import org.bukkit.entity.SpawnCategory;
import org.bukkit.generator.ChunkGenerator;
import org.eclipse.jdt.annotation.NonNull;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.commands.admin.DefaultAdminCommand;
import world.bentobox.bentobox.api.commands.island.DefaultPlayerCommand;
Expand Down Expand Up @@ -144,7 +146,7 @@ public void createWorlds()
// Set spawn rates
setSpawnRates(islandWorld);


BentoBox.getInstance().logDebug(islandWorld.getWorldFolder());
// Make the nether if it does not exist
if (this.settings.isNetherGenerate())
{
Expand Down Expand Up @@ -201,22 +203,22 @@ public void createWorlds()
private void setSpawnRates(World w) {
if (w != null) {
if (getSettings().getSpawnLimitMonsters() > 0) {
w.setMonsterSpawnLimit(getSettings().getSpawnLimitMonsters());
w.setSpawnLimit(SpawnCategory.MONSTER, getSettings().getSpawnLimitMonsters());
}
if (getSettings().getSpawnLimitAmbient() > 0) {
w.setAmbientSpawnLimit(getSettings().getSpawnLimitAmbient());
w.setSpawnLimit(SpawnCategory.AMBIENT, getSettings().getSpawnLimitAmbient());
}
if (getSettings().getSpawnLimitAnimals() > 0) {
w.setAnimalSpawnLimit(getSettings().getSpawnLimitAnimals());
w.setSpawnLimit(SpawnCategory.ANIMAL,getSettings().getSpawnLimitAnimals());
}
if (getSettings().getSpawnLimitWaterAnimals() > 0) {
w.setWaterAnimalSpawnLimit(getSettings().getSpawnLimitWaterAnimals());
w.setSpawnLimit(SpawnCategory.WATER_ANIMAL, getSettings().getSpawnLimitWaterAnimals());
}
if (getSettings().getTicksPerAnimalSpawns() > 0) {
w.setTicksPerAnimalSpawns(getSettings().getTicksPerAnimalSpawns());
w.setTicksPerSpawns(SpawnCategory.ANIMAL, getSettings().getTicksPerAnimalSpawns());
}
if (getSettings().getTicksPerMonsterSpawns() > 0) {
w.setTicksPerMonsterSpawns(getSettings().getTicksPerMonsterSpawns());
w.setTicksPerSpawns(SpawnCategory.MONSTER, getSettings().getTicksPerMonsterSpawns());
}
}

Expand Down
Loading
Loading