NPC's and Timers #610
-
Hello, i seem to be having an issue with NPC timers maybe i am doing something wrong, the code below is what i currently have what i am expecting to happen is the following when the NPC spawns start a timer called "time_till_despawn" World.queue("await_for_player_to_move", 2) {
val animatedArmour = npcs.add(npcToSpawn, target.tile, Direction.NORTH, 0)
if (animatedArmour != null) {
animatedArmour.target = player
animatedArmour.say("I'm ALIVE")
animatedArmour.softTimers.start("time_till_despawn")
World.queue("await_npc_to_spawn_and_chat", 1) {
animatedArmour.walkTo(Tile(baseTile.x, baseTile.y + 2))
}
}
} I have the code to handle when the NPC died to stop the timer (might not be required the engine probably stops the timer when the NPC dies) npcDeath("animated*armour") { armour ->
val animatedArmour: NPC = armour["animated*armour"] ?: return@npcDeath
if(animatedArmour.softTimers.contains("time_till_despawn")) {
animatedArmour.softTimers.stop("time_till_despawn")
logger.info { "REMOVING TIMER FOR NPC DEATH" }
if(!animatedArmour.contains("timer_till_despawn")){
logger.info { "REMOVED TIMER FOR NPC DEATH" }
}
}
} my issue lies after x minutes i want to remove the NPC from the world and that that i am using the following npcTimerTick("time_till_despawn") { npc ->
cancel()
logger.warn { "TIMER TICKED FOR NPC" }
}
npcTimerStop("time_till_despawn") { npc ->
npcs.remove(npc)
logger.warn { "TIMER TIMER STOPPED FOR NPC" }
}
npcTimerStart("time_till_despawn") {
interval = 10
logger.warn { "TIMER STARTED FOR ANIMATED NPC" }
} but when using error
the only thing i could think of was, the engine might be trying to remove the timer at the same time i was removing the NPC? so i tried a different approach with the following code animatedArmour.queue("await_npc_idle_despawn", 10) {
npcs.remove(animatedArmour)
} This appraoch doesn't throw any errors however, the NPC is "removed" but is still visible on client till i either leave that region or relog. any help would be appreciated |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Just before getting into timers, try to use The issue here is: npcTimerStop("time_till_despawn") { npc ->
npcs.remove(npc)
logger.warn { "TIMER TIMER STOPPED FOR NPC" }
} Because the timer events are happening within the NPCTask, you end up trying to modify the npcs list while iterating through it, essentially: for (npc in npcs) {
npcs.remove(npc)
} Which is why it results in a concurrent modification exception. Using a softQueue is probably how it should be done, however this will also cause the same error. I should really add a safer way of removing npcs and players... #611 So for now calling out to World queue inside will fix it because it'll wait until outside of the NPCTask. npc.softQueue("time_till_despawn", TimeUnit.MINUTES.toTicks(10)) {
World.queue("${npc.id}_despawn") {
npcs.remove(npc)
}
} |
Beta Was this translation helpful? Give feedback.
Just before getting into timers, try to use
delay()
's instead of queue's for timing things. You might have seen older examples where I have used queue's but that was changed with #590 (I'll update docs soon). World queue especially shouldn't be used often as their names need to be unique or they'll override when a second player does the same action.The issue here is:
Because the timer events are happening within the NPCTask, you end up trying to modify the npcs list while iterating through it, essentially:
Which is why it results in…