Files
livingWorld/Docs/Living World Mod - Studio Development Plan.md
2026-06-07 12:18:45 +01:00

125 KiB
Raw Permalink Blame History

Living World Mod — Studio Development Plan
Volume 1: Core Architecture & Simulation Engine

Document status: Working draft
Purpose: Build the real technical foundation for an Eco-style living Minecraft world mod.

1. What This Project Is

This mod is not a normal content mod. It is a simulation layer that sits above Minecraft and gives the world memory, momentum, and consequences. The goal is to make the server feel alive even when players are not actively touching every part of it.

Minecraft normally changes because a player loads an area, a random tick fires, an entity AI runs, or a vanilla system updates. This project adds a higher-level world simulation that tracks regions, ecology, settlements, factions, trade, roads, climate, resources, danger, and historical events.

The first volume exists to define the engine layer. No ecology, settlements, factions, wars, roads, or economy systems should be built until this foundation is working.

2. Non-Negotiable Design Rules

Rule 1: The world must continue without players nearby.

The mod must not depend on loaded chunks for its main simulation. Loaded chunks are only used when the simulation needs to visibly apply changes to terrain, structures, roads, or entities. Most world evolution must happen in abstract region data.

Rule 2: Simulate regions, not chunks.

Chunks are too small and too numerous. The simulation uses regions as its main unit of world state. A region starts as 8 by 8 chunks, equal to 128 by 128 blocks. This size is large enough to reduce processing cost and small enough to let different parts of the world evolve differently.

Rule 3: Everything must be modular.

Ecology, settlements, factions, roads, economy, climate, wildlife, history, and events must be separate modules. A module can depend on the core API, services, region data, and events. A module must not directly depend on another gameplay module.

Rule 4: Save data must be versioned from day one.

Every saved object must include a schema version. No system is allowed to save unversioned data. Migrations must be part of the architecture before the first playable release.

Rule 5: Debugging tools are not optional.

A simulation this large is impossible to balance by guesswork. The mod must include commands to inspect regions, force ticks, simulate time, show history, dump save data, and profile module cost.

3. Target Mod Loader and Version Strategy

Primary target: NeoForge or Forge for modern Minecraft.

The project should avoid hard-coding version-specific logic into simulation classes. Minecraft-facing adapters should live in dedicated packages so the simulation core can survive porting between Minecraft versions.

Recommended approach:

- Core simulation code should be plain Java where possible.
- Minecraft integration should be isolated.
- Save schemas should avoid depending directly on Minecraft runtime classes.
- BlockPos, ResourceLocation, Level, ServerLevel, and entity classes should be converted into internal data objects at the boundary.

4. High-Level Package Structure

com.livingworld

api
Public interfaces and data contracts that other modules or addons may use.

bootstrap
Startup code. Owns system creation order. No gameplay module should self-bootstrap.

config
Configuration files and validation.

core
Engine-level systems such as lifecycle, service registry, simulation control, and global state.

data
Save data, serialization, migration, schema validation, and export tooling.

events
Living World event bus and event definitions.

regions
Region identity, region state, region manager, region cache, and region query logic.

modules
Gameplay simulation modules. Each module lives in its own subpackage.

commands
Server commands for inspection and control.

debug
Profiling, dumps, overlays, diagnostics, and test helpers.

networking
Packets and client synchronization.

testing
Game tests, simulation tests, mock services, and long-run validation tools.

5. Core Startup Sequence

Startup order must be deterministic. The bootstrap system owns all major system creation.

Startup flow:

1. Minecraft loads the mod entrypoint.
2. LivingWorldMod creates the bootstrap context.
3. Config files are loaded.
4. Config values are validated.
5. Core services are created.
6. The Living World event bus is created.
7. Data migrations are registered.
8. Saved data services are prepared.
9. Module registry is created.
10. Built-in modules are registered.
11. Commands are registered.
12. Networking packets are registered.
13. Server-start hooks wait for world access.
14. On server start, world save data is loaded.
15. Simulation manager starts ticking.

The main mod entrypoint should not contain gameplay logic. Its job is to call bootstrap and register Minecraft-facing hooks.

6. Core Services

The project uses a service layer so modules do not need to know how everything is implemented.

Required services:

SimulationService
Owns simulation ticking, update queues, module update order, and performance budgets.

RegionService
Provides region lookup, region creation, coordinate conversion, region queries, and active region iteration.

PersistenceService
Owns save/load requests, dirty tracking, schema versioning, migration calls, and disk writes.

EventService
Owns Living World event publishing and subscription.

ModuleService
Owns module registry, lifecycle calls, module enable/disable state, and module dependency validation.

TimeService
Owns Living World calendar time, conversion between Minecraft ticks and simulation time, and time acceleration.

DebugService
Owns diagnostics, profiling, debug dumps, and command helper output.

ConfigService
Owns validated configuration access.

HistoryService
Owns historical record creation and lookup.

7. Service Access Rules

Modules may request services through a controlled service locator or dependency injection during initialization.

Allowed:

- EcologyModule receives RegionService, EventService, ConfigService, and DebugService.
- SettlementModule receives RegionService, EventService, TimeService, and HistoryService.

Not allowed:

- EcologyModule directly creates SettlementModule.
- RoadModule directly reads private settlement internals.
- FactionModule writes directly to region save files.

All cross-system communication must happen through services, public data contracts, or events.

8. Region Architecture

A region is the main unit of simulation. It is not a chunk and it is not a biome. It is an abstract simulation cell covering multiple chunks.

Default region size:

- Width: 8 chunks
- Depth: 8 chunks
- Block footprint: 128 by 128 blocks

A region stores simulation state even when no chunk in that area is loaded.

Region identity:

RegionCoordinate
- regionX
- regionZ
- dimensionId

Dimension must be included from the beginning. Even if v1 only simulates the Overworld, the architecture must not assume a single dimension forever.

9. RegionCoordinate Design

Class name:
RegionCoordinate

Type:
Immutable value object.

Fields:
- String dimensionId
- int x
- int z

Required methods:
- equals
- hashCode
- toString
- fromBlockPosition
- fromChunkPosition
- toMinimumChunkX
- toMinimumChunkZ
- toCenterBlockX
- toCenterBlockZ

Rules:

- RegionCoordinate must be immutable.
- It must be safe as a HashMap key.
- It must never store a direct Level or ServerLevel reference.
- Dimension identity must be saved as a stable string or resource key value.

10. Region Object Design

Class name:
Region

Purpose:
Stores all simulation state for one region.

Core fields:
- UUID id
- RegionCoordinate coordinate
- RegionLifecycleState lifecycleState
- long createdAtSimulationTick
- long lastUpdatedSimulationTick
- boolean dirty
- RegionFlags flags
- RegionMetrics metrics
- RegionModuleData moduleData

RegionMetrics fields:
- double ecologyScore
- double pollutionScore
- double prosperityScore
- double dangerScore
- double stabilityScore
- double developmentScore
- double resourcePressureScore

RegionModuleData:
A container mapping module IDs to module-specific region data.

Example:
- ecology -> EcologyRegionData
- climate -> ClimateRegionData
- settlements -> SettlementRegionData
- roads -> RoadRegionData

The core Region class must not contain every future field directly. It should contain common metrics plus a structured module data map.

11. Region Lifecycle

Every region exists in exactly one lifecycle state.

States:

UNLOADED
Region is not currently in memory.

LOADING
Region data is being loaded or created.

ACTIVE
Region is available for simulation.

DIRTY
Region has changed and must be saved.

SAVING
Persistence service is writing region data.

FAILED
Region failed to load, save, or validate.

UNLOADING
Region is being removed from memory after save.

Rules:

- A region cannot move from UNLOADED directly to DIRTY.
- A region cannot be saved unless it is DIRTY or explicitly force-saved.
- A failed region must not be simulated until recovery succeeds.
- Region transitions must be logged when debug mode is enabled.

12. RegionManager Responsibilities

Class name:
RegionManager

Responsibilities:

- Convert block and chunk positions to region coordinates.
- Return active regions.
- Create missing regions.
- Load regions from persistence.
- Mark regions dirty.
- Queue regions for saving.
- Unload low-priority regions from memory.
- Provide region query APIs.
- Protect against duplicate region instances.

Internal fields:

- Map<RegionCoordinate, Region> activeRegions
- RegionFactory regionFactory
- RegionStorage regionStorage
- RegionCache regionCache
- RegionQueryEngine queryEngine
- RegionLifecycleController lifecycleController
- DebugService debugService

Threading rule:
For v1, RegionManager is main-thread owned. Async save preparation may be added later, but direct mutation of active region objects must happen on the server thread until a safe threading model exists.

13. RegionFactory

Class name:
RegionFactory

Purpose:
Creates new region objects with default values.

Responsibilities:

- Assign UUIDs.
- Assign coordinate.
- Initialize lifecycle state.
- Initialize common metrics.
- Ask each enabled module to create default module data.
- Validate the finished region.

Method:
createNewRegion(RegionCoordinate coordinate)

Creation rules:

- New regions start with lifecycle state ACTIVE.
- New regions are marked dirty immediately so they are saved.
- Module default data must be deterministic based on world seed and region coordinate where randomness is needed.

14. RegionStorage

Class name:
RegionStorage

Purpose:
Bridge between RegionManager and PersistenceService.

Responsibilities:

- Load serialized region data.
- Save serialized region data.
- Validate schema version.
- Trigger migration if needed.
- Return load failures in a structured way.

RegionStorage must not contain simulation logic.

15. RegionCache

Class name:
RegionCache

Purpose:
Reduce memory pressure while keeping important regions available.

Cache policy v1:

- Always keep regions near online players.
- Always keep regions containing settlements.
- Always keep regions containing active events.
- Unload quiet regions after a configurable idle time.

Cache metrics:

- active region count
- dirty region count
- failed region count
- memory estimate
- average load time
- average save time

16. Region Query Engine

Class name:
RegionQueryEngine

Purpose:
Provide safe ways to search regions.

Required queries:

- getRegionAtBlockPos
- getRegionAtChunkPos
- getNeighbourRegions
- getRegionsInRadius
- getRegionsWithSettlement
- getRegionsAbovePollution
- getRegionsBelowEcology
- getRegionsByPriority
- getRegionsWithActiveEvent

Rules:

- Queries must avoid loading chunks.
- Queries may load region data if explicitly requested.
- Expensive queries must have limits.
- Debug commands must use query APIs rather than scanning internal maps directly.

17. Simulation Scheduler

Class name:
SimulationScheduler

Purpose:
Controls when regions update and how much work happens per cycle.

Minecraft runs at 20 ticks per second. The Living World simulation must not run heavy logic every tick.

Default timing:

- Simulation interval: every 100 Minecraft ticks
- Equivalent: every 5 seconds
- Configurable: yes

Scheduler fields:

- long minecraftTickCounter
- long simulationTickCounter
- int maxRegionsPerCycle
- int maxMillisecondsPerCycle
- Queue<RegionUpdateJob> updateQueue
- SimulationProfiler profiler
- RegionPriorityCalculator priorityCalculator

18. Region Update Job

Class name:
RegionUpdateJob

Fields:

- RegionCoordinate coordinate
- int priority
- long queuedAtSimulationTick
- Set<String> requestedModules
- UpdateReason reason

UpdateReason examples:

- NORMAL_ROLLING_UPDATE
- PLAYER_NEARBY
- SETTLEMENT_PRESENT
- ACTIVE_EVENT
- FORCED_DEBUG_COMMAND
- SAVE_MIGRATION_REQUIRED

19. Simulation Budgeting

The scheduler must prevent lag spikes.

Budget rules:

- Never update all regions in one cycle unless explicitly forced by debug command.
- Stop processing when max region count is reached.
- Stop processing when time budget is reached.
- Continue remaining jobs next cycle.
- Log budget overruns.

Default budget:

- Max regions per cycle: 50
- Max time per cycle: 25 milliseconds
- Emergency stop: 40 milliseconds

If a module exceeds its budget repeatedly, the profiler flags it.

20. Region Priority

Not all regions deserve equal update frequency.

Priority sources:

- Player nearby: very high
- Active settlement: high
- Active event: high
- Road or trade route: medium
- High pollution: medium
- High danger: medium
- Empty wilderness: low

Priority formula v1:

priority = base + playerBonus + settlementBonus + eventBonus + roadBonus + dangerBonus + pollutionBonus - idlePenalty

Priority must be deterministic and inspectable through debug commands.

21. Simulation Manager

Class name:
SimulationManager

Purpose:
Main coordinator for the simulation.

Responsibilities:

- Receive server tick callbacks.
- Ask SimulationScheduler whether a simulation cycle should run.
- Ask RegionManager for update candidates.
- Ask ModuleRegistry for enabled modules.
- Run module updates in the correct order.
- Publish events generated by modules.
- Mark changed regions dirty.
- Ask PersistenceService to process save queue.
- Send profiler data to DebugService.

The SimulationManager should be boring and predictable. It should coordinate, not contain gameplay rules.

22. Module Interface

Interface name:
SimulationModule

Required methods:

- String getModuleId()
- ModuleMetadata getMetadata()
- void initialize(ModuleContext context)
- void onServerStarted(ServerContext context)
- void createDefaultRegionData(Region region)
- ModuleUpdateResult updateRegion(RegionUpdateContext context)
- void onLivingWorldEvent(LivingWorldEvent event)
- void saveModuleData(PersistenceWriter writer)
- void loadModuleData(PersistenceReader reader)
- void shutdown()

Rules:

- Modules must report whether they changed a region.
- Modules must not save files directly.
- Modules must not load Minecraft chunks for abstract simulation.
- Modules must validate their config during initialize.

23. Module Metadata

Class name:
ModuleMetadata

Fields:

- moduleId
- displayName
- version
- description
- requiredCoreVersion
- dependencies
- optionalDependencies
- defaultEnabled
- serverOnly
- experimental

Purpose:
The ModuleRegistry uses metadata to validate load order and reject incompatible modules.

24. Module Context

Class name:
ModuleContext

Purpose:
Dependency container passed to modules at initialization.

Contains:

- ConfigService
- RegionService
- EventService
- TimeService
- PersistenceService
- DebugService
- HistoryService
- RandomService

Modules receive only the services they are allowed to use.

25. Module Update Result

Class name:
ModuleUpdateResult

Fields:

