Page 1 of 2

Finally got a reproducible player cloning bug

Posted: Mon Nov 17, 2014 1:35 am
by Suslik
Preamble:
Ok there's an old bug that makes a clone of your character and whenever it receives damage you do as well. It happens when you interact with allied creatures in some way: your friend dwarf in reknor, summons, etc. There's not known way to make the clone disappear after that happens and if the clone is on stairs and you have no way to teleport them away you're in trouble.

There have been numerous clues that the clone appears presumabley when you swap places with an allied creature that dies during the same turn and there's a map reference that instead of being nullified now points to you as well and you have 2 map elements that have a pointer to player character which looks like a clone.

Another bug:
Sometimes creatures become immortal without any obvious reasons and their HP cannot go lower than 0 and they just live forever. That's another bug and it happened to my mucus ooze:
Image

Where the things get interesting:
Now when I trade places with the ooze I have a clone created:
Image

That's exactly the kind of clone I was talking about. We have the same hp and the clone is essencially the same creature as my controlled character but that exists on another map tile as well. Furthermore if I try to aim it with an aimable spell when the targetting marker hovers over it, marker gets teleported onto my main character which feels really weird.

The most important bit:
Luckily I made a save after the immortal ooze spawned but before I created a clone out of it. So you can just trade places with it and voila - you get a clone. Ready for debugging:
https://dl.dropboxusercontent.com/u/256 ... german.zip

PS:
it was definitely a bad idea to go to the tempest peak on lvl 17 on insane/rl .___.

Re: Finally got a reproducible player cloning bug

Posted: Mon Nov 17, 2014 2:00 am
by palmito
Yeah it happens. I fixed the bug editing the desc.lua file with notepad, and adding the marson bosses gone AWOL' addon and then in the game pressed ctrl+c.

Re: Finally got a reproducible player cloning bug

Posted: Mon Nov 17, 2014 2:01 am
by Marson
I try to address these kinds of clones with my Bosses Gone AWOL addon. That wasn't the original focus of the addon, but I added the clone-killing functionality later. I didn't find a good way to prevent them, but I did find a way to remove them.

The clone is created when the map keeps a reference to your character even after your character has moved off the square it was on. There are two types of pointers (character -> grid & grid -> character) and they get a little crossed up.

Character data says character is on square 15, 22.
Square 15, 22 data says character is standing on it. (This is your actual character)
Square 15, 23 data says character is standing on it. (This is the clone)

This is why damaging the clone damages your character.

I didn't comment heavily, but hopefully you can figure out what I'm doing to kill the clone if you look at the addon code.

Re: Finally got a reproducible player cloning bug

Posted: Mon Nov 17, 2014 3:08 am
by Suslik
I'm aware about the addon but it's primary goal is to remove the clones to continue playing. Goal of the thread is to find out why they are created in the first place and why the references get messed. I think this reproducible savegame can shed some light on the exact process of why this occurs and how to prevent it.

Re: Finally got a reproducible player cloning bug

Posted: Mon Nov 17, 2014 3:17 am
by HousePet
Unfortunately, the immortal ooze is the same bug as a cloned player, so I wouldn't say you have a reproducible bug caught.

It would be good to look at the log up to that point though.

Re: Finally got a reproducible player cloning bug

Posted: Mon Nov 17, 2014 9:20 am
by HousePet
Found it!

Its combat.lua lines 61 and 62. Remove them.
Same issue as with the doQuake(). Do not remove an entities coordinates then call move(), this stops the engine from removing the reference to the entity from the map.

I can has cookie? :mrgreen:

Re: Finally got a reproducible player cloning bug

Posted: Mon Nov 17, 2014 1:29 pm
by Suslik
hmm but I still have 2 questions:
1) why that

Code: Select all

target.x = nil target.y = nil
self.x = nil self.y = nil
existed in the first place? and
2) why did it not always reproduce when you trade places with any creature?

Re: Finally got a reproducible player cloning bug

Posted: Mon Nov 17, 2014 2:38 pm
by Marson
Nice job, HousePet! You can have the whole candy store. :)
Suslik wrote:hmm but I still have 2 questions:
1) why that

Code: Select all

target.x = nil target.y = nil
self.x = nil self.y = nil
existed in the first place? and
2) why did it not always reproduce when you trade places with any creature?
I suspect the = nil lines were used ages ago before there was a move() function and they were just never taken out, but that's just a guess.

I haven't tested it, but I think that when you swap places with a live creature, then the coords get swapped correctly. If you swap places with a dead-but-not-yet-removed creature, then the swap gets garbled.

Re: Finally got a reproducible player cloning bug

Posted: Tue Nov 18, 2014 12:21 am
by HousePet
I think it messes up if something happens, like the creature dying, while still standing on the tile it was swapped to.
I'm really not sure why it works fine 99% of the time.

Also checking the code for Switch Place and Swap, Switch Place has the same bad code, whereas Swap does it correctly.
Maybe it would be useful to make a specific function for switching the locations of two actors?

Re: Finally got a reproducible player cloning bug

Posted: Tue Nov 18, 2014 1:50 am
by Marson
You can create a clone by killing a friendly in the very turn it is created and then stepping on that spot some time afterwards (if I remember right, it can be several turns later), so I believe the issue is initialized before x,y = nil comes into play and is a two-part problem.

You can do this with a Tammer Toss. Throw the hammer that will kill a creature in one hit, creating a Night Terror that then gets killed on the hammer's return. The spot that the Night Terror was on is now primed for clone creation, just waiting for you to step on it.

Re: Finally got a reproducible player cloning bug

Posted: Tue Nov 18, 2014 2:40 am
by HousePet
I think that one is a separate bug.

Re: Finally got a reproducible player cloning bug

Posted: Tue Nov 18, 2014 8:56 am
by 0player
So, as I understand, the issue is: when you swap with an entity that is not dead, the entity overwrites your old tile and everything is fine. But when you swap with something that is, somehow, dead, the move() refuses to place it onto the map, not overwriting your old position.

Re: Finally got a reproducible player cloning bug

Posted: Tue Nov 18, 2014 12:53 pm
by grayswandir
This would probably be best fixed with something like:

Code: Select all

function Actor:leaveMap()
  game.level.map:remove(self.x, self.y, Map.ACTOR)
  self.x = nil
  self.y = nil
end
To be used instead of just nilling out x and y manually.

Re: Finally got a reproducible player cloning bug

Posted: Tue Nov 18, 2014 7:02 pm
by Zireael
Or maybe the swap places function should explicitly check for not actor.dead?

Re: Finally got a reproducible player cloning bug

Posted: Wed Nov 19, 2014 12:32 am
by HousePet
Swapping with a dead creature shouldn't be possible. Its just a symptom of the cloning bug that allows that to happen. So dealing with it isn't important.

I'm wondering if the force argument to the move() function was added later, that would explain why some code is nuking an entities location to make the move work.
But with the force flag, it is unnecessary to mess with an entities location to do this sort of thing, so it shouldn't be done.