altar puzzle(why doesn't this script work)

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

altar puzzle(why doesn't this script work)

Post by FeMaiden »

okay, i'm confused.
I'm trying to make an "altar/alcove" puzzle
the puzzle is based on some notes the player finds ..
with movie trivia(I realize this might be inappropriate for the grimrock universe, I might change it)
the idea is I wrote references to different movies on the notes, then i have altars labeled with the movie titles and the player is supposed to put the movie description that matches the title on the correct altars and then a teleporter is supposed to appear.
but nothing happens.
this is the same script I used for my elemental beacons puzzle to respond to specific essences and it worked there.
unless there's some syntax error I'm missing?

or does it have to do with the notes? does the game take away the individual id's of the notes when i pick them up, turning them into generic notes with no ID?

Code: Select all

function library()
local dawn = false
local candyman = false
local childsplay = false
local nightmare = false
local sleepaway = false
local princess = false

	for _,itm in altar_1.surface:contents() do
		if itm.go.name == "note_dawn" then
         	dawn = true
         	break
      	end
   	end

   	for _,itm in altar_2.surface:contents() do
      	if itm.go.name == "note_candyman" then
        	candyman = true
         	break
      	end
   	end
    for _,itm in altar_3.surface:contents() do
     	if itm.go.name == "note_childsplay" then
         	childsplay = true
         	break
      	end
   	end

    for _,itm in altar_4.surface:contents() do
      	if itm.go.name == "note_nightmare" then
         	nightmare = true
         	break
      	end
   	end

	for _,itm in altar_5.surface:contents() do
      	if itm.go.name == "note_sleepaway" then
         	sleepaway = true
         	break
      	end
   	end
	
	for _,itm in altar_6.surface:contents() do
      	if itm.go.name == "note_princess" then
         	princess = true
         	break
      	end
   	end

	if dawn and candyman and childsplay and nightmare and sleepaway and princess then
      	teleporter_1.controller:activate()
	else
      	teleporter_1.controller:deactivate()
   end
end

User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: altar puzzle(why doesn't this script work)

Post by FeMaiden »

I solved the problem on my own.


the game was not considering the 6 notes to be different items. it considers them all to be the same exact item, which I guess is the same reason you can't have an alcove puzzle that uses figure_ogre_1 and figure_ogre_2 and figure_ogre_3, because the game considers them all the same item.

I got around this by making 6 new scroll item definitions so the game considers each of them to be a separate item
User avatar
Isaac
Posts: 3192
Joined: Fri Mar 02, 2012 10:02 pm

Re: altar puzzle(why doesn't this script work)

Post by Isaac »

Did you define these notes as objects?

The object.go.name is not the same as the object.go.id

The name will be the kind of object... are you using scrolls?
If you labeled a scroll "note_candyman" in the editor, then that is its id, not its name.

Try your script after replacing every go.name for go.id

** You can have a puzzle that uses 'figure_ogre_1' and 'figure_ogre_2' and 'figure_ogre_3'.
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: altar puzzle(why doesn't this script work)

Post by FeMaiden »

Isaac wrote:Did you define these notes as objects?

The object.go.name is not the same as the object.go.id

The name will be the kind of object... are you using scrolls?
If you labeled a scroll "note_candyman" in the editor, then that is its id, not its name.

Try your script after replacing every go.name for go.id

** You can have a puzzle that uses 'figure_ogre_1' and 'figure_ogre_2' and 'figure_ogre_3'.

yeah I solved it, I went into custom item defiinitions and copy pasted the definition for the scroll and made 6 different ones each with a different name, then i placed them and they worked perfectly.

incidentally, I also found the script that the main campaign used for the alcoves in the lexiconary, and their script is much more compact and elegant than mine. my script is working so i'm just gonna leave it like that though.

and yeah, i realize I CAN have a puzzle with figure ogre 1 2 and 3, if I create the custom definitions for them.
minmay
Posts: 2790
Joined: Mon Sep 23, 2013 2:24 am

Re: altar puzzle(why doesn't this script work)

Post by minmay »

The "name" field is not unique. All floor_trigger objects will have the name "floor_trigger".
The "id" field is unique. You are guaranteed that only one object with a certain id will exist at a time; if there is an object with the id "floor_trigger_1" and you try to spawn a second object with the id "floor_trigger_1", it will cause an error, unless you destroy the original floor_trigger_1 first.

Your original script doesn't work because you are checking the wrong field. You are comparing the "name" field when you need to compare the "id" field.

Ignoring the existence of the "id" field, like you seem to want to do now, is a bad idea. For example, storing an object's id and using findEntity() to get it later is the only reasonable way to keep a serializable reference to an object (direct references are not serializable).
FeMaiden wrote:and yeah, i realize I CAN have a puzzle with figure ogre 1 2 and 3, if I create the custom definitions for them.
No, that's not what Isaac's saying! His whole point is that you don't have to make multiple definitions because the id field exists!

You need to read the scripting reference again. It covers these fields:
All entities have the following properties that can be accessed with the dot operator:

name: returns the name of the entity
id: returns the unique identifier of the entity
x: returns the x-coordinate of the entity on the map
y: returns the y-coordinate of the entity on the map
elevation: returns the elevation of the entity on the map (0 = ground level)
facing: returns the facing of the entity (0=north, 1=east, 2=south, 3=west)
level: returns the dungeon level index of the entity
map: returns the Map object representing the dungeon level where the entity is
xyz: returns the component named “xyz” (or nil if no such component exists)
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: altar puzzle(why doesn't this script work)

Post by FeMaiden »

minmay wrote:The "name" field is not unique. All floor_trigger objects will have the name "floor_trigger".
The "id" field is unique. You are guaranteed that only one object with a certain id will exist at a time; if there is an object with the id "floor_trigger_1" and you try to spawn a second object with the id "floor_trigger_1", it will cause an error, unless you destroy the original floor_trigger_1 first.

Your original script doesn't work because you are checking the wrong field. You are comparing the "name" field when you need to compare the "id" field.

Ignoring the existence of the "id" field, like you seem to want to do now, is a bad idea. For example, storing an object's id and using findEntity() to get it later is the only reasonable way to keep a serializable reference to an object (direct references are not serializable).
FeMaiden wrote:and yeah, i realize I CAN have a puzzle with figure ogre 1 2 and 3, if I create the custom definitions for them.
No, that's not what Isaac's saying! His whole point is that you don't have to make multiple definitions because the id field exists!

You need to read the scripting reference again. It covers these fields:
All entities have the following properties that can be accessed with the dot operator:

name: returns the name of the entity
id: returns the unique identifier of the entity
x: returns the x-coordinate of the entity on the map
y: returns the y-coordinate of the entity on the map
elevation: returns the elevation of the entity on the map (0 = ground level)
facing: returns the facing of the entity (0=north, 1=east, 2=south, 3=west)
level: returns the dungeon level index of the entity
map: returns the Map object representing the dungeon level where the entity is
xyz: returns the component named “xyz” (or nil if no such component exists)



so you are telling me I should not have created new custom assets that are all scrolls but with a diferent name?

i made my puzzle work by putting this in the items.lua and using these instead of the regular scrolls

Code: Select all

defineObject{
	name = "scroll_dawn",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/scroll.fbx",
		},
		{
			class = "Item",
			uiName = "Scary Story",
			gfxIndex = 112,
			weight = 0.3,
		},
		{
			class = "ScrollItem",
		},
	},
}

defineObject{
	name = "scroll_nightmare",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/scroll.fbx",
		},
		{
			class = "Item",
			uiName = "Scary Story",
			gfxIndex = 112,
			weight = 0.3,
		},
		{
			class = "ScrollItem",
		},
	},
}

defineObject{
	name = "scroll_childsplay",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/scroll.fbx",
		},
		{
			class = "Item",
			uiName = "Scary Story",
			gfxIndex = 112,
			weight = 0.3,
		},
		{
			class = "ScrollItem",
		},
	},
}

defineObject{
	name = "scroll_sleepaway",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/scroll.fbx",
		},
		{
			class = "Item",
			uiName = "Scary Story",
			gfxIndex = 112,
			weight = 0.3,
		},
		{
			class = "ScrollItem",
		},
	},
}