- boolean changedRegion
- List<LivingWorldEvent> generatedEvents
- List<HistoryRecord> historyRecords
- int estimatedCost
- List<String> warnings

Purpose:
Prevents modules from mutating global systems directly during update. They return results, and SimulationManager applies them in a controlled way.

26. Module Update Order

Default order:

1. Climate
2. Ecology
3. Wildlife
4. Resources
5. Settlements
6. Economy
7. Roads
8. Factions
9. Events
10. History

Reasoning:

Climate affects ecology. Ecology affects wildlife and resources. Resources affect settlements. Settlements affect economy and roads. Economy affects factions. Events and history record the outcome.

27. Event Architecture

There are three event layers.

Layer 1: Minecraft events
Examples: block break, block place, entity death, player login, world tick.

Layer 2: Living World simulation events
Examples: forest expanded, pollution increased, settlement founded, trade route opened.

Layer 3: Historical events
Examples: town founded, famine began, war declared, city abandoned.

Minecraft events should be translated into Living World events at the boundary. Modules should mainly listen to Living World events, not raw Minecraft events.

28. Living World Event Bus

Class name:
LivingWorldEventBus

Responsibilities:

- Register listeners.
- Publish events.
- Queue events safely during simulation updates.
- Prevent recursive event storms.
- Log event counts for debugging.
- Allow modules to subscribe by event type.

Rules:

- Events are immutable.
- Events include timestamp and source module ID.
- Events may be cancellable only when explicitly designed as cancellable.
- Historical events are created from selected simulation events, not every minor event.

29. Persistence Service

Class name:
PersistenceService

Responsibilities:

- Own all save and load operations.
- Track dirty regions.
- Track dirty global module data.
- Validate save schemas.
- Run migrations.
- Write save files.
- Recover from partial save failures.
- Provide debug export commands.

Persistence rule:
Modules never call file write APIs directly.

30. Save File Layout

Recommended layout:

world/livingworld/

core.json
regions/
region_overworld_0_0.json
region_overworld_0_1.json
settlements.json
factions.json
events.json
history.json
migrations.log
profiling/
latest_profile.json

Early development may use JSON for readability. Later versions may switch to compressed NBT or SQLite if performance requires it. The persistence layer must hide this decision from modules.

31. Save Schema Versioning

Every save file includes:

- schemaVersion
- modVersion
- createdAt
- updatedAt
- data

Example:

{
"schemaVersion": 1,
"modVersion": "0.1.0",
"data": {}
}

No unversioned save file is valid.

32. Migration System

Class name:
MigrationManager

Responsibilities:

- Detect save schema version.
- Find migration path.
- Apply migrations in order.
- Validate migrated data.
- Backup old data before migration.
- Record migration in migrations.log.

Example migration:

V1 stores ecology as one number.
V2 splits ecology into forestDensity, soilHealth, waterQuality, and biodiversity.

The migration converts the old value into new fields using deterministic defaults.

33. Time Service

Class name:
TimeService

Purpose:
The Living World needs its own calendar.

Fields:

- long simulationTick
- int day
- int month
- int year
- double timeScale

Default mapping:

- 1 Minecraft day equals 1 Living World month.
- 12 Minecraft days equals 1 Living World year.

The mapping must be configurable.

34. Debug Commands

Command root:
/lw

Required commands:

/lw region info
Shows region coordinate, lifecycle state, metrics, module data summary, dirty state, and priority.

/lw region dump
Exports full region data to a debug file.

/lw simulate 100
Runs 100 simulation ticks as fast as budget allows.

/lw simulate 1000 unsafe
Runs forced simulation without normal delay. Requires operator permission.

/lw modules list
Shows loaded modules, enabled state, version, and update cost.

/lw profile start
Starts profiler capture.

/lw profile stop
Stops profiler capture and writes report.

/lw history recent
Shows recent historical records.

/lw event trigger
Triggers a test Living World event.

35. Profiling Framework

Class name:
SimulationProfiler

Tracks:

- total simulation cycle time
- per-module update time
- per-region update time
- event count
- dirty region count
- save queue size
- memory estimate
- budget overruns

Profiler output should be readable by humans and exportable as JSON.

36. Testing Requirements for Volume 1

Minimum tests before Volume 2 begins:

Test 1: Region coordinate conversion
Given block positions across positive and negative coordinates, region coordinates must be correct.

Test 2: Region creation
Requesting a missing region creates one with valid default data.

Test 3: Region persistence
A region changed, saved, unloaded, and reloaded must keep identical data.

Test 4: Scheduler budget
Given 5000 regions, scheduler only processes the configured number per cycle.

Test 5: Module lifecycle
A fake module receives initialize, update, save, load, and shutdown calls in correct order.

Test 6: Event bus
Publishing a test event reaches the correct listeners once.

Test 7: Migration
A v1 save migrates to v2 without data loss.

Test 8: Long run
The simulation runs 100,000 ticks without crash, memory leak, or corrupted save data.

37. Definition of Done for Volume 1

Volume 1 is complete when the following exist in code:

- Bootstrap system
- Config loading
- Core service registry
- RegionCoordinate
- Region
- RegionManager
- RegionFactory
- RegionStorage
- RegionCache
- RegionQueryEngine
- SimulationScheduler
- SimulationManager
- ModuleRegistry
- SimulationModule interface
- LivingWorldEventBus
- PersistenceService
- MigrationManager
- TimeService
- Debug commands
- SimulationProfiler
- Test module
- Persistence tests
- Scheduler tests
- Event tests
- Long-run simulation test

Only after these are passing should Volume 2 systems be implemented.

38. Implementation Rule for AI Agents

AI agents must not skip foundation tasks.

Every implementation task must include:

- Purpose
- File path
- Class name
- Inputs
- Outputs
- Dependencies
- Exact method signatures
- Expected tests
- Definition of done

Vague tasks are banned.

Bad task:
Build region manager.

Good task:
Create src/main/java/com/livingworld/regions/RegionCoordinate.java as an immutable record with dimensionId, x, and z fields. Add fromBlockPosition and fromChunkPosition factory methods. Add unit tests for positive and negative coordinates. Done when all tests pass and RegionCoordinate can be used as a HashMap key.

End of current Volume 1 draft section.

Next section to add: exact file-by-file implementation backlog for the Volume 1 foundation.

39. Volume 1 File-by-File Implementation Backlog

This section turns the architecture into buildable work. The tasks below are intentionally small, explicit, and ordered. A developer or AI coding agent should complete them in sequence unless a task explicitly says it can be done later.

Backlog rules:

- Do not create gameplay modules yet.
- Do not implement ecology, settlements, roads, factions, or economy yet.
- Do not start with mobs, structures, or terrain changes.
- Build the engine first.
- Each task must compile before moving on.
- Each task must either add tests or explain why tests are not yet possible.
- Every class should have a single clear responsibility.

40. Milestone 1 — Project Skeleton

Goal:
Create the base mod project and folder structure.

Definition of done:
The mod launches in a development environment, logs a startup message, and has empty packages prepared for the core architecture.

Task 1.1 — Create base mod package

Purpose:
Establish the root Java package.

File path:
src/main/java/com/livingworld/LivingWorldMod.java

Class name:
LivingWorldMod

Dependencies:
Forge or NeoForge mod loader entrypoint.

Implementation notes:
This class should contain only mod entrypoint wiring. It must not contain simulation logic. It should create or call a bootstrap class.

Required behaviour:
- Defines public static final String MOD_ID = "livingworld".
- Logs that Living World is loading.
- Registers mod lifecycle listeners.
- Delegates setup to LivingWorldBootstrap.

Definition of done:
The mod loads without crashing and the log shows a clear startup message.

Task 1.2 — Create bootstrap package

Purpose:
Create startup ownership boundary.

File path:
src/main/java/com/livingworld/bootstrap/LivingWorldBootstrap.java

Class name:
LivingWorldBootstrap

Required methods:
- void initialize()
- void onCommonSetup()
- void onServerStarting()
- void onServerStarted()
- void onServerStopping()

Implementation notes:
For now, methods can log their lifecycle stage. Later tasks will fill them with service creation and startup ordering.

Definition of done:
All lifecycle methods exist and can be called from the mod entrypoint.

Task 1.3 — Create package placeholders

Purpose:
Create the long-term source tree.

Packages to create:
- com.livingworld.api
- com.livingworld.bootstrap
- com.livingworld.config
- com.livingworld.core
- com.livingworld.core.lifecycle
- com.livingworld.core.registry
- com.livingworld.core.services
- com.livingworld.core.simulation
- com.livingworld.data
- com.livingworld.data.saved
- com.livingworld.data.migration
- com.livingworld.data.serialization
- com.livingworld.events
- com.livingworld.regions
- com.livingworld.regions.cache
- com.livingworld.regions.query
- com.livingworld.commands
- com.livingworld.debug
- com.livingworld.networking
- com.livingworld.testing
- com.livingworld.modules

Definition of done:
The packages exist and the project still compiles.

Task 1.4 — Create build constants

Purpose:
Centralize mod constants.

File path:
src/main/java/com/livingworld/core/LivingWorldConstants.java

Class name:
LivingWorldConstants

Fields:
- MOD_ID
- MOD_NAME
- CURRENT_CORE_SCHEMA_VERSION
- DEFAULT_REGION_SIZE_CHUNKS
- DEFAULT_SIMULATION_INTERVAL_TICKS

Initial values:
- MOD_ID = "livingworld"
- MOD_NAME = "Living World"
- CURRENT_CORE_SCHEMA_VERSION = 1
- DEFAULT_REGION_SIZE_CHUNKS = 8
- DEFAULT_SIMULATION_INTERVAL_TICKS = 100

Definition of done:
LivingWorldMod uses LivingWorldConstants.MOD_ID instead of duplicating the string.

41. Milestone 2 — Logging and Diagnostics Foundation

Goal:
Create consistent logging before more systems exist.

Definition of done:
Every core system can log through one shared logging helper.

Task 2.1 — Create logger wrapper

File path:
src/main/java/com/livingworld/debug/LivingWorldLogger.java

Class name:
LivingWorldLogger

Purpose:
Provide a central logging wrapper so logs are consistently formatted.

Required methods:
- info(String message)
- warn(String message)
- error(String message)
- error(String message, Throwable throwable)
- debug(String message)

Rules:
- Debug logs should respect a future debug config flag.
- Do not print directly to System.out.

Definition of done:
Bootstrap uses LivingWorldLogger for all startup logs.

Task 2.2 — Create diagnostic category enum

File path:
src/main/java/com/livingworld/debug/DiagnosticCategory.java

Enum values:
- BOOTSTRAP
- CONFIG
- REGIONS
- SIMULATION
- PERSISTENCE
- EVENTS
- MODULES
- COMMANDS
- NETWORKING
- TESTING

Purpose:
Allow future logs and profiler entries to be grouped.

Definition of done:
Logger can optionally accept a DiagnosticCategory.

42. Milestone 3 — Configuration Foundation

Goal:
Create config objects and validation before systems depend on hard-coded values.

Task 3.1 — Create simulation config model

File path:
src/main/java/com/livingworld/config/SimulationConfig.java

Class name:
SimulationConfig

Fields:
- int regionSizeChunks
- int simulationIntervalTicks
- int maxRegionsPerCycle
- int maxMillisecondsPerCycle
- int emergencyStopMilliseconds
- boolean enableDebugCommands
- boolean enableProfiler

Default values:
- regionSizeChunks = 8
- simulationIntervalTicks = 100
- maxRegionsPerCycle = 50
- maxMillisecondsPerCycle = 25
- emergencyStopMilliseconds = 40
- enableDebugCommands = true
- enableProfiler = true

Required methods:
- validate()

Validation rules:
- regionSizeChunks must be at least 1.
- simulationIntervalTicks must be at least 1.
- maxRegionsPerCycle must be at least 1.
- maxMillisecondsPerCycle must be at least 1.
- emergencyStopMilliseconds must be greater than or equal to maxMillisecondsPerCycle.

Definition of done:
Invalid values throw a clear validation exception.

Task 3.2 — Create config service interface

File path:
src/main/java/com/livingworld/core/services/ConfigService.java

Interface name:
ConfigService

Required methods:
- SimulationConfig getSimulationConfig()
- void reload()
- void validate()

Definition of done:
Interface compiles and is referenced by ModuleContext later.

Task 3.3 — Create default config service implementation

File path:
src/main/java/com/livingworld/config/DefaultConfigService.java

Class name:
DefaultConfigService

Implements:
ConfigService

Purpose:
Provide config values before full Forge/NeoForge config wiring is completed.

Definition of done:
Bootstrap can create DefaultConfigService, validate it, and log the active simulation interval.

43. Milestone 4 — Core Service Registry

Goal:
Make service access controlled and predictable.

Task 4.1 — Create ServiceKey

File path:
src/main/java/com/livingworld/core/services/ServiceKey.java

Class name:
ServiceKey

Type:
Generic immutable value object.

Fields:
- String id
- Class<T> serviceType

Rules:
- Must be immutable.
- Must validate non-empty ID.
- Must validate serviceType is not null.

Definition of done:
Can be used as a key for registered services.

Task 4.2 — Create ServiceRegistry

File path:
src/main/java/com/livingworld/core/services/ServiceRegistry.java

Class name:
ServiceRegistry

Responsibilities:
- Register services.
- Reject duplicate service IDs.
- Retrieve services by key.
- Check if service exists.
- Lock registry after bootstrap.

Required methods:
- <T> void register(ServiceKey<T> key, T service)
- <T> T get(ServiceKey<T> key)
- <T> Optional<T> find(ServiceKey<T> key)
- boolean isRegistered(ServiceKey<?> key)
- void lock()
- boolean isLocked()

Definition of done:
Duplicate registration fails. Getting a missing service fails with a clear error.

Task 4.3 — Create CoreServices keys

File path:
src/main/java/com/livingworld/core/services/CoreServices.java

Class name:
CoreServices

Purpose:
Central list of built-in service keys.

Keys to define:
- CONFIG
- REGIONS
- SIMULATION
- PERSISTENCE
- EVENTS
- MODULES
- TIME
- DEBUG
- HISTORY

Definition of done:
ServiceRegistry can register and retrieve ConfigService using CoreServices.CONFIG.

44. Milestone 5 — Region Identity

Goal:
Implement coordinate conversion correctly before any region storage exists.

Task 5.1 — Create RegionCoordinate

