import Foundation public class World { public typealias ChunkID = SIMD3 @inline(__always) public static func makeID(position: SIMD3) -> ChunkID { makeID(position: SIMD3(Int(floor(position.x)), Int(floor(position.y)), Int(floor(position.z)))) } @inline(__always) public static func makeID(position: SIMD3) -> ChunkID { position &>> Chunk.shift } private var _chunks: Dictionary private var _chunkDamage: Set private var _generator: WorldGenerator public init() { self._chunks = [:] self._chunkDamage = [] self._generator = WorldGenerator() } func getBlock(at position: SIMD3) -> Block { return if let chunk = self._chunks[position &>> Chunk.shift] { chunk.getBlock(at: position) } else { Block(.air) } } func setBlock(at position: SIMD3, type: BlockType) { // Find the chunk containing the block position let chunkID = position &>> Chunk.shift if let idx = self._chunks.index(forKey: chunkID) { // Set the block and mark the containing chunk for render update self._chunks.values[idx].setBlock(at: position, type: type) self._chunkDamage.insert(chunkID) // Mark adjacent chunks for render update when placing along the chunk border let internalPos = position &- chunkID &<< Chunk.shift for (i, ofs) in zip(internalPos.indices, [ SIMD3.X, .Y, .Z ]) { if internalPos[i] == 0 { let id = chunkID &- ofs if self._chunks.keys.contains(id) { self._chunkDamage.insert(id) } } else if internalPos[i] == Chunk.size - 1 { let id = chunkID &+ ofs if self._chunks.keys.contains(id) { self._chunkDamage.insert(id) } } } } } func getChunk(id chunkID: ChunkID) -> Chunk? { self._chunks[chunkID] } public func forEachChunk(_ body: @escaping (_ id: SIMD3, _ chunk: Chunk) throws -> Void) rethrows { for i in self._chunks { try body(i.key, i.value) } } func generate(width: Int, height: Int, depth: Int, seed: UInt64) { self._generator.reset(seed: seed) let orig = SIMD3(width, height, depth) / 2 for z in 0.. Void) { for id in self._chunkDamage { body(id, self._chunks[id]!) } self._chunkDamage.removeAll(keepingCapacity: true) } }