From 192fb28ea981c065d38516f513b2222cd7d5ba77 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 7 Jan 2026 18:42:13 +1100 Subject: [PATCH] Damn thing is slow as a slug --- client.gd | 7 +++--- wfc/generator.gd | 58 ++++++++++++++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/client.gd b/client.gd index b172200..dfaeed0 100644 --- a/client.gd +++ b/client.gd @@ -14,10 +14,11 @@ var wfc: Node = get_node("../Generator") func _ready() -> void: var ruleset: PackedInt32Array = read_sample_ruleset("sample1.png") var samples: Array[PackedInt32Array] = parse_samples_from_ruleset(ruleset) + var c = wfc.generate_chunk_at(0,0,_chunks,samples) #print(ruleset) #print(samples) - wfc.generate_chunk_at(0,0,_chunks,samples) + print(c.data) ## Read the png file, and parse it to a useable ruleset func read_sample_ruleset(filename: String) -> PackedInt32Array: @@ -29,10 +30,10 @@ func read_sample_ruleset(filename: String) -> PackedInt32Array: var size: int = (png.size() / 3) hex.resize(size) - print(png) + #print(png) for i in range(size): #the file is assumed to be in RGB format hex[i] = (png[i * 3] << 16) | (png[i * 3 + 1] << 8) | (png[i * 3 + 2] << 0) - print(i, "(", hex[i], "): ", png[i * 3], ",", png[i * 3 + 1], ",", png[i * 3 + 2]) + #print(i, "(", hex[i], "): ", png[i * 3], ",", png[i * 3 + 1], ",", png[i * 3 + 2]) return hex func parse_samples_from_ruleset(ruleset: PackedInt32Array) -> Array[PackedInt32Array]: diff --git a/wfc/generator.gd b/wfc/generator.gd index 0a68ba3..05633bb 100644 --- a/wfc/generator.gd +++ b/wfc/generator.gd @@ -5,32 +5,51 @@ extends Node func generate_chunk_at(_x: int, _y: int, _chunk_array: Array[Chunk], _samples: Array[PackedInt32Array]) -> Chunk: #TODO: fix the chunk-edges var chunk: Chunk = Chunk.new(_x, _y) - - var latch: int = 1 - while latch: - latch = 0 #if set to true, the generator needs another pass - #iterate over unset tiles with valid neighbours - for x in range(Chunk.CHUNK_WIDTH): - for y in range((Chunk.CHUNK_HEIGHT)): - if chunk.data[y * Chunk.CHUNK_HEIGHT + x] == 0: #direct access, to skip extra checks - #TODO: convert this to the low-entropy method - if _set_tile_from_samples(chunk, x, y, _samples) > 0: - latch += 1 - print("latch: ", latch) - print(chunk.data) + while _set_lowest_entropy_tile(chunk, _samples) > 0: pass + _chunk_array.append(chunk) return chunk -## Returns the value set, or -1 if no options found -func _set_tile_from_samples(chunk: Chunk, tile_x: int, tile_y: int, _samples: Array[PackedInt32Array]) -> int: +## Returns the entropy of the selected tile +func _set_lowest_entropy_tile(chunk: Chunk, _samples: Array[PackedInt32Array]) -> int: + var entropy: Array[Array] = [] + entropy.resize(Chunk.CHUNK_WIDTH * Chunk.CHUNK_HEIGHT) + + #iterate over unset tiles with valid neighbours + for x in range(Chunk.CHUNK_WIDTH): + for y in range((Chunk.CHUNK_HEIGHT)): + if chunk.data[y * Chunk.CHUNK_HEIGHT + x] == 0: #direct access, to skip extra checks + entropy[y * Chunk.CHUNK_HEIGHT + x] = _find_valid_samples(chunk, x, y, _samples) + + #find the lowest-entropy tile + var lowest: int = -1 + for i in range(Chunk.CHUNK_WIDTH * Chunk.CHUNK_HEIGHT): + if entropy[i].size() == 0: continue #no options + + if lowest < 0: + lowest = i + continue + if entropy[i].size() < entropy[lowest].size(): + lowest = i + + #finished + if lowest < 0: return lowest + + #finally, set the tile from the sample + var s: PackedInt32Array = entropy[lowest].pick_random() + chunk.data[lowest] = s[4] + return entropy.size() + +## Returns the valid samples +func _find_valid_samples(chunk: Chunk, tile_x: int, tile_y: int, _samples: Array[PackedInt32Array]) -> Array[PackedInt32Array]: var valid: Array[PackedInt32Array] = [] #use a lambda for easy reading below var compare := func (tile_value: int, sample: int) -> bool: return tile_value <= 0 or tile_value == sample - #find all valid samples + #filter the samples for sample in _samples: if !compare.call(chunk.get_tile(tile_x -1, tile_y -1), sample[0]): continue if !compare.call(chunk.get_tile(tile_x , tile_y -1), sample[1]): continue @@ -43,10 +62,5 @@ func _set_tile_from_samples(chunk: Chunk, tile_x: int, tile_y: int, _samples: Ar if !compare.call(chunk.get_tile(tile_x +1, tile_y +1), sample[8]): continue valid.append(sample) - print("Valid samples: ", valid.size()) - if valid.size() <= 0: return -1 - var s = valid.pick_random() - #set the tile to the randomly selected value - chunk.set_tile(tile_x, tile_y, s[4]) - return s[4] + return valid