File path:
src/main/java/com/livingworld/regions/RegionCoordinate.java

Class name:
RegionCoordinate

Recommended type:
Java record.

Fields:
- String dimensionId
- int x
- int z

Required factory methods:
- static RegionCoordinate fromChunk(String dimensionId, int chunkX, int chunkZ, int regionSizeChunks)
- static RegionCoordinate fromBlock(String dimensionId, int blockX, int blockZ, int regionSizeChunks)

Required instance methods:
- int minChunkX(int regionSizeChunks)
- int minChunkZ(int regionSizeChunks)
- int maxChunkX(int regionSizeChunks)
- int maxChunkZ(int regionSizeChunks)
- int centerBlockX(int regionSizeChunks)
- int centerBlockZ(int regionSizeChunks)
- String stableId()

Important rule:
Use floor division, not normal truncating division, so negative coordinates work correctly.

Test cases:
- block 0,0 maps to region 0,0.
- block 127,127 maps to region 0,0 when region size is 8 chunks.
- block 128,0 maps to region 1,0.
- block -1,0 maps to region -1,0.
- block -128,0 maps to region -1,0.
- block -129,0 maps to region -2,0.

Definition of done:
All coordinate tests pass and RegionCoordinate is safe as a map key.

Task 5.2 — Create RegionLifecycleState

File path:
src/main/java/com/livingworld/regions/RegionLifecycleState.java

Enum values:
- UNLOADED
- LOADING
- ACTIVE
- DIRTY
- SAVING
- FAILED
- UNLOADING

Definition of done:
Enum exists and is used by Region in the next milestone.

Task 5.3 — Create RegionFlags

File path:
src/main/java/com/livingworld/regions/RegionFlags.java

Class name:
RegionFlags

Fields:
- boolean hasPlayerActivity
- boolean hasSettlement
- boolean hasRoad
- boolean hasActiveEvent
- boolean forceLoadedBySimulation
- boolean corrupted

Required methods:
- copy()
- clearTransientFlags()

Definition of done:
Flags can be created, copied, and reset.

45. Milestone 6 — Region Core Data

Goal:
Create the in-memory region object and common metrics.

Task 6.1 — Create RegionMetrics

File path:
src/main/java/com/livingworld/regions/RegionMetrics.java

Class name:
RegionMetrics

Fields:
- double ecologyScore
- double pollutionScore
- double prosperityScore
- double dangerScore
- double stabilityScore
- double developmentScore
- double resourcePressureScore

Rules:
- Values should generally be clamped between 0 and 100.
- Clamping should happen through setter methods or normalize().

Required methods:
- normalize()
- copy()
- static RegionMetrics defaults()

Definition of done:
Default metrics create a neutral region and normalize clamps out-of-range values.

Task 6.2 — Create RegionModuleData

File path:
src/main/java/com/livingworld/regions/RegionModuleData.java

Class name:
RegionModuleData

Purpose:
Store module-specific data without bloating the core Region class.

Fields:
- Map<String, Object> moduleData

Required methods:
- put(String moduleId, Object data)
- <T> Optional<T> get(String moduleId, Class<T> type)
- boolean contains(String moduleId)
- Set<String> moduleIds()
- RegionModuleData copyShallow()

V1 note:
Using Object is acceptable for the first architecture pass. Later, replace with a typed serialization contract.

Definition of done:
Can store and retrieve typed module data safely.

Task 6.3 — Create Region

File path:
src/main/java/com/livingworld/regions/Region.java

Class name:
Region

Fields:
- UUID id
- RegionCoordinate coordinate
- RegionLifecycleState lifecycleState
- long createdAtSimulationTick
- long lastUpdatedSimulationTick
- boolean dirty
- RegionFlags flags
- RegionMetrics metrics
- RegionModuleData moduleData

Required methods:
- markDirty()
- clearDirty()
- isDirty()
- updateLastSimulatedTick(long tick)
- setLifecycleState(RegionLifecycleState state)
- validate()

Validation rules:
- id must not be null.
- coordinate must not be null.
- lifecycleState must not be null.
- metrics must not be null.
- moduleData must not be null.

Definition of done:
Region can be constructed, validated, marked dirty, and updated.

46. Milestone 7 — Region Creation and Lifecycle Control

Goal:
Create safe lifecycle transitions and deterministic region creation.

Task 7.1 — Create RegionLifecycleController

File path:
src/main/java/com/livingworld/regions/RegionLifecycleController.java

Class name:
RegionLifecycleController

Purpose:
Validate state transitions.

Required methods:
- boolean canTransition(RegionLifecycleState from, RegionLifecycleState to)
- void transition(Region region, RegionLifecycleState target)

Allowed transitions:
- UNLOADED to LOADING
- LOADING to ACTIVE
- LOADING to FAILED
- ACTIVE to DIRTY
- DIRTY to SAVING
- SAVING to ACTIVE
- SAVING to FAILED
- ACTIVE to UNLOADING
- UNLOADING to UNLOADED
- FAILED to LOADING

Definition of done:
Invalid transitions throw clear exceptions.

Task 7.2 — Create RegionFactory

File path:
src/main/java/com/livingworld/regions/RegionFactory.java

Class name:
RegionFactory

Dependencies:
- ModuleRegistry later, but initial version can accept no modules.

Required methods:
- Region createNewRegion(RegionCoordinate coordinate, long simulationTick)

Rules:
- New region receives random UUID.
- New region starts ACTIVE.
- New region has default metrics.
- New region is dirty immediately.
- New region validates before return.

Definition of done:
Factory creates valid regions that pass Region.validate().

47. Milestone 8 — Module Contracts

Goal:
Define module contracts before modules exist.

Task 8.1 — Create SimulationModule interface

File path:
src/main/java/com/livingworld/modules/SimulationModule.java

Interface name:
SimulationModule

Required methods:
- String getModuleId()
- ModuleMetadata getMetadata()
- void initialize(ModuleContext context)
- void onServerStarted(ServerContext context)
- void createDefaultRegionData(Region region)
- ModuleUpdateResult updateRegion(RegionUpdateContext context)
- void onLivingWorldEvent(LivingWorldEvent event)
- void saveModuleData(PersistenceWriter writer)
- void loadModuleData(PersistenceReader reader)
- void shutdown()

Temporary placeholders:
If ServerContext, LivingWorldEvent, PersistenceWriter, or PersistenceReader do not exist yet, create minimal placeholder interfaces in the appropriate packages.

Definition of done:
The interface compiles and can be implemented by a fake test module.

Task 8.2 — Create ModuleMetadata

File path:
src/main/java/com/livingworld/modules/ModuleMetadata.java

Recommended type:
Record or immutable class.

Fields:
- String moduleId
- String displayName
- String version
- String description
- String requiredCoreVersion
- List<String> dependencies
- List<String> optionalDependencies
- boolean defaultEnabled
- boolean serverOnly
- boolean experimental

Definition of done:
ModuleMetadata validates moduleId and displayName are present.

Task 8.3 — Create ModuleContext

File path:
src/main/java/com/livingworld/modules/ModuleContext.java

Class name:
ModuleContext

Fields:
- ServiceRegistry services

Required methods:
- <T> T getService(ServiceKey<T> key)

Definition of done:
A module can request ConfigService through ModuleContext.

Task 8.4 — Create ModuleUpdateResult

File path:
src/main/java/com/livingworld/modules/ModuleUpdateResult.java

Fields:
- boolean changedRegion
- List<LivingWorldEvent> generatedEvents
- List<HistoryRecord> historyRecords
- int estimatedCost
- List<String> warnings

Required static constructors:
- noChange()
- changed()

Definition of done:
A fake module can return noChange or changed results.

Task 8.5 — Create ModuleRegistry

File path:
src/main/java/com/livingworld/modules/ModuleRegistry.java

Responsibilities:
- Register modules.
- Reject duplicate module IDs.
- Resolve module order.
- Return enabled modules.
- Initialize modules.
- Shutdown modules.

Required methods:
- void register(SimulationModule module)
- List<SimulationModule> getAllModules()
- List<SimulationModule> getEnabledModules()
- Optional<SimulationModule> find(String moduleId)
- void initializeAll(ModuleContext context)
- void shutdownAll()

Definition of done:
A fake module can be registered, initialized, found, and shut down.

48. Milestone 9 — Event Foundation

Goal:
Create the Living World event layer.

Task 9.1 — Create LivingWorldEvent

File path:
src/main/java/com/livingworld/events/LivingWorldEvent.java

Class name:
LivingWorldEvent

Recommended type:
Interface.

Required methods:
- String eventType()
- long simulationTick()
- String sourceModuleId()

Definition of done:
Test events can implement this interface.

Task 9.2 — Create BaseLivingWorldEvent

File path:
src/main/java/com/livingworld/events/BaseLivingWorldEvent.java

Class name:
BaseLivingWorldEvent

Fields:
- String eventType
- long simulationTick
- String sourceModuleId

Definition of done:
Can be used for simple test events.

Task 9.3 — Create LivingWorldEventListener

File path:
src/main/java/com/livingworld/events/LivingWorldEventListener.java

Interface method:
- void onEvent(LivingWorldEvent event)

Definition of done:
Listener interface compiles.

Task 9.4 — Create LivingWorldEventBus

File path:
src/main/java/com/livingworld/events/LivingWorldEventBus.java

Responsibilities:
- Register listener by event type.
- Publish event.
- Queue event during active dispatch.
- Prevent endless recursive dispatch.

Required methods:
- void register(String eventType, LivingWorldEventListener listener)
- void publish(LivingWorldEvent event)
- int getPublishedEventCount()
- int getListenerCount(String eventType)

Definition of done:
A published event reaches its listener once.

49. Milestone 10 — Time Service

Goal:
Create internal simulation time independent from Minecraft time.

Task 10.1 — Create LivingWorldCalendar

File path:
src/main/java/com/livingworld/core/simulation/LivingWorldCalendar.java

Fields:
- long simulationTick
- int day
- int month
- int year

Required methods:
- advanceTicks(long ticks)
- copy()
- toDisplayString()

Definition of done:
Advancing ticks updates the calendar in a predictable way.

Task 10.2 — Create TimeService interface

File path:
src/main/java/com/livingworld/core/services/TimeService.java

Methods:
- long getSimulationTick()
- LivingWorldCalendar getCalendar()
- void advanceSimulationTick()
- void advanceSimulationTicks(long ticks)

Definition of done:
Interface exists and is used by DefaultTimeService.

Task 10.3 — Create DefaultTimeService

File path:
src/main/java/com/livingworld/core/simulation/DefaultTimeService.java

Implements:
TimeService

Definition of done:
Simulation tick can advance and calendar state can be read.

50. Milestone 11 — Simulation Scheduler and Manager

Goal:
Create the heartbeat of the simulation.

Task 11.1 — Create UpdateReason

File path:
src/main/java/com/livingworld/core/simulation/UpdateReason.java

Enum values:
- NORMAL_ROLLING_UPDATE
- PLAYER_NEARBY
- SETTLEMENT_PRESENT
- ACTIVE_EVENT
- FORCED_DEBUG_COMMAND
- SAVE_MIGRATION_REQUIRED

Definition of done:
Enum compiles and is used by RegionUpdateJob.

Task 11.2 — Create RegionUpdateJob

File path:
src/main/java/com/livingworld/core/simulation/RegionUpdateJob.java

Fields:
- RegionCoordinate coordinate
- int priority
- long queuedAtSimulationTick
- Set<String> requestedModules
- UpdateReason reason

Definition of done:
Jobs can be sorted by descending priority.

Task 11.3 — Create RegionPriorityCalculator

File path:
src/main/java/com/livingworld/core/simulation/RegionPriorityCalculator.java

Method:
- int calculatePriority(Region region)

Initial scoring:
- base = 5
- player activity bonus = 100
- settlement bonus = 75
- active event bonus = 75
- road bonus = 50
- danger bonus = dangerScore / 2
- pollution bonus = pollutionScore / 2

Definition of done:
Priority score is deterministic and testable.

Task 11.4 — Create SimulationScheduler

File path:
src/main/java/com/livingworld/core/simulation/SimulationScheduler.java

Responsibilities:
- Track Minecraft tick count.
- Decide when simulation should run.
- Maintain update queue.
- Respect max region budget.
- Respect time budget.

Required methods:
- void onMinecraftTick()
- boolean shouldRunSimulationCycle()
- void queueRegion(RegionUpdateJob job)
- List<RegionUpdateJob> pollJobsForCycle()

Definition of done:
Given 500 queued jobs and maxRegionsPerCycle of 50, one cycle returns 50 jobs.

Task 11.5 — Create SimulationManager

File path:
src/main/java/com/livingworld/core/simulation/SimulationManager.java

Responsibilities:
- Receive tick calls.
- Ask scheduler whether to run.
- Get update jobs.
- Resolve regions.
- Run enabled modules.
- Publish generated events.
- Mark changed regions dirty.

Definition of done:
A fake module can update a fake region through SimulationManager.

51. Milestone 12 — Persistence Foundation

Goal:
Build save/load abstraction before data becomes complicated.

Task 12.1 — Create PersistenceWriter

File path:
src/main/java/com/livingworld/data/serialization/PersistenceWriter.java

Purpose:
Abstraction for writing save data.

Initial methods:
- void writeString(String key, String value)
- void writeInt(String key, int value)
- void writeLong(String key, long value)
- void writeDouble(String key, double value)
- void writeBoolean(String key, boolean value)

Definition of done:
Interface compiles.

Task 12.2 — Create PersistenceReader

File path:
src/main/java/com/livingworld/data/serialization/PersistenceReader.java

Purpose:
Abstraction for reading save data.

Initial methods:
- String readString(String key, String defaultValue)
- int readInt(String key, int defaultValue)
- long readLong(String key, long defaultValue)
- double readDouble(String key, double defaultValue)
- boolean readBoolean(String key, boolean defaultValue)

Definition of done:
Interface compiles.

Task 12.3 — Create SaveMetadata

File path:
src/main/java/com/livingworld/data/saved/SaveMetadata.java

Fields:
- int schemaVersion
- String modVersion
- long createdAt
- long updatedAt

Definition of done:
Save metadata validates schemaVersion is greater than zero.

Task 12.4 — Create PersistenceService interface

File path:
src/main/java/com/livingworld/core/services/PersistenceService.java

