Using hashes (SOLVED)

Hello,

I don’t understand hashes. I know what a hash is (a number got by applying a function on a string).

But when reading this in the documentation, for go.get_position(id)

[id]
string | hash | url optional id of the game object instance to get the position for, by default the instance of the calling script

I understand i can give as a parameter the name of my game object, it’s hashed value or the path to it (the url).

Still doing the runner tutorial, i’ve tried this:

local pieces = { "ground00", "ground01", "ground02", "ground03",
                 "ground04", "ground05", "ground06" }

function init(self)
  self.speed = 6
  for i, p in ipairs(pieces) do
    pieces[i] = hash(p)
  end
end

For replacing the string by its hash, at the beginning.

But when i try to get the position later, i have an error :

function update(self, dt)
  for i, p in ipairs(pieces) do
    local pos = go.get_position(p)
    …

I get an error on the line which set the pos variable: instance (null) not found.

May be a bug on my side ? Or i don’t understand how to use hashed values.

Thank you for reading.

1 Like

Try putting a / in front of the ID strings in pieces. It seems like if you use a hash as an ID instead of a string it needs to be absolute. A look at the examples in the documentation for go.get_id() may help this make sense.

Of course, I’m not sure why you are hashing them at all. You can just use the strings with go.get_position().

1 Like

Thank you :slight_smile:

I see now, when i use hash i have to pass the absolute path (/collection/game_object).
And with go.get_id(), i can pass only the game object name (i there is no name collision, i guess).

This one works:

function init(self)
  self.speed = 6
  for i, p in ipairs(pieces) do
    pieces[i] = hash("/ground/" .. p)
    -- or you can use this instead of hashing with full path:
    --pieces[i] = go.get_id(p)
  end
end
1 Like

Yeah, sort of. Relative paths are written from the point of view of the game object they’re used from. Any other game objects in the same collection can be addressed by only game object name. If they’re in a sub-collection, you need to include that: "sub_collection/object_name", and so on. If you need to address an object “higher” in the collection tree then you need to use an absolute ID, starting with “/”. This is all explained thoroughly in the message passing manual (check around 1/4 of the way down).

The engine won’t allow name collisions. All game objects within the same collection must have a unique name.

2 Likes

On the subject. I am in the process of rewriting some of the docs. The message passing doc I intend to split into two, one about message passing, and one new about addressing (since it applies to more than message passing). I’ve put up a version of it here (https://www.defold.com/manuals/addressing/) and I would be happy if you wouldn’t mind reading through it and see if it’s clear to follow?

5 Likes

As a newcomer, i’ve read carefully, after i have read “message passing”.

The explainations seem clear to me :slight_smile:

Though i have to say i don’t know if i would have understood so easily without keeping in mind the first illustration of message passing .
This one helped me a lot, understanding the encapsulation involved between interfaces , game objects and components.
collections can be seen as a a super-structure (like the library you encounter on mainframes like AS/400).
game_objects are more like directories to me.
components of course are files.

Seeing the Defold object structure as a filesystem helped me a lot to remember its organisation. And then after, collections proxy was a breeze (as long as you have understood the collection object for what it is).

So i think you should keep this one:

I still don’t understand shorthands :

 -- Post "reset" to the current script
 msg.post("#", "reset")

wouldn’t it be simpler to just call the reset function , instead of passing to the current script a message that will be hashed, tested with another hashed string, and then finally treated ?
So, if # limits to the current object , i don’t see the point to use it, as it will always reference the script itself.

Or may be it could be used for acquiring focus ? Instead of referring the current game object, we could also refer to the script itself, which will treat the input events ?

-- Let this game object acquire input focus
 msg.post("#", "acquire_input_focus") --instead of "."

I tried with the runner tutorial, and it worked well for me. But may be there are case where it wouldn’t.

But in this case, in don’t see the utility of the dot shorthand.

Hope it helps without confuse :slight_smile:

1 Like

I mostly use the shorthands "." and "#" with msg.url() to create a full URL that I can pass to other scripts and modules.

1 Like