defineObject{
	name = "scroll_candyman",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/scroll.fbx",
		},
		{
			class = "Item",
			uiName = "Scary Story",
			gfxIndex = 112,
			weight = 0.3,
		},
		{
			class = "ScrollItem",
		},
	},
}

defineObject{
	name = "scroll_princess",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/scroll.fbx",
		},
		{
			class = "Item",
			uiName = "Fantasy Adventure Romance",
			gfxIndex = 112,
			weight = 0.3,
		},
		{
			class = "ScrollItem",
		},
	},
}

defineObject{
	name = "scroll_nightof",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/scroll.fbx",
		},
		{
			class = "Item",
			uiName = "Scary Story",
			gfxIndex = 112,
			weight = 0.3,
		},
		{
			class = "ScrollItem",
		},
	},
}


why is this "bad"?
minmay
Posts: 2790
Joined: Mon Sep 23, 2013 2:24 am

Re: altar puzzle(why doesn't this script work)

Post by minmay »

You are defining 7 identical objects. Do you not see how there's an easier way to make your puzzle? (Hint: it's exactly what you tried in the first post, except with "name" replaced with "id").
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: altar puzzle(why doesn't this script work)

Post by FeMaiden »

minmay wrote:You are defining 7 identical objects. Do you not see how there's an easier way to make your puzzle? (Hint: it's exactly what you tried in the first post, except with "name" replaced with "id").
oh...yeah, I see it now, I see what you mean. but...I guess I like doing things the hard way.
seriously, I do understand what you are saying now. but I already wrote my code so i may as well just leave it like that.
(besides, I like my custom scroll better than the regular one, I changed it to "scary story" which fits the theme of the puzzle)
User avatar
gambit37
Posts: 218
Joined: Fri Mar 02, 2012 3:40 pm