Methods:
- void markRegionDirty(Region region)
- void saveDirtyRegions()
- Optional<Region> loadRegion(RegionCoordinate coordinate)
- void saveRegion(Region region)
- void flushAll()

Definition of done:
Interface compiles and RegionStorage can depend on it.

52. Milestone 13 — Region Storage and Manager

Goal:
Connect region creation, lookup, cache, and storage.

Task 13.1 — Create RegionStorage

File path:
src/main/java/com/livingworld/regions/RegionStorage.java

Dependencies:
- PersistenceService

Methods:
- Optional<Region> load(RegionCoordinate coordinate)
- void save(Region region)

Definition of done:
Can delegate load/save to PersistenceService.

Task 13.2 — Create RegionCache

File path:
src/main/java/com/livingworld/regions/cache/RegionCache.java

Fields:
- Map<RegionCoordinate, Region> activeRegions

Methods:
- Optional<Region> get(RegionCoordinate coordinate)
- void put(Region region)
- void remove(RegionCoordinate coordinate)
- Collection<Region> allActive()
- int size()

Definition of done:
Can store and retrieve regions by coordinate.

Task 13.3 — Create RegionQueryEngine

File path:
src/main/java/com/livingworld/regions/query/RegionQueryEngine.java

Methods:
- Optional<Region> getRegion(RegionCoordinate coordinate)
- List<Region> getRegionsInRadius(RegionCoordinate center, int radius)
- List<Region> getRegionsWithActiveEvent()
- List<Region> getRegionsWithSettlement()

Definition of done:
Queries operate on RegionCache without touching chunks.

Task 13.4 — Create RegionManager

File path:
src/main/java/com/livingworld/regions/RegionManager.java

Dependencies:
- RegionFactory
- RegionStorage
- RegionCache
- RegionQueryEngine
- RegionLifecycleController
- SimulationConfig

Methods:
- Region getOrCreateRegion(RegionCoordinate coordinate)
- Optional<Region> findRegion(RegionCoordinate coordinate)
- Region getOrCreateRegionAtBlock(String dimensionId, int blockX, int blockZ)
- Collection<Region> getActiveRegions()
- void markDirty(Region region)
- void unloadRegion(RegionCoordinate coordinate)

Definition of done:
Requesting a region first checks cache, then storage, then factory.

53. Milestone 14 — Debug Commands

Goal:
Expose inspection tools early.

Task 14.1 — Create LivingWorldCommandRoot

File path:
src/main/java/com/livingworld/commands/LivingWorldCommandRoot.java

Purpose:
Register /lw command tree.

Initial subcommands:
- /lw status
- /lw region info
- /lw modules list
- /lw simulate <ticks>

Definition of done:
Commands register and return placeholder output if systems are not fully connected.

Task 14.2 — Create RegionInfoCommand

File path:
src/main/java/com/livingworld/commands/RegionInfoCommand.java

Output:
- Region coordinate
- Lifecycle state
- Dirty state
- Metrics
- Flags
- Module IDs present

Definition of done:
Standing in a world and running /lw region info prints region state.

Task 14.3 — Create SimulateCommand

File path:
src/main/java/com/livingworld/commands/SimulateCommand.java

Purpose:
Force simulation ticks for testing.

Rules:
- Operator-only.
- Maximum safe default: 1000 ticks.
- Unsafe mode can bypass limit later.

Definition of done:
Command advances TimeService and runs SimulationManager for requested ticks.

54. Milestone 15 — Profiling

Goal:
Measure simulation cost before real systems are added.

Task 15.1 — Create SimulationProfiler

File path:
src/main/java/com/livingworld/debug/SimulationProfiler.java

Tracks:
- cycle start time
- cycle end time
- per-module timings
- per-region timings
- event count
- save count
- budget overruns

Methods:
- beginCycle()
- endCycle()
- beginModule(String moduleId)
- endModule(String moduleId)
- recordEvent()
- recordSave()
- createSnapshot()

Definition of done:
Profiler can produce a snapshot after a simulation cycle.

Task 15.2 — Create SimulationProfileSnapshot

File path:
src/main/java/com/livingworld/debug/SimulationProfileSnapshot.java

Fields:
- long totalCycleNanos
- Map<String, Long> moduleTimings
- int eventsPublished
- int regionsUpdated
- int savesPerformed
- boolean budgetExceeded

Definition of done:
Snapshot can be printed in debug command output.

55. Milestone 16 — Test Module and Long Run Test

Goal:
Prove the engine can run before real gameplay systems exist.

Task 16.1 — Create TestSimulationModule

File path:
src/main/java/com/livingworld/testing/TestSimulationModule.java

Purpose:
Fake module used to verify lifecycle and update flow.

Behaviour:
- On initialize, record initialized = true.
- On updateRegion, increment a counter in test module data.
- Every 10 updates, return changedRegion = true.

Definition of done:
SimulationManager can run this module against test regions.

Task 16.2 — Create RegionCoordinateTest

File path:
src/test/java/com/livingworld/regions/RegionCoordinateTest.java

Must test:
- Positive coordinate conversion.
- Negative coordinate conversion.
- Stable ID generation.
- HashMap key usage.

Definition of done:
All tests pass.

Task 16.3 — Create RegionLifecycleControllerTest

File path:
src/test/java/com/livingworld/regions/RegionLifecycleControllerTest.java

Must test:
- Allowed transitions succeed.
- Invalid transitions fail.
- Failed regions can return to loading.

Definition of done:
All tests pass.

Task 16.4 — Create SchedulerBudgetTest

File path:
src/test/java/com/livingworld/core/simulation/SchedulerBudgetTest.java

Must test:
- 500 jobs with limit 50 returns 50.
- Higher priority jobs are returned first.
- Jobs not processed remain queued.

Definition of done:
All tests pass.

Task 16.5 — Create EventBusTest

File path:
src/test/java/com/livingworld/events/EventBusTest.java

Must test:
- Listener receives event.
- Listener receives event once.
- Multiple listeners receive event.
- Unknown event type does not crash.

Definition of done:
All tests pass.

Task 16.6 — Create LongRunSimulationTest

File path:
src/test/java/com/livingworld/testing/LongRunSimulationTest.java

Purpose:
Prove the foundation does not collapse under time.

Test setup:
- Create 1000 fake regions.
- Register TestSimulationModule.
- Run 100,000 simulation ticks.
- Save dirty regions periodically.

Pass conditions:
- No crash.
- No unhandled exception.
- No invalid lifecycle transition.
- Dirty region count does not grow forever.
- Profiler reports cycle data.

Definition of done:
Long-run test completes reliably.

56. Milestone 17 — Volume 1 Completion Gate

Volume 1 cannot be considered complete until all items below are true:

- The mod launches.
- Bootstrap sequence logs all stages.
- Config service loads and validates defaults.
- Service registry registers all core services.
- RegionCoordinate handles negative coordinates correctly.
- Region objects validate their internal state.
- RegionFactory creates valid dirty regions.
- RegionLifecycleController rejects invalid transitions.
- ModuleRegistry can register and initialize a test module.
- LivingWorldEventBus publishes events once.
- TimeService advances simulation time.
- SimulationScheduler respects region budget.
- SimulationManager runs at least one module over at least one region.
- RegionManager can get, create, cache, mark dirty, and unload regions.
- Debug commands exist.
- Profiler creates snapshots.
- Unit tests pass.
- Long-run simulation test passes.

Only then should development move into Volume 2: Ecology, Climate, Wildlife, and Environmental Change.

57. Next Volume 1 Expansion

The next expansion should add implementation-level pseudocode for the most important classes:

- RegionCoordinate
- Region
- RegionManager
- SimulationScheduler
- SimulationManager
- ModuleRegistry
- LivingWorldEventBus
- PersistenceService

That section should include method bodies in pseudocode, expected edge cases, and exact failure handling.

58. Platform Decision Update — Minecraft Java 26.1

Date added: 05 June 2026

Decision:
This project is a Minecraft Java Edition NeoForge-first mod. It is not a Bukkit, Spigot, or Paper plugin.

Current verified target:
The current verified documentation target is Minecraft Java Edition 26.1. The official Minecraft 26.1 release article was published on 24 March 2026 and describes the Tiny Takeover drop. NeoForge documentation is also currently available for version 26.1.

Primary implementation target:
Minecraft Java Edition 26.1 with NeoForge 26.1.

Forward compatibility target:
When the next Minecraft Java release becomes stable, the project should not immediately jump to it. First, verify that NeoForge or Forge support has stabilised, common dependencies have updated, and the mod can still pass its long-run simulation tests.

Loader preference:
1. NeoForge first.
2. Forge-compatible architecture where practical.
3. Fabric is a possible future port after the core simulation engine is stable.
4. Bukkit, Spigot, and Paper are not valid primary targets for this project.

Why this is a mod, not a Bukkit plugin:

The Living World project needs deep world simulation, persistent custom world data, server tick integration, modular simulation systems, possible custom blocks, possible custom entities, custom networking, dedicated server testing, and long-term modded-server compatibility.

A Bukkit, Spigot, or Paper plugin is better suited to server-side behaviour on mostly vanilla servers: commands, moderation tools, permissions, minigames, simple economy features, region protection, and server rule changes.

This project is different. It is closer to an engine-level simulation mod. It needs access to mod-loader systems such as registries, events, data storage, networking, and client/server separation. Therefore, it belongs on NeoForge or Forge.

Architecture rule:
Core simulation code must remain as plain Java wherever possible. Minecraft-specific code must sit behind a platform adapter so future ports are possible.

Required platform packages:

com.livingworld.platform
Common platform interfaces.

com.livingworld.platform.neoforge
NeoForge implementation.

com.livingworld.platform.forge
Optional future Forge compatibility layer.

com.livingworld.integration.minecraft
Boundary code that converts Minecraft classes into internal Living World data objects.

Boundary conversion examples:

- BlockPos becomes an internal block coordinate object.
- ChunkPos becomes an internal chunk coordinate object.
- ResourceKey or dimension ID becomes a stable dimension string.
- ServerLevel is used only at the boundary, never stored inside core simulation objects.
- Entity references become stable IDs or event data, not long-lived direct object references.

Version policy:

- Do not hard-code the architecture to one Minecraft minor version.
- Do not let gameplay modules depend directly on NeoForge classes.
- Keep mod-loader code in the platform layer.
- Keep region simulation, scheduler, persistence rules, and event logic in plain Java where possible.
- Before every Minecraft version upgrade, run all unit tests, migration tests, dedicated server tests, and long-run simulation tests.

Volume 1 backlog addition — Platform Adapter Foundation

Task P1 — Create PlatformAdapter interface

File path:
src/main/java/com/livingworld/platform/PlatformAdapter.java

Purpose:
Define the boundary between the Living World core engine and the active Minecraft mod loader.

Required methods:
- String getPlatformName()
- String getMinecraftVersion()
- String getLoaderVersion()
- boolean isDedicatedServer()
- Path getWorldSaveDirectory()
- void registerCommands()
- void registerServerTickHook()
- void registerPlayerEventHooks()

Definition of done:
The core bootstrap can ask the platform adapter what loader and Minecraft version are active without directly importing NeoForge classes.

Task P2 — Create NeoForgePlatformAdapter

File path:
src/main/java/com/livingworld/platform/neoforge/NeoForgePlatformAdapter.java

Purpose:
Implement PlatformAdapter using NeoForge APIs.

Rules:
- This class may import NeoForge and Minecraft classes.
- Core simulation classes must not import NeoForge classes.
- The adapter should forward server tick events to SimulationManager.

Definition of done:
The mod logs active platform name, Minecraft version, and loader version during bootstrap.

Task P3 — Create MinecraftCoordinateMapper

File path:
src/main/java/com/livingworld/integration/minecraft/MinecraftCoordinateMapper.java

Purpose:
Convert Minecraft positions into Living World coordinates.

Required methods:
- RegionCoordinate fromBlockPos(String dimensionId, int blockX, int blockZ, int regionSizeChunks)
- RegionCoordinate fromChunkPos(String dimensionId, int chunkX, int chunkZ, int regionSizeChunks)

Definition of done:
Minecraft boundary code can convert positions without leaking Minecraft classes into region-core classes.

Task P4 — Update project build policy

File path:
build.gradle or gradle.properties

Purpose:
Record the chosen Minecraft and NeoForge versions explicitly when implementation starts.

Required values:
- minecraft_version
- neoforge_version
- mod_id
- mod_version
- java_version

Definition of done:
The project build file clearly targets Minecraft Java 26.1 and NeoForge 26.1 unless a later verified stable target is chosen.

Task P5 — Add version verification checklist

File path:
docs/version-verification-checklist.md

Purpose:
Prevent blind upgrading.

Checklist:
- Confirm latest stable Minecraft Java release.
- Confirm matching NeoForge version exists.
- Confirm required Java version.
- Confirm mappings/toolchain changes.
- Confirm dedicated server launches.
- Confirm test mod loads.
- Confirm long-run simulation test passes.
- Confirm save files migrate correctly.

Definition of done:
Every Minecraft version bump must complete this checklist before becoming the main target.

59. Scope Correction — Ecosystem-Only Mod Direction

Date added: 05 June 2026

Decision:
The Living World mod is now defined as an ecosystem-focused world evolution mod. It must not become an NPC civilisation simulator.

This means the mod should focus on environmental systems, landscape change, resource pressure, pollution, soil health, water quality, biome pressure, vegetation spread, decay, recovery, erosion-style effects, and long-term ecological consequences.

Removed from core scope:

- No custom NPC civilisation simulation.
- No autonomous villagers.
- No village growth system.
- No settlement AI.
- No faction diplomacy.
- No wars.
- No NPC economy.
- No wildlife population simulation as a primary system.
- No direct modification of vanilla villager behaviour.
- No requirement to alter passive mobs, hostile mobs, or animal spawning for the core mod.

Allowed only as optional future addons:

- Compatibility hooks for existing village mods.
- Optional data export that other civilisation mods can read.
- Optional environmental effects that indirectly influence mob spawning if the server owner enables them.
- Optional addon modules for settlements or factions, kept outside the ecosystem core.

New primary focus:

1. Region ecosystem state
Each region stores ecosystem health values such as soil quality, moisture, vegetation density, water quality, pollution, decay, recovery pressure, temperature pressure, and resource depletion.

