#pragma once #include #include #include #include #include #include "World.h" #include "Math.h" #include "Block.h" #include "TimeOfDay.h" #include "Weather.h" #include "Farming.h" #include "BiomeGen.h" #include "RandomTick.h" #include "BlockTick.h" #include "Container.h" #include "Circuit.h" #include "Hopper.h" #include "Dispenser.h" #include "Minecart.h" #include "Rail.h" #include "Mob.h" namespace vf { // Climate carries its own vf::BlockChange that collides with the one in // Protocol.h. Kept out of this header (forward declared, held by pointer) so a // translation unit can pull WorldSim together with ChunkSync/Protocol. class Climate; // Mirror of ClimateConfig's tunables, so callers can shape the climate without // pulling Climate.h (and its clashing BlockChange) into their translation unit. struct WorldClimateSettings { int seaLevel = 26; float heightLapse = 0.006f; float latitudeLapse = 0.0009f; float freezeTemperature = 0.15f; float meltTemperature = 0.5f; float frostSpreadTemperature = 0.30f; int maxSnowDepth = 8; int packThreshold = 4; }; struct WorldSimConfig { uint32_t worldSeed = 1u; // Farming random ticks dispatched by the WorldSim's own selector. int randomTicksPerChunk = 3; // Vanilla block random ticks handled by the reused BlockTickScheduler. int blockRandomTicksPerChunk = 3; long long weatherIntervalTicks = 1; long long climateIntervalTicks = 20; long long logisticsIntervalTicks = 1; float mobDt = 1.0f / 20.0f; WorldTick startTick = 0; TimeOfDayConfig time; WeatherConfig weather; WorldClimateSettings climate; FarmingConfig farming; BiomeGenParams biome; CartConfig cart; CreatureConfig creature; }; // Deterministic orchestrator that folds the standalone simulation modules into // one step. Every tick advances the clock, periodically the weather and the // regional climate, dispatches random ticks to farming and vanilla block // behaviour, runs redstone, logistics (hoppers/dispensers), minecarts and // creatures, then collects the block cells that changed inside the active // region as a dirty feed for chunk replication. Given the same seed and the // same inputs, two WorldSims produce byte-identical world state. class WorldSim { public: WorldSim(World& world, const Vec3i& regionOrigin, const Vec3i& regionDims, const WorldSimConfig& config = {}); ~WorldSim(); WorldSim(const WorldSim&) = delete; WorldSim& operator=(const WorldSim&) = delete; WorldSim(WorldSim&&) = delete; WorldSim& operator=(WorldSim&&) = delete; void step(long long ticks = 1); long long currentTick() const { return tickCounter; } const Vec3i& regionOrigin() const { return origin; } const Vec3i& regionDims() const { return dims; } const TimeOfDay& time() const { return clock; } const Weather& weather() const { return sky; } Farming& farming() { return crops; } const Farming& farming() const { return crops; } RedstoneCircuit& circuit() { return *redstone; } ContainerStore& containers() { return store; } const ContainerStore& containers() const { return store; } // Climate readouts exposed without leaking Climate.h into callers. int snowDepthAt(const Vec3i& pos) const; int iceAgeAt(const Vec3i& pos) const; float temperatureAt(int gx, int gy, int gz) const; Precipitation currentPrecipitation() const; void addMinecart(const Minecart& cart); std::vector& minecarts() { return carts; } const std::vector& minecarts() const { return carts; } void setPoweredRailPredicate(std::function predicate); void addCreature(const Creature& creature); std::vector& creatures() { return mobs; } const std::vector& creatures() const { return mobs; } void setPlayer(const Vec3& pos); void clearPlayer(); // Global cells whose block changed versus the last clearDirty (or since // construction), in a deterministic sorted order. const std::vector& dirtyBlocks() const { return dirtyList; } void clearDirty(); uint64_t regionHash() const; private: void runFarmingRandomTicks(); void runClimate(); void runLogistics(); void runMinecarts(); void runCreatures(); void recomputeDirty(); int localIndexOf(int gx, int gy, int gz) const; Block baselineBlock(int localIdx) const { return baseline[static_cast(localIdx)]; } World& world; Vec3i origin; Vec3i dims; long long tickCounter; long long weatherInterval; long long climateInterval; long long logisticsInterval; float mobDt; TimeOfDay clock; Weather sky; BiomeGen biomes; std::unique_ptr weatherClimate; Farming crops; RandomTick randomTick; BlockTickScheduler scheduler; ContainerStore store; std::unique_ptr redstone; std::unordered_map hopperStates; std::unordered_map dispenserStates; CartConfig cartConfig; CreatureConfig creatureConfig; std::vector carts; std::function poweredRail; std::vector mobs; Vec3 player; bool hasPlayer = false; std::vector baseline; std::vector dirtyList; }; } // namespace vf