Page 1 of 1

Load a save after updating a dungeon

Posted: Wed Nov 23, 2016 7:58 pm
by vieuxchat
I saved a game in my dungeon.
Then I changed a script (some lines of code).
Then I load the save and the changes I made aren't there. The save game still load the old script.

When I load the save it asks me if I want as the version number isn't the same. So I thought it was the new script that should have loaded.
It's really annoying because I saved just before a crash and if I can't test my changes then I have to replay all my dungeon from the beginning (hoping the changes I did wouldn't make the game crash again...)

What's strange is that it didn't crash in the dungeon editor.

Here is the crash log :

Code: Select all

#script_entity_50.script:4: attempt to index a nil value
stack traceback:
	#script_entity_50.script:4: in function <#script_entity_50.script:1>
	[string "Script.lua"]: in function 'sendMessage'
	[string "Component.lua"]: in function 'triggerConnectors'
	[string "Component.lua"]: in function 'callHook'
	[string "Socket.lua"]: in function 'addItem'
	[string "Socket.lua"]: in main chunk
	[string "GameObject.lua"]: in function 'sendMessage'
	[string "Clickable.lua"]: in function 'onClickComponent'
	[string "GameMode.lua"]: in function 'mousePressed'
	[string "GameMode.lua"]: in function 'update'
	[string "Grimrock.lua"]: in function 'display'
	[string "Grimrock.lua"]: in main chunk
PS: Do I understand the crash log well ? I think that "#script_entity_50.script:4" means it crashed at line 4 of the script in script_entity_50.
PS2: here is the faulty script :

Code: Select all

function checkSiFigurinesBienPlacees()
	local pc = findEntity("pedestal_crowern")
	local crowernOK = false
	if pc.socket:count() == 1 then crowernOK = pc.socket:getItem().go.name == "figure_crowern" end
	
	local po = findEntity("pedestal_ogre")
	local ogreOK = false
	if po.socket:count() == 1 then ogreOK = po.socket:getItem().go.name == "figure_ogre" end
	
	local ps = findEntity("pedestal_skeleton")
	local skeletonOK = false
	if ps.socket:count() == 1 then skeletonOK = ps.socket:getItem().go.name == "figure_skeleton" end
	
	local psn = findEntity("pedestal_snail")
	local snailOK = false
	if psn.socket:count() == 1 then snailOK = psn.socket:getItem().go.name == "figure_snail" end
	
	local open = crowernOK and ogreOK and skeletonOK and snailOK
	if open then 
		counter_37.counter:decrement()
	end
end

Re: Load a save after updating a dungeon

Posted: Wed Nov 23, 2016 8:29 pm
by THOM
I'm not an expert in scripting but I think in line 4 of your script yo are saying crowernOK shall become the name of an object. But before you defined crowernOK as false. So it can now only be false or true but not a name...

Also you wrote pc.socket:getItem().go.name == "figure_crowern" - a line that I don't understand. Afaik you can use == in connection with an if, but there is none here...

What do you want to get with your whole line?

And AFAIK Scripts and other stuff inside a Mod are just loaded once at the beginning of a new game and then stored into the savefile. So, if you change a script inside your mod you won't have changed it in your savefile and so it's never been loaded into the game engine...

Re: Load a save after updating a dungeon

Posted: Wed Nov 23, 2016 8:38 pm
by zimberzimber

Code: Select all

local crowernOK = false
You don't have to define it as false. If it doesn't have a value and you're perform a check on it (if crowernOK then) it will return false.

Code: Select all

if pc.socket:count() == 1 then crowernOK = pc.socket:getItem().go.name == "figure_crowern" end
I doubt you can compare values outside of 'if' or loop statements.

Here's what it should look like:

Code: Select all

function checkFigurines()
	local pc = findEntity("pedestal_crowern")
	local crowernOK
	if pc.socket:count() == 1 and pc.socket:getItem().go.name == "figure_crowern" then crowernOK = true end
	
	local po = findEntity("pedestal_ogre")
	local ogreOK
	if po.socket:count() == 1 and po.socket:getItem().go.name == "figure_ogre" then ogreOK = true end
	
	local ps = findEntity("pedestal_skeleton")
	local skeletonOK
	if ps.socket:count() == 1 and ps.socket:getItem().go.name == "figure_skeleton" then skeletonOK = true end
	
	local psn = findEntity("pedestal_snail")
	local snailOK
	if psn.socket:count() == 1 and psn.socket:getItem().go.name == "figure_snail" then snailOK = true end
	
	if crowernOK and ogreOK and skeletonOK and snailOK then
		counter_37.counter:decrement()
	end
end

Re: Load a save after updating a dungeon

Posted: Wed Nov 23, 2016 9:48 pm
by minmay
When you reload a savegame, the dungeon.lua is not run again. The savegame contains all the information about object and component placement and state. So if you change object placements, ScriptComponent source, whatever, your changes will NOT apply to old savegames. Only changes to other files (asset definitions, textures, etc.) will apply to old savegames.

Re: Load a save after updating a dungeon

Posted: Thu Nov 24, 2016 12:04 am
by AndakRainor
Not really related to the mod upadting versus saved games problem, but something similar to:

Code: Select all

crowernOK = pc.socket:getItem().go.name == "figure_crowern"
is allowed in lua (and all programming languages I know...). This only means that crowernOK will store a boolean value after this line and it will be the result of the test followoing "=". The symbol "==" is just an operator that return a boolean value. You can use it outside if or loops statements as you would with any other operator. (That does not mean that this line does exactly what you wanted it to do when you wrote it...)

PS: I made a small updating system for "Magic of Grimrock" that is able to "patch" a saved game by respawning script entities that need it (but it has its limits and uses the official scripting interface only, so you can't respawn anything you want without crashing the game, for example redefining party's native hooks is not possible as it would require to respawn the party's object!!! So be careful with those!). I proposed to share it but I had no reply about that (because every one has done it on their own or do not care about updating saved games?).

Re: Load a save after updating a dungeon

Posted: Thu Nov 24, 2016 7:57 am
by vieuxchat
minmay wrote:When you reload a savegame, the dungeon.lua is not run again. The savegame contains all the information about object and component placement and state. So if you change object placements, ScriptComponent source, whatever, your changes will NOT apply to old savegames. Only changes to other files (asset definitions, textures, etc.) will apply to old savegames.
Oh.
That's what I feared.
So I'll have to start a new game from scratch.

About:
crowernOK = pc.socket:getItem().go.name == "figure_crowern"

I used 4 pedestals where the player must put figures. When the player enters a new object the script check is each figure is at the right place (I gave each pedestal the name of its figure, so pedestal_crowern is the pedestal where you have tu put the crowern). So I use 4 boolean values for each of the 4 pedestals.

crowernOK = pc.socket:getItem().go.name == "figure_crowern" must be read for right to left :first it checks if the name of the inserted object is "figure_crowern" then it stores the result (true or false) into crowernOK.

I didn't know that the base value of a boolean was false. But I'll still set each of the ar to false to help me remember what the function should be doing (my programming teacher always told me to assignate a value to all the var I declare for easier readability and maintenance)

Anyway, thanks to everybody.