Merging Mahric's Npc-Scripts with new Monsters?
Posted: Tue Jul 30, 2013 3:07 pm
Hej,
I'm really new to modding and lua, but after I've seen what's possible I thought to try it for myself. So I'm working on a dungeon and use a lot of costum stuff from various users.
I found the NPC Script from Mahric and tried to implement a Skeleton Ghost. I'm really new to lua scripting and tried to copy/paste my way to the goal .
The skeleton ghost is from Pandafox. It has his own models and textures and so on. How can I add the skeleton ghost into the existing files from Mahric, so that I have this fellow as a NPC?
I tried to copie a definition for a NPC from Mahrics monster.lua and merged the the skeleton_ghost.lua into that. But i get a lot of errors.
The animations refering still to the md_npc_skeleton_warrior animations. Is this a problem? I really don't have a clue. I learned lua via try and error during building my dungeon and that was ok - til now. Now its to complicated.
Can somebody help me?
---- edit:
So I tried it with the normal monsters, to look how it would work, but I get a strange Error:
The editor crashes and creates a error-file. In this version I didn't change anything.
I'm really new to modding and lua, but after I've seen what's possible I thought to try it for myself. So I'm working on a dungeon and use a lot of costum stuff from various users.
I found the NPC Script from Mahric and tried to implement a Skeleton Ghost. I'm really new to lua scripting and tried to copy/paste my way to the goal .
The skeleton ghost is from Pandafox. It has his own models and textures and so on. How can I add the skeleton ghost into the existing files from Mahric, so that I have this fellow as a NPC?
I tried to copie a definition for a NPC from Mahrics monster.lua and merged the the skeleton_ghost.lua into that. But i get a lot of errors.
SpoilerShow
cloneObject {
name = "md_npc_skeleton_ghost",
baseObject = "skeleton_ghost",
brain = "Melee",
onMove = function(monster, direction)
return false
end,
onTurn = function(monster, direction)
return false
end,
onAttack = function(monster, attackName)
return false
end,
onRangedAttack = function(monster)
return false
end,
onDealDamage = function(monster, champion, amount)
return false
end,
onDamage = function(monster, damageAmount, damageType)
local npc = mdNPC.getNPC(monster.id)
if npc ~= nil then
return not npc.invulnerable
else
return false
end
end,
onProjectileHit = function(monster, damageAmount, damageType)
local npc = mdNPC.getNPC(monster.id)
if npc ~= nil then
return not npc.invulnerable
else
return false
end
end,
onDie = function(monster)
local npc = mdNPC.getNPC(monster.id)
if npc ~= nil then
return not npc.invulnerable
else
return false
end
end,
}
cloneObject {
name = "md_npc_skeleton_warrior_walk",
baseObject = "md_npc_skeleton_warrior",
animations = {
idle = "mod_assets/md_npc/animations/skeleton_warrior_walk.fbx",
moveForward = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_walk.fbx",
turnLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_left.fbx",
turnRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_right.fbx",
attack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack.fbx",
attackBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack_back.fbx",
getHitFrontLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
getHitFrontRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_right.fbx",
getHitBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_back.fbx",
getHitLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_left.fbx",
getHitRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_right.fbx",
fall = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
},
}
cloneObject {
name = "md_npc_skeleton_warrior_turn_left",
baseObject = "md_npc_skeleton_warrior",
animations = {
idle = "mod_assets/md_npc/animations/skeleton_warrior_turn_left.fbx",
moveForward = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_walk.fbx",
turnLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_left.fbx",
turnRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_right.fbx",
attack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack.fbx",
attackBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack_back.fbx",
getHitFrontLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
getHitFrontRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_right.fbx",
getHitBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_back.fbx",
getHitLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_left.fbx",
getHitRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_right.fbx",
fall = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
},
}
cloneObject {
name = "md_npc_skeleton_warrior_turn_right",
baseObject = "md_npc_skeleton_warrior",
animations = {
idle = "mod_assets/md_npc/animations/skeleton_warrior_turn_right.fbx",
moveForward = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_walk.fbx",
turnLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_left.fbx",
turnRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_right.fbx",
attack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack.fbx",
attackBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack_back.fbx",
getHitFrontLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
getHitFrontRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_right.fbx",
getHitBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_back.fbx",
getHitLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_left.fbx",
getHitRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_right.fbx",
fall = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
},
lightName = "hip",
lightColor = vec(0.9, 0.4, 0.4),
lightBrightness = 20,
lightRange = 1.5,
allAroundSight = true,
seeInvisible = true,
flying = true,
turnAnimSpeed = 2,
--attackAnimSpeed = 5,
moveSound = "skeleton_walk",
footstepSound = "skeleton_footstep",
attackSound = "skeleton_attack",
hitSound = "skeleton_hit",
dieSound = "skeleton_die",
hitEffect = "hit_dust",
capsuleHeight = 0.7,
capsuleRadius = 0.25,
collisionRadius = 0.6,
health = 10,
sight = 10,
attackPower = 10,
accuracy = 10,
protection = 2,
evasion=2,
immunities = { “poison”, “fire”, “cold” },
movementCoolDown = 0.1,
noRecoilInterval = { 0.25, 0.5 },
exp = 0,
healthIncrement = 15,
attackPowerIncrement = 5,
protectionIncrement = 1,
brain = "Melee",
particleSystem = "ghostsk",
particleSystemNode = "head",
}
defineParticleSystem{
name = "ghostsk",
emitters = {
-- glow
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {0,0,0},
boxMax = {0,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
},
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {-0.25,0,0},
boxMax = {-0.25,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
},
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {-0.5,0,0},
boxMax = {-0.5,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
},
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {-0.75,0,0},
boxMax = {-0.75,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
},
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {-1.1,0,0},
boxMax = {-1.1,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
}
}
}
defineMaterial{
name = "skeleton_ghost_weapons",
diffuseMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_weapons_dif.tga",
specularMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_weapons_spec.tga",
normalMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_weapons_normal.tga",
doubleSided = false,
lighting = true,
alphaTest = false,
blendMode = "Additive",
--blendMode = "Opaque",
textureAddressMode = "Wrap",
glossiness = 50,
depthBias = 0,
}
defineMaterial{
name = "skeleton_ghost",
diffuseMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_dif.tga",
specularMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_spec.tga",
normalMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_normal.tga",
doubleSided = false,
lighting = true,
alphaTest = false,
blendMode = "Additive",
--blendMode = "Opaque",
textureAddressMode = "Wrap",
glossiness = 75,
depthBias = 0,
}
name = "md_npc_skeleton_ghost",
baseObject = "skeleton_ghost",
brain = "Melee",
onMove = function(monster, direction)
return false
end,
onTurn = function(monster, direction)
return false
end,
onAttack = function(monster, attackName)
return false
end,
onRangedAttack = function(monster)
return false
end,
onDealDamage = function(monster, champion, amount)
return false
end,
onDamage = function(monster, damageAmount, damageType)
local npc = mdNPC.getNPC(monster.id)
if npc ~= nil then
return not npc.invulnerable
else
return false
end
end,
onProjectileHit = function(monster, damageAmount, damageType)
local npc = mdNPC.getNPC(monster.id)
if npc ~= nil then
return not npc.invulnerable
else
return false
end
end,
onDie = function(monster)
local npc = mdNPC.getNPC(monster.id)
if npc ~= nil then
return not npc.invulnerable
else
return false
end
end,
}
cloneObject {
name = "md_npc_skeleton_warrior_walk",
baseObject = "md_npc_skeleton_warrior",
animations = {
idle = "mod_assets/md_npc/animations/skeleton_warrior_walk.fbx",
moveForward = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_walk.fbx",
turnLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_left.fbx",
turnRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_right.fbx",
attack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack.fbx",
attackBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack_back.fbx",
getHitFrontLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
getHitFrontRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_right.fbx",
getHitBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_back.fbx",
getHitLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_left.fbx",
getHitRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_right.fbx",
fall = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
},
}
cloneObject {
name = "md_npc_skeleton_warrior_turn_left",
baseObject = "md_npc_skeleton_warrior",
animations = {
idle = "mod_assets/md_npc/animations/skeleton_warrior_turn_left.fbx",
moveForward = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_walk.fbx",
turnLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_left.fbx",
turnRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_right.fbx",
attack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack.fbx",
attackBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack_back.fbx",
getHitFrontLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
getHitFrontRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_right.fbx",
getHitBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_back.fbx",
getHitLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_left.fbx",
getHitRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_right.fbx",
fall = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
},
}
cloneObject {
name = "md_npc_skeleton_warrior_turn_right",
baseObject = "md_npc_skeleton_warrior",
animations = {
idle = "mod_assets/md_npc/animations/skeleton_warrior_turn_right.fbx",
moveForward = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_walk.fbx",
turnLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_left.fbx",
turnRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_turn_right.fbx",
attack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack.fbx",
attackBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_attack_back.fbx",
getHitFrontLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
getHitFrontRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_right.fbx",
getHitBack = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_back.fbx",
getHitLeft = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_left.fbx",
getHitRight = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_right.fbx",
fall = "assets/animations/monsters/skeleton_warrior/skeleton_warrior_get_hit_front_left.fbx",
},
lightName = "hip",
lightColor = vec(0.9, 0.4, 0.4),
lightBrightness = 20,
lightRange = 1.5,
allAroundSight = true,
seeInvisible = true,
flying = true,
turnAnimSpeed = 2,
--attackAnimSpeed = 5,
moveSound = "skeleton_walk",
footstepSound = "skeleton_footstep",
attackSound = "skeleton_attack",
hitSound = "skeleton_hit",
dieSound = "skeleton_die",
hitEffect = "hit_dust",
capsuleHeight = 0.7,
capsuleRadius = 0.25,
collisionRadius = 0.6,
health = 10,
sight = 10,
attackPower = 10,
accuracy = 10,
protection = 2,
evasion=2,
immunities = { “poison”, “fire”, “cold” },
movementCoolDown = 0.1,
noRecoilInterval = { 0.25, 0.5 },
exp = 0,
healthIncrement = 15,
attackPowerIncrement = 5,
protectionIncrement = 1,
brain = "Melee",
particleSystem = "ghostsk",
particleSystemNode = "head",
}
defineParticleSystem{
name = "ghostsk",
emitters = {
-- glow
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {0,0,0},
boxMax = {0,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
},
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {-0.25,0,0},
boxMax = {-0.25,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
},
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {-0.5,0,0},
boxMax = {-0.5,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
},
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {-0.75,0,0},
boxMax = {-0.75,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
},
{
spawnBurst = true,
emissionRate = 1,
emissionTime = 0,
maxParticles = 1,
boxMin = {-1.1,0,0},
boxMax = {-1.1,0,0},
sprayAngle = {0,30},
velocity = {0,0},
texture = "assets/textures/particles/glow.tga",
lifetime = {1000000, 1000000},
colorAnimation = false,
color0 = {0.2, 0.2, 0.2},
opacity = 1,
objectSpace = true,
fadeIn = 0.1,
fadeOut = 0.1,
size = {1, 1},
gravity = {0,0,0},
airResistance = 1,
rotationSpeed = 0,
blendMode = "Additive",
depthBias = -0.002,
}
}
}
defineMaterial{
name = "skeleton_ghost_weapons",
diffuseMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_weapons_dif.tga",
specularMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_weapons_spec.tga",
normalMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_weapons_normal.tga",
doubleSided = false,
lighting = true,
alphaTest = false,
blendMode = "Additive",
--blendMode = "Opaque",
textureAddressMode = "Wrap",
glossiness = 50,
depthBias = 0,
}
defineMaterial{
name = "skeleton_ghost",
diffuseMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_dif.tga",
specularMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_spec.tga",
normalMap = "mod_assets/pandafox_assets/skeleton_ghost/textures/skeleton_ghost_normal.tga",
doubleSided = false,
lighting = true,
alphaTest = false,
blendMode = "Additive",
--blendMode = "Opaque",
textureAddressMode = "Wrap",
glossiness = 75,
depthBias = 0,
}
Can somebody help me?
---- edit:
So I tried it with the normal monsters, to look how it would work, but I get a strange Error:
SpoilerShow
mod_assets/md_npc/scripts/party.lua:59: attempt to call field 'onDraw' (a nil value)
stack traceback:
mod_assets/md_npc/scripts/party.lua:59: in function 'onDrawGui'
[string "Party.lua"]: in main chunk
[string "Map.lua"]: in function 'sendMessage'
[string "GameMode.lua"]: in function 'update'
[string "DungeonEditor.lua"]: in main chunk
[C]: in function 'xpcall'
[string "DungeonEditor.lua"]: in function 'preview'
[string "DungeonEditor.lua"]: in function 'update'
[string "Grimrock.lua"]: in main chunk
stack traceback:
[C]: in function 'error'
[string "DungeonEditor.lua"]: in function 'handleError'
[string "DungeonEditor.lua"]: in function 'preview'
[string "DungeonEditor.lua"]: in function 'update'
[string "Grimrock.lua"]: in main chunk
stack traceback:
mod_assets/md_npc/scripts/party.lua:59: in function 'onDrawGui'
[string "Party.lua"]: in main chunk
[string "Map.lua"]: in function 'sendMessage'
[string "GameMode.lua"]: in function 'update'
[string "DungeonEditor.lua"]: in main chunk
[C]: in function 'xpcall'
[string "DungeonEditor.lua"]: in function 'preview'
[string "DungeonEditor.lua"]: in function 'update'
[string "Grimrock.lua"]: in main chunk
stack traceback:
[C]: in function 'error'
[string "DungeonEditor.lua"]: in function 'handleError'
[string "DungeonEditor.lua"]: in function 'preview'
[string "DungeonEditor.lua"]: in function 'update'
[string "Grimrock.lua"]: in main chunk