2. Vegetation and plant pressure
The world can slowly gain or lose vegetation based on region conditions. This should include grass spread, sapling success chance, forest pressure, dead-zone formation, invasive overgrowth, and recovery after damage.

3. Soil system
Soil should not be treated as permanent perfect dirt. Regions track soil fertility, compaction, contamination, moisture, and exhaustion. Farming, deforestation, overuse, fire, pollution, and lack of vegetation can reduce soil quality.

4. Water system
Water quality is tracked at region level. Pollution near water, industrial blocks, mass farming, decay, and runoff can lower water quality. Clean neighbouring regions and rainfall-style recovery can improve it.

5. Pollution system
Pollution is one of the main simulation drivers. It should spread slowly through neighbouring regions, decay over time, and create visible consequences when thresholds are crossed.

6. Decomposition and decay
Organic material, fallen leaves, dead vegetation, and abandoned player impact should feed back into soil quality or disease/rot pressure. The world should feel like matter cycles through the environment.

7. Resource depletion
Mining, quarrying, logging, farming, and repeated harvesting should reduce local resource scores. Regions should remember that they have been heavily exploited.

8. Recovery and succession
Damaged areas should recover through ecological succession: barren ground becomes sparse grass, sparse grass becomes scrub, scrub becomes young woodland, and young woodland becomes mature forest where conditions allow.

9. Climate and seasonal pressure
The core ecosystem may use seasonal modifiers and climate pressure, but this should remain environmental. It should not require animal or NPC simulation.

10. Visible world feedback
The mod should eventually apply changes to loaded chunks, such as grass becoming coarse dirt, dirt becoming barren dirt, vegetation spreading, polluted water indicators, moss growth, dead vegetation, regrowth zones, and biome-edge transformation.

Updated module list:

Core required modules:

- Core Simulation
- Regions
- Persistence
- Event Bus
- Time System
- Debug Tools
- Ecosystem Metrics
- Soil System
- Water Quality System
- Pollution System
- Vegetation System
- Resource Depletion System
- Recovery/Succession System
- Visible World Effects System
- Configuration
- Profiling and Testing

Removed or postponed modules:

- Settlements
- Factions
- NPC population
- Villager behaviour
- War system
- NPC economy
- Road generation
- Trade networks
- Wildlife simulation

Architecture impact:

The existing modular architecture remains valid, but the module package list must be simplified. The project should not spend time designing settlement AI, diplomacy, NPC jobs, village growth, or faction systems. Those are distractions from the actual goal.

New recommended package structure:

com.livingworld

api
bootstrap
config
core
data
events
regions
commands
debug
networking
platform
integration.minecraft
modules.ecosystem
modules.soil
modules.water
modules.pollution
modules.vegetation
modules.resources
modules.recovery
modules.worldeffects
testing

Updated Volume 1 rule:
The foundation must support modules, but Volume 1 examples should stop assuming future settlement, faction, economy, or wildlife modules. Future examples should use ecosystem modules instead.

Example module update order:

1. Climate pressure
2. Water quality
3. Soil quality
4. Pollution spread
5. Resource depletion
6. Vegetation pressure
7. Recovery and succession
8. Visible world effects
9. History/logging

Updated first playable prototype:

The first playable version should do this:

- Divide the world into regions.
- Track ecosystem health per region.
- Track pollution per region.
- Track soil quality per region.
- Track vegetation pressure per region.
- Save and load those values.
- Provide /lw region info.
- Allow /lw simulate ticks.
- Apply one visible effect in loaded chunks.

First visible effect:
If region pollution is high and soil quality is low, grass blocks in loaded chunks slowly degrade into dirt or coarse dirt.

Second visible effect:
If region vegetation pressure is high and soil quality is healthy, grass, moss, flowers, or saplings have a small chance to spread in loaded chunks.

Third visible effect:
If a region has been heavily logged, natural tree regrowth slows until soil and vegetation pressure recover.

New project identity:
This mod is not Minecraft Eco with villagers. It is Minecraft as a changing ecosystem. The player should feel that the land itself remembers damage, recovers slowly, spreads life where conditions are good, and degrades where conditions are abused.

Design sentence:
The Living World mod makes the environment evolve over time without adding civilisation simulation.

60. AI Prompt Pack — Local Model Workflow for Each Build Step

Date added: 05 June 2026

Purpose:
This section gives copy-and-paste prompts for local AI development using Qwen3.5-9B as the main coding worker and Qwen3.6-27B as the planner, reviewer, debugger, and architecture guard.

Model usage rule:

- Use Qwen3.5-9B for small, isolated implementation tasks.
- Use Qwen3.6-27B for architecture decisions, reviewing several files at once, diagnosing difficult errors, and checking that the code still follows the design.
- Do not ask Qwen3.5-9B to build broad systems.
- Do not waste Qwen3.6-27B on tiny one-class tasks unless Qwen3.5-9B fails twice.

General 9B worker prompt template:

Use this when asking Qwen3.5-9B to create or edit one file.

MODEL: Qwen3.5-9B

PROMPT:
You are implementing one small Java task for a Minecraft NeoForge mod called Living World.

Important project rules:
- Core simulation code must be plain Java wherever possible.
- Do not import Minecraft or NeoForge classes unless this specific task says to.
- Do not create extra systems beyond the task.
- Keep the code small and testable.
- Follow the package path exactly.
- Use clear names.
- Add validation where requested.
- If tests are requested, write the tests too.

Task:
[PASTE TASK HERE]

Output required:
1. Brief explanation of what files you will create or edit.
2. Full code for each file.
3. Any test code required.
4. Notes about assumptions.

Do not skip requirements.
Do not add unrelated features.

General 27B architect/reviewer prompt template:

Use this when asking Qwen3.6-27B to review multiple files, fix design drift, or plan the next batch.

MODEL: Qwen3.6-27B

PROMPT:
You are the senior architect reviewing the Living World Minecraft NeoForge mod.

Project direction:
This is an ecosystem-only world evolution mod. It does not simulate villagers, NPC civilisations, settlements, factions, wars, trade, roads, or wildlife AI.

Architecture rules:
- Core simulation must remain plain Java where possible.
- Minecraft and NeoForge code must stay in platform or integration packages.
- Regions are the main simulation unit, not chunks.
- Modules must communicate through services, events, or public data contracts.
- Save data must be versioned.
- Debug and tests are mandatory.

Review these files:
[PASTE FILES OR SUMMARIES]

Check for:
1. Incorrect Minecraft/NeoForge imports in core classes.
2. Scope creep into NPCs, factions, roads, or settlements.
3. Broken package boundaries.
4. Missing validation.
5. Bad lifecycle handling.
6. Save/versioning issues.
7. Test gaps.
8. Overly broad or fragile code.

Output required:
1. Pass/fail summary.
2. Specific problems by file.
3. Exact fixes.
4. Revised code only where necessary.
5. Recommended next task.

61. Milestone 1 AI Prompts — Project Skeleton

Task 1.1 prompt — Create base mod package

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/LivingWorldMod.java for a Minecraft NeoForge mod called Living World.

Requirements:
- Package: com.livingworld
- Class name: LivingWorldMod
- Define public static final String MOD_ID using LivingWorldConstants.MOD_ID if that class already exists. If it does not exist yet, temporarily define MOD_ID = "livingworld" and add a TODO to replace it after constants are created.
- This class must contain only entrypoint wiring.
- It must not contain simulation logic.
- It must log a startup message.
- It must delegate startup work to com.livingworld.bootstrap.LivingWorldBootstrap if available.
- If NeoForge annotations/imports are needed, keep them only in this entrypoint file.

Output:
- Full Java file.
- Any assumptions about the NeoForge version.
- Do not create unrelated classes.

Task 1.2 prompt — Create bootstrap class

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/bootstrap/LivingWorldBootstrap.java.

Requirements:
- Package: com.livingworld.bootstrap
- Class name: LivingWorldBootstrap
- Methods:
- void initialize()
- void onCommonSetup()
- void onServerStarting()
- void onServerStarted()
- void onServerStopping()
- Each method should log its lifecycle stage.
- Use LivingWorldLogger if available. If not available yet, use a minimal temporary logger comment and no System.out.
- Do not add gameplay logic.
- Do not create region, ecosystem, or persistence systems yet.

Output:
- Full Java file.
- Short explanation of where it should be called from.

Task 1.3 prompt — Create package placeholders

MODEL: Qwen3.5-9B

PROMPT:
Create the package placeholder structure for the Living World mod.

Packages:
- com.livingworld.api
- com.livingworld.bootstrap
- com.livingworld.config
- com.livingworld.core
- com.livingworld.core.lifecycle
- com.livingworld.core.registry
- com.livingworld.core.services
- com.livingworld.core.simulation
- com.livingworld.data
- com.livingworld.data.saved
- com.livingworld.data.migration
- com.livingworld.data.serialization
- com.livingworld.events
- com.livingworld.regions
- com.livingworld.regions.cache
- com.livingworld.regions.query
- com.livingworld.commands
- com.livingworld.debug
- com.livingworld.networking
- com.livingworld.platform
- com.livingworld.platform.neoforge
- com.livingworld.integration.minecraft
- com.livingworld.modules
- com.livingworld.modules.ecosystem
- com.livingworld.modules.soil
- com.livingworld.modules.water
- com.livingworld.modules.pollution
- com.livingworld.modules.vegetation
- com.livingworld.modules.resources
- com.livingworld.modules.recovery
- com.livingworld.modules.worldeffects
- com.livingworld.testing

If Java requires at least one file per package in this project setup, create a package-info.java file with a one-line comment for each package.

Do not add implementation logic.

Task 1.4 prompt — Create constants

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/LivingWorldConstants.java.

Requirements:
- Package: com.livingworld.core
- Final utility class.
- Private constructor.
- Constants:
- public static final String MOD_ID = "livingworld";
- public static final String MOD_NAME = "Living World";
- public static final int CURRENT_CORE_SCHEMA_VERSION = 1;
- public static final int DEFAULT_REGION_SIZE_CHUNKS = 8;
- public static final int DEFAULT_SIMULATION_INTERVAL_TICKS = 100;
- Do not import Minecraft or NeoForge classes.
- Add short comments explaining each constant.

Output:
- Full Java file.

Milestone 1 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review the completed Milestone 1 project skeleton for the Living World ecosystem mod.

Files to review:
[PASTE LivingWorldMod.java, LivingWorldBootstrap.java, LivingWorldConstants.java, and package list]

Check:
- Entrypoint contains no simulation logic.
- Bootstrap owns startup flow.
- Constants are centralised.
- No ecosystem/NPC/settlement/faction systems were added early.
- Minecraft/NeoForge imports are restricted to entrypoint or platform boundary.

Output:
- Pass/fail.
- Required fixes.
- Next safe milestone.

62. Milestone 2 AI Prompts — Logging and Diagnostics

Task 2.1 prompt — Create logger wrapper

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/debug/LivingWorldLogger.java.

Requirements:
- Package: com.livingworld.debug
- Class name: LivingWorldLogger
- Provide static methods:
- info(String message)
- warn(String message)
- error(String message)
- error(String message, Throwable throwable)
- debug(String message)
- info(DiagnosticCategory category, String message)
- warn(DiagnosticCategory category, String message)
- error(DiagnosticCategory category, String message)
- debug(DiagnosticCategory category, String message)
- Use a standard logger appropriate for the mod environment if available.
- Do not use System.out.
- If debug config does not exist yet, allow debug messages for now and add a TODO to wire config later.
- Do not import ecosystem module classes.

Output:
- Full Java file.

Task 2.2 prompt — Create diagnostic category enum

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/debug/DiagnosticCategory.java.

Requirements:
- Package: com.livingworld.debug
- Enum values:
- BOOTSTRAP
- CONFIG
- REGIONS
- SIMULATION
- PERSISTENCE
- EVENTS
- MODULES
- COMMANDS
- NETWORKING
- PLATFORM
- ECOSYSTEM
- TESTING
- Add a method displayName() that returns a readable name.
- Do not import Minecraft or NeoForge classes.

Output:
- Full Java enum.

Milestone 2 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review the logging and diagnostics foundation.

Files:
[PASTE LivingWorldLogger.java and DiagnosticCategory.java]

Check:
- No System.out usage.
- Logger methods are consistent.
- Categories match the ecosystem-only architecture.
- No unnecessary Minecraft imports.
- Debug behaviour can later connect to config.

Output:
- Problems found.
- Recommended fixes.
- Whether Milestone 3 can begin.

63. Milestone 3 AI Prompts — Configuration Foundation

Task 3.1 prompt — Create SimulationConfig

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/config/SimulationConfig.java.

Requirements:
- Plain Java class.
- Fields:
- int regionSizeChunks = 8
- int simulationIntervalTicks = 100
- int maxRegionsPerCycle = 50
- int maxMillisecondsPerCycle = 25
- int emergencyStopMilliseconds = 40
- boolean enableDebugCommands = true
- boolean enableProfiler = true
- Add getters.
- Add setters only if needed for tests.
- Add validate() method.
- Validation rules:
- regionSizeChunks >= 1
- simulationIntervalTicks >= 1
- maxRegionsPerCycle >= 1
- maxMillisecondsPerCycle >= 1
- emergencyStopMilliseconds >= maxMillisecondsPerCycle
- Throw IllegalArgumentException with clear messages on invalid values.
- Do not import Minecraft or NeoForge classes.

Output:
- Full Java file.
- Basic test suggestions.

Task 3.2 prompt — Create ConfigService interface

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/services/ConfigService.java.

Requirements:
- Interface.
- Methods:
- SimulationConfig getSimulationConfig()
- void reload()
- void validate()
- Import SimulationConfig from com.livingworld.config.
- Do not reference NeoForge config APIs here.

Output:
- Full Java interface.

Task 3.3 prompt — Create DefaultConfigService

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/config/DefaultConfigService.java.

Requirements:
- Implements ConfigService.
- Holds a SimulationConfig instance.
- Constructor creates default SimulationConfig and validates it.
- getSimulationConfig returns the config.
- reload can be a safe placeholder for now, but it must revalidate.
- validate delegates to SimulationConfig.validate().
- Log validation success using LivingWorldLogger if available.
- Do not use NeoForge config classes yet.

Output:
- Full Java file.

Milestone 3 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review the configuration foundation for the Living World ecosystem mod.

Files:
[PASTE SimulationConfig.java, ConfigService.java, DefaultConfigService.java]

