
VillageAI
Intelligent village defense system. Villages centered on bells automatically detect nearby villagers. Friendly players gain reputation by trading. Hostile players lose reputation by attacking villagers. When hostile players are nearby reputation drops belo
3.0.0
Compatibility
Changes
[3.0.0] - 2026-04-12 โ Major Update: Full Fix + New Features
๐ Bug Fixes
Critical
- Real item exchange in trades โ
executeTrade()previously only logged the trade without moving any items. Both the GUI and text command now properly remove emeralds from the player and give items (or vice versa). - Quests never completed โ After accepting a quest there was no mechanism to check for completion. A check is now triggered automatically when the player interacts with a villager. Added
QuestStatus.IN_PROGRESSto prevent two players accepting the same quest. - VillageValidator was dead code โ
validateVillageData()searched for a"villages"section that was never written. It now correctly iterates root-level keys (village-0,village-1, โฆ). - No periodic save โ
saveVillages()was defined but never called. An autosave timer is now scheduled inonEnable()(default every 5 minutes), preventing data loss on server crash.
High
- NPE in
applyMoraleBuffsโcenter.getWorld()can return null when a world is unloaded. A null-check is now applied consistently (matching the pattern already used inhasHostilePlayerNearby). - Memory leak in
interactCooldownsโ TheHashMapaccumulated entries indefinitely. APlayerQuitEventlistener now removes entries when players disconnect. - Two unsynchronized reputation systems โ Defense and economy reputation were completely separate. Completing a quest now increments both, keeping them reasonably in sync.
- Multiple players could accept the same quest โ No status guard existed. Quests now move to
IN_PROGRESSon accept; only the assigned player can complete or fail them. QuestGeneratorused world UUID instead of village UUID โ Every village in the same world shared the same questvillageId. Fixed: UUID is now derived from the village's coordinate-based ID string viaUUID.nameUUIDFromBytes.
Medium
- Morale buffs never applied with default config โ Default
speed_amp: 0combined with a> 0guard made the feature permanently inactive. Default changed tospeed_amp: 1and the guard removed. TradeHistory.toString()printed quantity instead of datetime โ The format argument wasInteger.valueOf(quantity)instead ofgetDateTime().- Morale buff radius hardcoded to 32 blocks โ Now reads
village.check_radiusfrom config for consistency. - Economy state lost on restart โ
VillageSnapshotnow persists theUpgradeManagerstate in addition to members, golems and reputation.
๐ New Features
โ๏ธ Wave-Based Raid System (RaidManager)
- Raids consist of up to 5 escalating waves: Pillager โ Vindicator โ Evoker โ Ravager + Witch
- Mobs spawn in a ring around the village bell at random angles
- Waves advance automatically when all spawned mobs are dead
- Players nearby receive emerald rewards and +20 reputation on full clear
- Server announces raid start, each wave, and victory/defeat to nearby players
- Admin commands:
/villageraid start | stop | status
๐ฐ Village Upgrade System (UpgradeManager)
- Four infrastructure upgrades: Wall, Watchtower, Granary, Forge
- Players contribute materials directly from their inventory via
/vtrade upgrade <name> - Contribution progress is tracked per-player and shared across all contributors
- Upgrade state persists across server restarts via
VillageSnapshot - Watchtower increases detection radius; Forge reduces all trade prices by 10%; Granary generates extra quests; Wall reduces golem damage taken
๐ Inventory Trade GUI (TradeGui)
- 54-slot chest GUI opened via
/vtrade gui - Each active trade offer is displayed as a clickable item with price and reputation discount info
- Clicking an offer executes the full trade (item check โ remove payment โ give items) immediately
- Upgrade status and player reputation displayed as reference icons
- GUI refreshes after each trade
๐ Night Cycle Mode
- At night (world time 12300โ23850) the village transitions to
NIGHTstate and closes all doors automatically - Returns to
SAFEat dawn without spawning golems
๐ก PlaceholderAPI Integration
- Registers a
villageaiexpansion when PlaceholderAPI is detected at startup (soft-depend, no hard requirement) - Provides four placeholders:
%villageai_rep%,%villageai_state%,%villageai_nearest%,%villageai_upgrades%
๐ง Improved Commands
/villageai infoโ detailed stats for the nearest village (state, members, golems, upgrades, reputation)/villageai listโ lists all loaded villages with state and member count/villageai saveโ forces an immediate synchronous save/vtrade upgrade [name]โ shows progress toward each upgrade or contributes materials/vtrade acceptnow uses and displays full UUIDs (no more truncation bug)VillageStateextended withNIGHTandRAIDstates
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:QkbM4VXn:kfyzjOZT"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:QkbM4VXn:kfyzjOZT"
}