Re: altar puzzle(why doesn't this script work)

Post by gambit37 »

I think it's a mistake to keep your code, just because you "already wrote it" that way. As minmay points out, defining the same item 6 times is pointless and inefficient, and you should always strive for efficiency in any code that you develop. Code is cheap: be prepared to rewrite and delete it when necessary, and don't hang on to stuff you don't need.

In addition, you now have code in two places: your script in the editor, and your object definitions file. Your script now depends on external code, when it doesn't really need to.

Modding (and by extension, coding in general) is more than just making something work. It's also about clarity, efficiency, performance and optimisation. Why stick with an inefficient method for your script when there is a better way to do it?
User avatar
FeMaiden
Posts: 290
Joined: Wed Jan 16, 2013 8:16 am

Re: altar puzzle(why doesn't this script work)

Post by FeMaiden »

gambit37 wrote:I think it's a mistake to keep your code, just because you "already wrote it" that way. As minmay points out, defining the same item 6 times is pointless and inefficient, and you should always strive for efficiency in any code that you develop. Code is cheap: be prepared to rewrite and delete it when necessary, and don't hang on to stuff you don't need.

In addition, you now have code in two places: your script in the editor, and your object definitions file. Your script now depends on external code, when it doesn't really need to.

Modding (and by extension, coding in general) is more than just making something work. It's also about clarity, efficiency, performance and optimisation. Why stick with an inefficient method for your script when there is a better way to do it?

well...okay, you do have a point. the thing with the scrolls won't actually take me more than a few minutes. I do want to keep one of them because I like the GUI name = "Scary Story", it will clue the player in that this is a key item for the puzzle, distinguishing it from the generic "scroll"

although, on a tangent here, what's your opinion on my using movie trivia as part of a puzzle?
I've seen other mods use logic problems and riddles and anagrams and cryptography in their puzzles but all those things can be worked out through logic. trivia is more of a "you either know it or you don't" kind of thing. of course, my trivia references are easy to recognize and should be easy to use a simple google search to recognize where they came from...

and..I'm probably spoiling my puzzle now

I mean, i probably already spoiled the solution by posting my code, but how else will I learn unless I share my by sloppy codes so I can learn to do it better?
Post Reply