Check:
- Config is plain Java.
- Validation is strict and clear.
- No direct NeoForge dependency yet.
- Defaults match the design document.
- Future Forge/NeoForge config wiring can be added without rewriting core code.

Output:
- Pass/fail.
- Required fixes.
- Any missing config values for ecosystem-only MVP.

64. Milestone 4 AI Prompts — Core Service Registry

Task 4.1 prompt — Create ServiceKey

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/services/ServiceKey.java.

Requirements:
- Generic immutable value object.
- Prefer Java record if project Java version supports it.
- Fields:
- String id
- Class<T> serviceType
- Validate id is not null or blank.
- Validate serviceType is not null.
- Add stable toString().
- Do not import Minecraft or NeoForge classes.

Output:
- Full Java file.

Task 4.2 prompt — Create ServiceRegistry

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/services/ServiceRegistry.java.

Requirements:
- Plain Java class.
- Internally store services by ServiceKey.
- Methods:
- <T> void register(ServiceKey<T> key, T service)
- <T> T get(ServiceKey<T> key)
- <T> Optional<T> find(ServiceKey<T> key)
- boolean isRegistered(ServiceKey<?> key)
- void lock()
- boolean isLocked()
- Reject duplicate registrations.
- Reject null keys and null services.
- If locked, reject new registrations.
- Missing get() should throw clear IllegalStateException.
- No Minecraft imports.

Output:
- Full Java file.
- Suggested unit tests.

Task 4.3 prompt — Create CoreServices

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/services/CoreServices.java.

Requirements:
- Final utility class with private constructor.
- Define ServiceKey constants for:
- CONFIG
- REGIONS
- SIMULATION
- PERSISTENCE
- EVENTS
- MODULES
- TIME
- DEBUG
- HISTORY
- If some service interfaces do not exist yet, add TODO comments and create keys only for existing interfaces, or use Object temporarily with clear TODOs.
- Do not create fake gameplay services.
- No Minecraft imports.

Output:
- Full Java file.
- Note any TODOs caused by missing interfaces.

Milestone 4 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review the core service registry.

Files:
[PASTE ServiceKey.java, ServiceRegistry.java, CoreServices.java]

Check:
- Type safety is acceptable.
- Registry cannot be mutated after lock.
- Errors are clear.
- No hidden global state problems.
- No Minecraft imports.
- Design is suitable for module dependency injection later.

Output:
- Pass/fail.
- Fixes.
- Risk notes.

65. Milestone 5 AI Prompts — Region Identity

Task 5.1 prompt — Create RegionCoordinate

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/RegionCoordinate.java.

Requirements:
- Java record if available.
- Fields:
- String dimensionId
- int x
- int z
- Validate dimensionId is not null or blank.
- Static methods:
- fromChunk(String dimensionId, int chunkX, int chunkZ, int regionSizeChunks)
- fromBlock(String dimensionId, int blockX, int blockZ, int regionSizeChunks)
- Instance methods:
- int minChunkX(int regionSizeChunks)
- int minChunkZ(int regionSizeChunks)
- int maxChunkX(int regionSizeChunks)
- int maxChunkZ(int regionSizeChunks)
- int centerBlockX(int regionSizeChunks)
- int centerBlockZ(int regionSizeChunks)
- String stableId()
- Use Math.floorDiv so negative coordinates work correctly.
- Validate regionSizeChunks >= 1.
- Do not import Minecraft classes.

Test requirements:
Create RegionCoordinateTest if test framework exists.
Test:
- block 0,0 maps to region 0,0
- block 127,127 maps to region 0,0 with region size 8 chunks
- block 128,0 maps to region 1,0
- block -1,0 maps to region -1,0
- block -128,0 maps to region -1,0
- block -129,0 maps to region -2,0
- stableId is stable
- works as HashMap key

Output:
- Full Java file.
- Full test file if possible.

Task 5.2 prompt — Create RegionLifecycleState

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/RegionLifecycleState.java.

Requirements:
- Enum values:
- UNLOADED
- LOADING
- ACTIVE
- DIRTY
- SAVING
- FAILED
- UNLOADING
- Add comments explaining each state.
- Do not add methods unless useful.
- No Minecraft imports.

Output:
- Full Java enum.

Task 5.3 prompt — Create RegionFlags

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/RegionFlags.java.

Requirements:
- Plain Java class.
- Fields:
- boolean hasPlayerActivity
- boolean hasHighPollution
- boolean hasLowSoilQuality
- boolean hasActiveEcosystemEvent
- boolean forceLoadedBySimulation
- boolean corrupted
- Do not include settlement, road, faction, or NPC flags.
- Add getters and setters.
- Add copy().
- Add clearTransientFlags(). This should clear hasPlayerActivity and hasActiveEcosystemEvent, but not corrupted.
- No Minecraft imports.

Output:
- Full Java file.

Milestone 5 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review region identity classes.

Files:
[PASTE RegionCoordinate.java, RegionLifecycleState.java, RegionFlags.java, and tests]

Check:
- Negative coordinate math is correct.
- No Minecraft classes leaked into region core.
- Flags match ecosystem-only scope.
- RegionCoordinate is safe as a HashMap key.
- Tests cover edge cases.

Output:
- Pass/fail.
- Exact fixes if needed.

66. Milestone 6 AI Prompts — Region Core Data

Task 6.1 prompt — Create RegionMetrics

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/RegionMetrics.java.

Requirements:
- Plain Java class.
- Ecosystem-only fields:
- double ecosystemHealth
- double pollutionScore
- double soilQuality
- double waterQuality
- double vegetationPressure
- double resourceDepletion
- double recoveryPressure
- Values should normally be clamped between 0 and 100.
- Add normalize().
- Add copy().
- Add static defaults().
- Defaults:
- ecosystemHealth = 60
- pollutionScore = 0
- soilQuality = 60
- waterQuality = 60
- vegetationPressure = 50
- resourceDepletion = 0
- recoveryPressure = 50
- Add applyDelta methods if simple and clean.
- No Minecraft imports.

Output:
- Full Java file.
- Suggested tests.

Task 6.2 prompt — Create RegionModuleData

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/RegionModuleData.java.

Requirements:
- Stores module-specific data by module ID.
- Field:
- Map<String, Object> moduleData
- Methods:
- void put(String moduleId, Object data)
- <T> Optional<T> get(String moduleId, Class<T> type)
- boolean contains(String moduleId)
- Set<String> moduleIds()
- RegionModuleData copyShallow()
- Validate moduleId is not null or blank.
- Reject null data.
- If get type does not match, return Optional.empty instead of throwing.
- No Minecraft imports.

Output:
- Full Java file.

Task 6.3 prompt — Create Region

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/Region.java.

Requirements:
- Plain Java class.
- Fields:
- UUID id
- RegionCoordinate coordinate
- RegionLifecycleState lifecycleState
- long createdAtSimulationTick
- long lastUpdatedSimulationTick
- boolean dirty
- RegionFlags flags
- RegionMetrics metrics
- RegionModuleData moduleData
- Constructor validates required fields.
- Methods:
- markDirty()
- clearDirty()
- isDirty()
- updateLastSimulatedTick(long tick)
- setLifecycleState(RegionLifecycleState state)
- validate()
- validate() checks id, coordinate, lifecycleState, flags, metrics, and moduleData are not null.
- Do not include settlement, faction, road, or NPC fields.
- No Minecraft imports.

Output:
- Full Java file.

Milestone 6 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review the region core data classes.

Files:
[PASTE RegionMetrics.java, RegionModuleData.java, Region.java]

Check:
- Metrics match ecosystem-only scope.
- Region is not bloated with future unrelated systems.
- Validation is strong.
- Dirty state behaviour is sensible.
- No Minecraft imports.
- No direct persistence logic inside Region.

Output:
- Pass/fail.
- Exact corrections.

67. Milestone 7 AI Prompts — Region Creation and Lifecycle

Task 7.1 prompt — Create RegionLifecycleController

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/RegionLifecycleController.java.

Requirements:
- Plain Java class.
- Methods:
- boolean canTransition(RegionLifecycleState from, RegionLifecycleState to)
- void transition(Region region, RegionLifecycleState target)
- Allowed transitions:
- UNLOADED -> LOADING
- LOADING -> ACTIVE
- LOADING -> FAILED
- ACTIVE -> DIRTY
- DIRTY -> SAVING
- SAVING -> ACTIVE
- SAVING -> FAILED
- ACTIVE -> UNLOADING
- UNLOADING -> UNLOADED
- FAILED -> LOADING
- Invalid transitions throw IllegalStateException with clear message.
- transition() must validate region is not null.
- No Minecraft imports.

Output:
- Full Java file.
- Suggested tests.

Task 7.2 prompt — Create RegionFactory

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/RegionFactory.java.

Requirements:
- Plain Java class.
- Method:
- Region createNewRegion(RegionCoordinate coordinate, long simulationTick)
- New region rules:
- random UUID
- coordinate from argument
- lifecycleState ACTIVE
- createdAtSimulationTick = simulationTick
- lastUpdatedSimulationTick = simulationTick
- dirty = true
- default RegionFlags
- RegionMetrics.defaults()
- empty RegionModuleData
- validate before return
- No Minecraft imports.
- Do not initialise ecology modules here yet; that comes after ModuleRegistry is connected.

Output:
- Full Java file.

Milestone 7 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review lifecycle and region creation.

Files:
[PASTE RegionLifecycleController.java and RegionFactory.java]

Check:
- Invalid transitions are rejected.
- New regions are immediately dirty.
- Factory does not import Minecraft classes.
- Factory does not start implementing ecosystem gameplay prematurely.
- Tests cover valid and invalid transitions.

Output:
- Pass/fail.
- Fixes.

68. Milestone 8 AI Prompts — Module Contracts

Task 8.1 prompt — Create SimulationModule interface

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/modules/SimulationModule.java.

Requirements:
- Interface.
- Methods:
- String getModuleId()
- ModuleMetadata getMetadata()
- void initialize(ModuleContext context)
- void onServerStarted(ServerContext context)
- void createDefaultRegionData(Region region)
- ModuleUpdateResult updateRegion(RegionUpdateContext context)
- void onLivingWorldEvent(LivingWorldEvent event)
- void saveModuleData(PersistenceWriter writer)
- void loadModuleData(PersistenceReader reader)
- void shutdown()
- Create minimal placeholder interfaces/classes if missing:
n - ServerContext
- RegionUpdateContext
- LivingWorldEvent
- PersistenceWriter
- PersistenceReader
- Do not implement any real ecosystem module yet.
- No Minecraft imports in this interface.

Output:
- Full Java interface.
- Any minimal placeholder files required.

Task 8.2 prompt — Create ModuleMetadata

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/modules/ModuleMetadata.java.

Requirements:
- Immutable class or record.
- Fields:
- String moduleId
- String displayName
- String version
- String description
- String requiredCoreVersion
- List<String> dependencies
- List<String> optionalDependencies
- boolean defaultEnabled
- boolean serverOnly
- boolean experimental
- Validate moduleId and displayName are not blank.
- Replace null dependency lists with empty lists.
- No Minecraft imports.

Output:
- Full Java file.

Task 8.3 prompt — Create ModuleContext

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/modules/ModuleContext.java.

Requirements:
- Plain Java class.
- Field:
- ServiceRegistry services
- Constructor validates services is not null.
- Method:
- <T> T getService(ServiceKey<T> key)
- Do not expose the whole registry for mutation if avoidable.
- No Minecraft imports.

Output:
- Full Java file.

Task 8.4 prompt — Create ModuleUpdateResult

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/modules/ModuleUpdateResult.java.

Requirements:
- Immutable class or record.
- Fields:
- boolean changedRegion
- List<LivingWorldEvent> generatedEvents
- List<HistoryRecord> historyRecords
- int estimatedCost
- List<String> warnings
- Static constructors:
- noChange()
- changed()
- Null lists become empty lists.
- estimatedCost must not be negative.
- No Minecraft imports.

If HistoryRecord does not exist, create a minimal placeholder in com.livingworld.modules or com.livingworld.events with TODO to move later.

Output:
- Full Java file.
- Any placeholder file required.

Task 8.5 prompt — Create ModuleRegistry

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/modules/ModuleRegistry.java.

Requirements:
- Plain Java class.
- Responsibilities:
- register modules
- reject duplicate module IDs
- return all modules
- return enabled modules
- find by module ID
- initialize all
- shutdown all
- Methods:
- void register(SimulationModule module)
- List<SimulationModule> getAllModules()
- List<SimulationModule> getEnabledModules()
- Optional<SimulationModule> find(String moduleId)
- void initializeAll(ModuleContext context)
- void shutdownAll()
- For v1, enabled modules are modules where metadata.defaultEnabled is true.
- Do not implement dependency sorting yet; add TODO.
- No Minecraft imports.

Output:
- Full Java file.

Milestone 8 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review module contract architecture.

Files:
[PASTE SimulationModule.java, ModuleMetadata.java, ModuleContext.java, ModuleUpdateResult.java, ModuleRegistry.java]

Check:
- Modules are generic and not tied to settlements/factions/NPCs.
- Core module contracts do not import Minecraft classes.
- ModuleRegistry is simple enough for v1.
- Missing placeholders are sensible and marked as TODO.
- Architecture supports ecosystem modules later.

Output:
- Pass/fail.
- Required fixes.
- Next implementation task.

69. Milestone 9 AI Prompts — Event Foundation

Task 9.1 prompt — Create LivingWorldEvent

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/events/LivingWorldEvent.java.

Requirements:
- Interface.
- Methods:
- String eventType()
- long simulationTick()
- String sourceModuleId()
- No Minecraft imports.
- Events must be usable by ecosystem modules later.

Output:
- Full Java interface.

Task 9.2 prompt — Create BaseLivingWorldEvent

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/events/BaseLivingWorldEvent.java.

Requirements:
- Immutable class or record implementing LivingWorldEvent.
- Fields:
- String eventType
- long simulationTick
- String sourceModuleId
- Validate eventType is not blank.
- Validate simulationTick is not negative.
- sourceModuleId may be "core" for core events but must not be blank.
- No Minecraft imports.

Output:
- Full Java file.

Task 9.3 prompt — Create LivingWorldEventListener

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/events/LivingWorldEventListener.java.

Requirements:
- Functional interface.
- Method:
- void onEvent(LivingWorldEvent event)
- No Minecraft imports.

