0 votes

Hi, I'm trying to use threads to ini a tilemap. In this example, I created 4 new threads and start them in a loop. My tilemap is 1000x1000 and it keeps crashing on execution. When I init the tilemap without threads, then everything works fine.

initWorldGeneration([0, 0, Global.worldSize.x, Global.worldSize.y])

I added a lock to ensure, taht the threads don't interfere and even tested it with only one therad, but it keeps crashing.

extends Panel

var worldTile
var timer
var threads = []
var finished = 0
var wait
var maxValues = Vector2(2, 2)
var stage = 0


func _ready():
    wait = Mutex.new()
    for i in range(0, maxValues.x+maxValues.y):
        threads.append(Thread.new())
    worldTile = self.get_node("worldTile")
    self.set_size(Vector2(32*Global.worldSize.x, 32*Global.worldSize.y))
    initTimer()
    #initWorldGeneration([0, 0, Global.worldSize.x, Global.worldSize.y])


func startThreads():
    var idx = 0
    for x in range(0, maxValues.x):
        for y in range(0, maxValues.y):
            if(not threads[idx].is_active()):
                threads[idx].start(self, "initWorldGeneration", [x*Global.worldSize.x/maxValues.x, y*Global.worldSize.y/maxValues.y, (x+1)*Global.worldSize.x/maxValues.x, (y+1)*Global.worldSize.y/maxValues.y], 1)
                idx += 1


func initTimer():
    timer = Timer.new()
    timer.set_one_shot(false)
    timer.set_timer_process_mode(Timer.TIMER_PROCESS_FIXED)
    timer.set_wait_time(0.6)
    timer.connect("timeout", self, "_timer_callback")
    self.add_child(timer)
    timer.start()


func _timer_callback():
    if(stage == 0):
        stage == 1
        startThreads()
    elif(stage == 1 and finished == maxValues.x + maxValues.y):
        print("finished")
        stage == 1


func initWorldGeneration(arg):
    print(str("Starting thread with: ", arg))
    for x in range(arg[0], arg[2], 1):
        for y in range(arg[1], arg[3], 1):
            wait.lock()
            worldTile.set_cellv(Vector2(x, y), 0)
            wait.unlock()
    finished += 1
    return null

Thanks.

asked Jul 18, 2017 in Engine by Degreeno (15 points)

AFAIK, you should not do something to manipulate elements those will be rendered on screen on not main thread.

Which means it is not possible to use more than one core to create/fill
tilemaps?

1 Answer

0 votes

It could be too late but I found a solution:

1) Remove the tileMap from the tree
2) Set the tileMap tiles
3) Add the tileMap again to the tree

Those crashes seems to appear because the game is trying to update the collision/draw of the tileMap every frame. Removing from the tree makes the engine only update it once.

Note: Reducing the quadrant size bring backs the problem: 16 works fine, 2 don't

answered Mar 12 by katuiche (23 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.