shivsta shivsta - 9 months ago 52
Swift Question

SpriteKit: Hashing a Recycled SKShapeNode

I'm trying to detect collisions between nodes that have not collided before in my SpriteKit game by calling node.hash and storing new nodes in a set. I'm seeing that after some time, new nodes have the same hash as nodes that I had previously called node.removeFromParent() on.

I'm guessing that because I am removing from parent and recreating very similar nodes over and over, SK is automatically recycling some nodes.

How can I get a truly unique hash from nodes in SpriteKit?

Please let me know if further clarification is needed. I feel like posting my code wouldn't be too relevant to this post.

Furthermore, I am not able to reproduce this issue when I'm debugging with my phone attached to xcode but I have added logging that shows node.hash not being unique for newly created nodes. Anyone know why recycling behavior would be different with my phone connected to Xcode?


I think you may be misunderstanding what a hash is and does.

A hash is not necessarily a unique value. It is a one way function of some kind (not necessarily cryptographic) that takes arbitrary data and produces a value. If the same data is hashed more than one time, it will produce the same hash value, not a different value.

Working against you, however, is the fact that the .hash value is not a cryptographic hash (which is somewhat computationally intensive). The quality of a hash function, cryptographic or not, is based on how frequently there are hash collisions. A hash collision occurs when two different values produce the same hash.

Cryptographic hashing functions are selected, amongst other things, based on a low hash collision rate. The .hash function may have a high collision rate, even if your data is different, depending on your particular data.

A far better solution is to add a property to your nodes that can be easily checked:

class MyNodeClass: SkShapeNode {
   var hasCollided = false  // Publicly accessible property

I do notice that in other comments you say, "I am interesting in finding the proper hash." I'd strongly recommend against this approach since, again, hash functions will definitely carry a computational load. The better the function, the higher that load.

If what you are really looking for is a unique identifier for each node (rather than a collision tracker) then why not implement an internal property that is initialized from the initializer based on a class value that simply produces a unique, incrementing ID?