Output:
- Full Java interface.

Task 9.4 prompt — Create LivingWorldEventBus

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/events/LivingWorldEventBus.java.

Requirements:
- Plain Java class.
- Methods:
- void register(String eventType, LivingWorldEventListener listener)
- void publish(LivingWorldEvent event)
- int getPublishedEventCount()
- int getListenerCount(String eventType)
- Validate eventType is not blank.
- Validate listener is not null.
- Event publishing should send the event to listeners registered for that event type.
- Unknown event type should not crash.
- Prevent obvious recursive event storms with a simple dispatching guard or TODO if not implemented.
- No Minecraft imports.

Output:
- Full Java file.
- Suggested tests.

Milestone 9 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review the Living World event foundation.

Files:
[PASTE LivingWorldEvent.java, BaseLivingWorldEvent.java, LivingWorldEventListener.java, LivingWorldEventBus.java]

Check:
- Events are plain Java.
- EventBus is not overcomplicated.
- Unknown events are safe.
- Recursion risk is noted or controlled.
- Event types can support pollution/soil/vegetation events later.

Output:
- Pass/fail.
- Fixes.

70. Milestone 10 AI Prompts — Time Service

Task 10.1 prompt — Create LivingWorldCalendar

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/simulation/LivingWorldCalendar.java.

Requirements:
- Plain Java class.
- Fields:
- long simulationTick
- int day
- int month
- int year
- Default start: day 1, month 1, year 1, simulationTick 0.
- Methods:
- advanceTicks(long ticks)
- copy()
- toDisplayString()
- Keep the calendar simple for now.
- Use 30 days per month and 12 months per year unless config is added later.
- No Minecraft imports.

Output:
- Full Java file.

Task 10.2 prompt — Create TimeService interface

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/services/TimeService.java.

Requirements:
- Interface.
- Methods:
- long getSimulationTick()
- LivingWorldCalendar getCalendar()
- void advanceSimulationTick()
- void advanceSimulationTicks(long ticks)
- No Minecraft imports.

Output:
- Full Java interface.

Task 10.3 prompt — Create DefaultTimeService

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/simulation/DefaultTimeService.java.

Requirements:
- Implements TimeService.
- Owns a LivingWorldCalendar.
- advanceSimulationTick advances by 1.
- advanceSimulationTicks validates ticks >= 0 and advances calendar.
- getCalendar returns a copy, not the internal mutable instance.
- No Minecraft imports.

Output:
- Full Java file.

Milestone 10 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review the Living World time system.

Files:
[PASTE LivingWorldCalendar.java, TimeService.java, DefaultTimeService.java]

Check:
- Time is independent of Minecraft classes.
- Calendar cannot be mutated externally by accident.
- Behaviour is deterministic.
- Good enough for ecosystem simulation v1.

Output:
- Pass/fail.
- Fixes.

71. Milestone 11 AI Prompts — Scheduler and Simulation Manager

Task 11.1 prompt — Create UpdateReason

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/simulation/UpdateReason.java.

Requirements:
- Enum values:
- NORMAL_ROLLING_UPDATE
- PLAYER_NEARBY
- HIGH_POLLUTION
- LOW_SOIL_QUALITY
- ACTIVE_ECOSYSTEM_EVENT
- FORCED_DEBUG_COMMAND
- SAVE_MIGRATION_REQUIRED
- Do not include settlement, road, faction, or NPC update reasons.
- No Minecraft imports.

Output:
- Full Java enum.

Task 11.2 prompt — Create RegionUpdateJob

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/simulation/RegionUpdateJob.java.

Requirements:
- Immutable class or record.
- Fields:
- RegionCoordinate coordinate
- int priority
- long queuedAtSimulationTick
- Set<String> requestedModules
- UpdateReason reason
- Validate coordinate and reason are not null.
- priority must not be negative.
- queuedAtSimulationTick must not be negative.
- Null requestedModules becomes empty set.
- Add comparator for descending priority if clean.
- No Minecraft imports.

Output:
- Full Java file.

Task 11.3 prompt — Create RegionPriorityCalculator

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/simulation/RegionPriorityCalculator.java.

Requirements:
- Plain Java class.
- Method:
- int calculatePriority(Region region)
- Initial ecosystem-only scoring:
- base = 5
- hasPlayerActivity bonus = 100
- hasActiveEcosystemEvent bonus = 75
- hasHighPollution bonus = 50
- hasLowSoilQuality bonus = 50
- pollution bonus = pollutionScore / 2
- resource depletion bonus = resourceDepletion / 3
- recovery pressure bonus = recoveryPressure / 4
- Validate region is not null.
- Result should be deterministic.
- No Minecraft imports.

Output:
- Full Java file.

Task 11.4 prompt — Create SimulationScheduler

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/simulation/SimulationScheduler.java.

Requirements:
- Plain Java class.
- Constructor accepts SimulationConfig.
- Fields:
- long minecraftTickCounter
- long simulationTickCounter
- PriorityQueue<RegionUpdateJob> updateQueue
- Methods:
- void onMinecraftTick()
- boolean shouldRunSimulationCycle()
- void queueRegion(RegionUpdateJob job)
- List<RegionUpdateJob> pollJobsForCycle()
- long getMinecraftTickCounter()
- long getSimulationTickCounter()
- shouldRunSimulationCycle true when minecraftTickCounter reaches the configured interval.
- pollJobsForCycle returns at most maxRegionsPerCycle jobs.
- Higher priority jobs first.
- No Minecraft imports.

Output:
- Full Java file.
- Suggested scheduler budget tests.

Task 11.5 prompt — Create SimulationManager skeleton

MODEL: Qwen3.6-27B

PROMPT:
Create the first version of src/main/java/com/livingworld/core/simulation/SimulationManager.java.

This is an architecture-sensitive class. Keep it boring and coordinator-only.

Requirements:
- Constructor dependencies:
- SimulationScheduler scheduler
- RegionManager regionManager
- ModuleRegistry moduleRegistry
- LivingWorldEventBus eventBus
- TimeService timeService
- PersistenceService persistenceService
- SimulationProfiler profiler, if available. If not available, make it optional or TODO.
- Methods:
- void onMinecraftServerTick()
- void runSimulationCycle()
- void runForcedSimulationTicks(int ticks)
- Responsibilities:
- Advance scheduler on Minecraft tick.
- If scheduler says cycle should run, run one cycle.
- Poll region update jobs.
- Resolve regions from RegionManager.
- Run enabled modules in order.
- Publish generated events.
- Mark changed regions dirty.
- Advance TimeService.
- Do not implement ecosystem rules here.
- Do not import Minecraft or NeoForge classes.
- Do not scan chunks.

Output:
- Full Java file.
- Any missing interface TODOs.
- Explanation of control flow.

Milestone 11 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review scheduler and SimulationManager.

Files:
[PASTE UpdateReason.java, RegionUpdateJob.java, RegionPriorityCalculator.java, SimulationScheduler.java, SimulationManager.java]

Check:
- No Minecraft imports in scheduler/manager.
- Budgeting is respected.
- SimulationManager contains no gameplay rules.
- Ecosystem-only priority values are correct.
- Forced simulation cannot accidentally lock the server forever.
- Good enough before persistence and region manager are finished.

Output:
- Pass/fail.
- Fixes.
- Next safest step.

72. Milestone 12 AI Prompts — Persistence Foundation

Task 12.1 prompt — Create PersistenceWriter

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/data/serialization/PersistenceWriter.java.

Requirements:
- Interface.
- Methods:
- void writeString(String key, String value)
- void writeInt(String key, int value)
- void writeLong(String key, long value)
- void writeDouble(String key, double value)
- void writeBoolean(String key, boolean value)
- No Minecraft imports.

Output:
- Full Java interface.

Task 12.2 prompt — Create PersistenceReader

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/data/serialization/PersistenceReader.java.

Requirements:
- Interface.
- Methods:
- String readString(String key, String defaultValue)
- int readInt(String key, int defaultValue)
- long readLong(String key, long defaultValue)
- double readDouble(String key, double defaultValue)
- boolean readBoolean(String key, boolean defaultValue)
- No Minecraft imports.

Output:
- Full Java interface.

Task 12.3 prompt — Create SaveMetadata

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/data/saved/SaveMetadata.java.

Requirements:
- Immutable class or record.
- Fields:
- int schemaVersion
- String modVersion
- long createdAt
- long updatedAt
- Validate schemaVersion > 0.
- Validate modVersion is not blank.
- Validate updatedAt >= createdAt.
- No Minecraft imports.

Output:
- Full Java file.

Task 12.4 prompt — Create PersistenceService interface

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/core/services/PersistenceService.java.

Requirements:
- Interface.
- Methods:
- void markRegionDirty(Region region)
- void saveDirtyRegions()
- Optional<Region> loadRegion(RegionCoordinate coordinate)
- void saveRegion(Region region)
- void flushAll()
- No Minecraft imports.
- Do not implement file storage yet.

Output:
- Full Java interface.

Milestone 12 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review persistence foundation.

Files:
[PASTE PersistenceWriter.java, PersistenceReader.java, SaveMetadata.java, PersistenceService.java]

Check:
- Persistence interfaces are plain Java.
- Region persistence is abstracted.
- Save metadata is versioned.
- No module writes files directly.
- Good enough before JSON/NBT implementation.

Output:
- Pass/fail.
- Fixes.

73. Milestone 13 AI Prompts — Region Storage and Manager

Task 13.1 prompt — Create RegionStorage

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/RegionStorage.java.

Requirements:
- Plain Java class.
- Constructor dependency:
- PersistenceService persistenceService
- Methods:
- Optional<Region> load(RegionCoordinate coordinate)
- void save(Region region)
- load delegates to persistenceService.loadRegion.
- save delegates to persistenceService.saveRegion.
- Validate dependencies and arguments.
- No Minecraft imports.

Output:
- Full Java file.

Task 13.2 prompt — Create RegionCache

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/cache/RegionCache.java.

Requirements:
- Plain Java class.
- Field:
- Map<RegionCoordinate, Region> activeRegions
- Methods:
- Optional<Region> get(RegionCoordinate coordinate)
- void put(Region region)
- void remove(RegionCoordinate coordinate)
- Collection<Region> allActive()
- int size()
- Validate inputs.
- allActive should return an unmodifiable copy or safe view.
- No Minecraft imports.

Output:
- Full Java file.

Task 13.3 prompt — Create RegionQueryEngine

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/regions/query/RegionQueryEngine.java.

Requirements:
- Plain Java class.
- Constructor dependency:
- RegionCache cache
- Methods:
- Optional<Region> getRegion(RegionCoordinate coordinate)
- List<Region> getRegionsInRadius(RegionCoordinate center, int radius)
- List<Region> getRegionsWithActiveEcosystemEvent()
- List<Region> getRegionsAbovePollution(double threshold)
- List<Region> getRegionsBelowSoilQuality(double threshold)
- Do not touch Minecraft chunks.
- Radius means region-coordinate radius.
- Validate radius >= 0.
- No settlement, road, faction, or NPC queries.
- No Minecraft imports.

Output:
- Full Java file.

Task 13.4 prompt — Create RegionManager

MODEL: Qwen3.6-27B

PROMPT:
Create src/main/java/com/livingworld/regions/RegionManager.java.

This is a core architecture class. Keep it clean and plain Java.

Dependencies:
- RegionFactory regionFactory
- RegionStorage regionStorage
- RegionCache regionCache
- RegionQueryEngine queryEngine
- RegionLifecycleController lifecycleController
- SimulationConfig simulationConfig

Methods:
- Region getOrCreateRegion(RegionCoordinate coordinate)
- Optional<Region> findRegion(RegionCoordinate coordinate)
- Region getOrCreateRegionAtBlock(String dimensionId, int blockX, int blockZ)
- Collection<Region> getActiveRegions()
- void markDirty(Region region)
- void unloadRegion(RegionCoordinate coordinate)

Rules:
- getOrCreate first checks cache.
- If missing, try storage.
- If storage missing, use factory.
- New or modified regions must be marked dirty.
- Do not import Minecraft or NeoForge classes.
- Do not scan chunks.
- Do not apply visible world effects.

Output:
- Full Java file.
- Explanation of load/create flow.
- Edge cases.

Milestone 13 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review RegionStorage, RegionCache, RegionQueryEngine, and RegionManager.

Files:
[PASTE FILES]

Check:
- RegionManager load/create flow is correct.
- No duplicate region instances are likely.
- No Minecraft imports.
- Queries are ecosystem-focused.
- Dirty handling is sensible.
- Region lifecycle transitions are not abused.

Output:
- Pass/fail.
- Fixes.
- Tests to add.

74. Milestone 14 AI Prompts — Debug Commands

Task 14.1 prompt — Create command root

MODEL: Qwen3.6-27B

PROMPT:
Create src/main/java/com/livingworld/commands/LivingWorldCommandRoot.java for a NeoForge Minecraft mod.

This file is allowed to use Minecraft/NeoForge command classes because it is in the commands boundary.

Requirements:
- Register /lw command tree.
- Initial subcommands:
- /lw status
- /lw region info
- /lw modules list
- /lw simulate <ticks>
- If exact NeoForge command registration API is uncertain, create a clean skeleton with TODO comments at API-specific points.
- Command implementation should delegate to service classes where possible.
- Do not place ecosystem simulation rules inside command classes.

Output:
- Full Java file.
- Notes about API assumptions.

Task 14.2 prompt — Create RegionInfoCommand

MODEL: Qwen3.6-27B

PROMPT:
Create src/main/java/com/livingworld/commands/RegionInfoCommand.java.

This class may use Minecraft command/source classes if necessary, but region logic must stay in RegionManager.

Output should include:
- Region coordinate
- Lifecycle state
- Dirty state
- Ecosystem metrics
- Flags
- Module IDs present

Requirements:
- Use RegionManager to get region data.
- Use coordinate mapper or boundary conversion instead of putting Minecraft classes into RegionCoordinate.
- Do not reference settlements, factions, NPCs, roads, or economy.

Output:
- Full Java file.
- API assumptions.

Task 14.3 prompt — Create SimulateCommand

MODEL: Qwen3.6-27B

PROMPT:
Create src/main/java/com/livingworld/commands/SimulateCommand.java.

Requirements:
- Operator-only command.
- Accept tick count.
- Safe maximum default: 1000 ticks.
- Calls SimulationManager.runForcedSimulationTicks(ticks).
- Rejects negative or zero ticks.
- Prints clear success/failure output.
- Does not implement simulation rules itself.

Output:
- Full Java file.
- Notes on NeoForge/Minecraft command API assumptions.

Milestone 14 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review command implementation.

Files:
[PASTE LivingWorldCommandRoot.java, RegionInfoCommand.java, SimulateCommand.java]

Check:
- Minecraft/NeoForge imports are limited to command boundary.
- Commands delegate to services.
- /lw simulate has safety limits.
- Output is useful for debugging ecosystem state.
- No gameplay logic hidden in commands.

Output:
- Pass/fail.
- Fixes.

75. Milestone 15 AI Prompts — Profiling

Task 15.1 prompt — Create SimulationProfiler

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/debug/SimulationProfiler.java.

Requirements:
- Plain Java class.
- Tracks:
- cycle start time
- cycle end time
- per-module timings
- per-region timings if simple
- event count
- save count
- budget overruns
- Methods:
- beginCycle()
- endCycle()
- beginModule(String moduleId)
- endModule(String moduleId)
- recordEvent()
- recordSave()
- recordBudgetOverrun()
- SimulationProfileSnapshot createSnapshot()
- Use System.nanoTime internally for timing.
- Do not use System.out.
- No Minecraft imports.

Output:
- Full Java file.

Task 15.2 prompt — Create SimulationProfileSnapshot

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/debug/SimulationProfileSnapshot.java.

Requirements:
- Immutable class or record.
- Fields:
- long totalCycleNanos
- Map<String, Long> moduleTimings
- int eventsPublished
- int regionsUpdated
- int savesPerformed
- boolean budgetExceeded
- Add method toHumanReadableString().
- No Minecraft imports.

Output:
- Full Java file.

Milestone 15 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review simulation profiling classes.

Files:
[PASTE SimulationProfiler.java and SimulationProfileSnapshot.java]

Check:
- Profiler can measure module cost.
- Snapshot is immutable or safely copied.
- No server-spam logging built in.
- Usable by debug commands later.
- No Minecraft imports.

Output:
- Pass/fail.
- Fixes.

76. Milestone 16 AI Prompts — Tests and Long-Run Validation

Task 16.1 prompt — Create TestSimulationModule

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/testing/TestSimulationModule.java.

Requirements:
- Implements SimulationModule.
- Module ID: test
- Metadata display name: Test Simulation Module
- On initialize, set initialized = true.
- On updateRegion, increment an internal update counter.
- Every 10 updates, return ModuleUpdateResult.changed().
- Otherwise return ModuleUpdateResult.noChange().
- No Minecraft imports.
- This is for engine testing only, not gameplay.

Output:
- Full Java file.

Task 16.2 prompt — Create RegionCoordinateTest

MODEL: Qwen3.5-9B

PROMPT:
Create src/test/java/com/livingworld/regions/RegionCoordinateTest.java.

Tests:
- block 0,0 maps to region 0,0
- block 127,127 maps to region 0,0 with region size 8 chunks
- block 128,0 maps to region 1,0
- block -1,0 maps to region -1,0
- block -128,0 maps to region -1,0
- block -129,0 maps to region -2,0
- stableId remains stable
- RegionCoordinate works as HashMap key

Use the projects test framework. If unknown, assume JUnit 5.

Output:
- Full test file.

Task 16.3 prompt — Create RegionLifecycleControllerTest

MODEL: Qwen3.5-9B

PROMPT:
Create src/test/java/com/livingworld/regions/RegionLifecycleControllerTest.java.

Tests:
- Allowed transitions succeed.
- Invalid transitions throw IllegalStateException.
- FAILED can transition to LOADING.
- ACTIVE cannot transition directly to SAVING.

Use JUnit 5 unless project uses something else.

Output:
- Full test file.

Task 16.4 prompt — Create SchedulerBudgetTest

MODEL: Qwen3.5-9B

PROMPT:
Create src/test/java/com/livingworld/core/simulation/SchedulerBudgetTest.java.

Tests:
- Given 500 jobs and maxRegionsPerCycle 50, one cycle returns 50 jobs.
- Higher priority jobs are returned first.
- Jobs not processed remain queued.
- shouldRunSimulationCycle respects simulationIntervalTicks.

Use JUnit 5 unless project uses something else.

Output:
- Full test file.

Task 16.5 prompt — Create EventBusTest

MODEL: Qwen3.5-9B

PROMPT:
Create src/test/java/com/livingworld/events/EventBusTest.java.

Tests:
- Listener receives event.
- Listener receives event once.
- Multiple listeners receive the event.
- Unknown event type does not crash.

Use BaseLivingWorldEvent for test events.
Use JUnit 5 unless project uses something else.

Output:
- Full test file.

Task 16.6 prompt — Create LongRunSimulationTest

MODEL: Qwen3.6-27B

PROMPT:
Create src/test/java/com/livingworld/testing/LongRunSimulationTest.java.

Purpose:
Prove the foundation can run for a long time without collapsing.

Test setup:
- Create 1000 fake regions.
- Register TestSimulationModule.
- Run 100,000 simulation ticks or a reduced count if local test runtime is too high.
- Save dirty regions periodically using a fake/in-memory PersistenceService.

Pass conditions:
- No crash.
- No unhandled exception.
- No invalid lifecycle transition.
- Dirty region count does not grow forever.
- Profiler reports cycle data.

Requirements:
- Keep it plain Java where possible.
- Do not require a full Minecraft client.
- If full implementation requires missing services, create small in-memory fakes inside the test.

Output:
- Full test file.
- Explanation of any fake services.

Milestone 16 review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review the engine test suite.

Files:
[PASTE all test files and TestSimulationModule.java]

Check:
- Tests cover foundation risks.
- Tests do not require Minecraft client unless absolutely necessary.
- Long-run test is realistic for local hardware.
- Tests catch coordinate, lifecycle, scheduler, event, and simulation failures.
- No NPC/settlement/faction/wildlife scope creep.

Output:
- Pass/fail.
- Missing tests.
- Recommended final fixes before Volume 2.

77. Platform Adapter AI Prompts

Task P1 prompt — Create PlatformAdapter interface

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/platform/PlatformAdapter.java.

Requirements:
- Interface.
- Methods:
- String getPlatformName()
- String getMinecraftVersion()
- String getLoaderVersion()
- boolean isDedicatedServer()
- Path getWorldSaveDirectory()
- void registerCommands()
- void registerServerTickHook()
- void registerPlayerEventHooks()
- Import java.nio.file.Path only.
- No NeoForge imports here.

Output:
- Full Java interface.

Task P2 prompt — Create NeoForgePlatformAdapter skeleton

MODEL: Qwen3.6-27B

PROMPT:
Create src/main/java/com/livingworld/platform/neoforge/NeoForgePlatformAdapter.java.

Purpose:
Implement PlatformAdapter using NeoForge as the active loader.

Rules:
- This class may import NeoForge and Minecraft classes.
- Core simulation classes must not import NeoForge or Minecraft classes.
- If exact NeoForge API names are uncertain for the target version, add clear TODOs at those points instead of inventing unsafe code.
- Must log platform name, Minecraft version, and loader version during bootstrap.
- Must provide hooks that can forward server ticks to SimulationManager later.

Output:
- Full Java file or safe skeleton.
- API assumptions.
- TODOs requiring verification.

Task P3 prompt — Create MinecraftCoordinateMapper

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/integration/minecraft/MinecraftCoordinateMapper.java.

Requirements:
- Boundary class for converting Minecraft coordinates into Living World coordinates.
- For now, avoid importing Minecraft classes unless necessary.
- Methods:
- RegionCoordinate fromBlockPos(String dimensionId, int blockX, int blockZ, int regionSizeChunks)
- RegionCoordinate fromChunkPos(String dimensionId, int chunkX, int chunkZ, int regionSizeChunks)
- Delegate to RegionCoordinate.fromBlock and RegionCoordinate.fromChunk.
- No gameplay logic.

Output:
- Full Java file.

Platform review prompt

MODEL: Qwen3.6-27B

PROMPT:
Review the platform adapter layer.

Files:
[PASTE PlatformAdapter.java, NeoForgePlatformAdapter.java, MinecraftCoordinateMapper.java]

Check:
- NeoForge imports are isolated to platform/neoforge or command boundary.
- Core simulation remains plain Java.
- Platform API is not too wide.
- Version reporting is possible.
- Server tick hook can eventually call SimulationManager.

Output:
- Pass/fail.
- Fixes.
- Any NeoForge API calls that need checking against current docs.

78. Ecosystem MVP AI Prompts — To Use After Volume 1 Passes

Do not use these until the Volume 1 completion gate passes.

Ecosystem MVP prompt 1 — Create EcosystemRegionData

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/modules/ecosystem/EcosystemRegionData.java.

Requirements:
- Plain Java class.
- Fields:
- double ecosystemHealth
- double stress
- double resilience
- double recoveryRate
- Values clamped 0 to 100.
- Methods:
- defaults()
- normalize()
- copy()
- applyStress(double amount)
- applyRecovery(double amount)
- No Minecraft imports.
- No wildlife, NPC, village, faction, or economy logic.

Output:
- Full Java file.

Ecosystem MVP prompt 2 — Create SoilRegionData

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/modules/soil/SoilRegionData.java.

Requirements:
- Plain Java class.
- Fields:
- double fertility
- double moisture
- double contamination
- double compaction
- double erosion
- Values clamped 0 to 100.
- Methods:
- defaults()
- normalize()
- copy()
- degrade(double amount)
- recover(double amount)
- No Minecraft imports.

Output:
- Full Java file.

Ecosystem MVP prompt 3 — Create PollutionRegionData

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/modules/pollution/PollutionRegionData.java.

Requirements:
- Plain Java class.
- Fields:
- double airPollution
- double groundPollution
- double waterPollution
- double decayResistance
- Values clamped 0 to 100.
- Methods:
- defaults()
- normalize()
- copy()
- addPollution(double air, double ground, double water)
- decay(double amount)
- No Minecraft imports.

Output:
- Full Java file.

Ecosystem MVP prompt 4 — Create VegetationRegionData

MODEL: Qwen3.5-9B

PROMPT:
Create src/main/java/com/livingworld/modules/vegetation/VegetationRegionData.java.

Requirements:
- Plain Java class.
- Fields:
- double grassPressure
- double flowerPressure
- double shrubPressure
- double treePressure
- double deadVegetation
- Values clamped 0 to 100.
- Methods:
- defaults()
- normalize()
- copy()
- reduceFromLogging(double amount)
- recover(double amount)
- No Minecraft imports.
- Do not simulate animal populations.

Output:
- Full Java file.

Ecosystem MVP prompt 5 — Create simple ecosystem update formulas

MODEL: Qwen3.6-27B

PROMPT:
Design the first simple ecosystem update formulas for the Living World mod.

Scope:
- Ecosystem-only.
- No animals.
- No villagers.
- No settlements.
- No factions.

Inputs per region:
- ecosystemHealth
- soil fertility
- soil moisture
- soil contamination
- water quality
- air/ground/water pollution
- vegetation pressure
- resource depletion
- recovery pressure

Output required:
1. Simple formulas for one simulation tick.
2. Pseudocode for update order.
3. Edge cases.
4. Values that should be configurable.
5. Safety caps so values stay between 0 and 100.
6. Explanation simple enough to turn into Java classes.

Do not write Minecraft block-changing code yet.

79. Daily Local AI Working Method

Use this method every coding session.

Step 1:
Use Qwen3.6-27B for planning the next 3 to 5 tiny tasks.

Prompt:
MODEL: Qwen3.6-27B

Given the current Living World project state below, choose the next 3 to 5 safest tasks.

Current state:
[PASTE WHAT EXISTS]

Rules:
- Ecosystem-only mod.
- No NPCs, factions, settlements, roads, or wildlife simulation.
- Core simulation remains plain Java.
- Minecraft/NeoForge imports stay in platform, integration, or command packages.
- Each task must be completable by Qwen3.5-9B in one file or one test file.

Output:
For each task give:
- task name
- target model
- file path
- exact prompt to give Qwen3.5-9B
- tests required
- definition of done

Step 2:
Give one task at a time to Qwen3.5-9B.

Step 3:
Run build/tests.

Step 4:
If build fails, give the exact error to Qwen3.5-9B once.

Repair prompt:
MODEL: Qwen3.5-9B

The previous code failed to compile.

Error:
[PASTE ERROR]

Relevant files:
[PASTE FILES]

Fix only the error.
Do not rewrite unrelated code.
Do not add new systems.
Return the corrected file only.

Step 5:
If the second 9B attempt fails, escalate to Qwen3.6-27B.

Escalation prompt:
MODEL: Qwen3.6-27B

Qwen3.5-9B failed twice to fix this issue.

Goal:
[PASTE TASK GOAL]

Error:
[PASTE ERROR]

Files:
[PASTE RELEVANT FILES]

Find the root cause and provide the smallest safe fix.
Do not redesign the system unless the design is the root cause.
Do not add unrelated features.

Output:
- root cause
- corrected code
- why the fix works
- any follow-up test needed

Step 6:
After every successful task, ask Qwen3.6-27B to review the milestone when enough files exist.

80. Prompt Discipline Rules

These rules are mandatory when working with local AI.

Rule 1:
Never ask a 9B model to build a whole subsystem.

Rule 2:
Never give vague prompts such as "make the ecosystem" or "fix the mod".

Rule 3:
Always include the file path.

Rule 4:
Always include the class name.

Rule 5:
Always state whether Minecraft or NeoForge imports are allowed.

Rule 6:
Always state what is out of scope.

Rule 7:
Always ask for tests when the code is plain Java.

Rule 8:
Always run tests before moving on.

Rule 9:
After two failed repair attempts by Qwen3.5-9B, escalate to Qwen3.6-27B.

Rule 10:
If Qwen3.6-27B says the task is too broad, split it into smaller files.

81. Local Model Role Summary

Qwen3.5-9B role:
- one class
- one enum
- one record
- one interface
- one test file
- simple bug fix
- simple refactor
- simple documentation

Qwen3.6-27B role:
- architecture review
- multi-file debugging
- NeoForge uncertainty
- save design
- scheduler design
- module boundary review
- version upgrade review
- difficult compile errors
- planning next batches

Do not swap these roles unless necessary.