Zombie Objects

Hello all.

Can anybody confirm to me what exactly a zombie object is?

I have duplicated a rig with the skin on it. It has nothing else parented to it or anything like that, just the skin and rig.

I have a script with a keyboard sensor on it and all it does is print the children of the rigs name (so just prints the name of the object.

When I run it, no errors until I hit the key, then it prints:

Zombie object! name = playerSkin

Google told me that a zombie object can’t end properly because of duplication, or it’s parented to something on another layer. But, there is nothing else parented to this object besides the rig, nothing on another layer. It has logic on it to endObject, but it shouldn’t be triggering yet.

So can somebody clarify what a zombie object is exactly and how to fix it? I am a little confused by what I have found online so far.

What do you care , just grab your gun and shoot it in the face. :evilgrin:
But if you insist to know what it is >click< :slight_smile:

Sorry that did not help :(.

I have confirmed it is this code:

import bge

def main():

    cont = bge.logic.getCurrentController()
    own = cont.owner
    if own['hold'] == 1:
           vari = own.children    
           print(vari) #Prints the whole list with all elements
           print(vari[0].name) #Prints the correct element name at whatever index I use
           own['hold'] = 11        #Just makes it so it doesn't go into the _init_ if again
               for i in vari:
                        so = vari[i].name
                        print("lalala:" + so)  
main()

This shoots out into the console after the first two success print statements:

KeyError: “CList[key]: ‘Player Mesh’ key not in list”
Blender Game Engine Finished
Zombie object! name=Player Mesh

Can somebody please tell me whats going on here? It has to be something with the list received from the .children function. Can’t I interact with a Clist in the same way as a normal list?

I know Clists are read only, but can you not even use them for loop iteration? I replaced that for loop code with this while loop that doesn’t use the list as a parameter, and it works pretty well. I have noticed every once in a blue moon it randomly crashes, I have not figured out why yet.

Anyways, can somebody tell me if I am correct on this, you cannot use a Clist for a loop indexer?

working while loop:

if own['hold'] == 1:
        vari = own.children    
        print(vari)
        print(vari[0].name)
        own['hold'] = 11  
        i = 0
        totItems = len(vari)
        while i != totItems:      
        #for i in vari:
            so = vari[i]
            print("lalala:" + str(so))
            i += 1
            print(so['health'])            
            if so['health'] &lt;= 0:   
                print(so.name)

The problem of a zombie object is when you try to access something that has been deleted/removed.
Not having you blend or the rest of your scripts, it’s hard to say what it is thats removing it.

You can use clists for loop iteration

Hmm see that is so strange for me, it only appears as a zombie when a for loop is involved.

I have 0 other code or logic in my file, and nothing else in different layers that could be not rendering for some reason.

I tried to write a function now to take the original list, and put it into a different list to see if I could get it to work that way, but now it says:

List indices’s must be integers, not KX_game_logic, or just crashes :/.

Here is a .blend file, sorry should have put this in in the first place. Hopefully somebody can now tell me whats going on here.

file.zip (307 KB)

It works in the file because my for loops are commented out atm.

You wrote you get a key error with key ‘Player Mesh’.
This is not part of the posted code.

Finally it is as sdfgeoff wrote: you access the an ended game object. I guess you stored a reference somewhere and accessed it after ending the object.

But where in my code am I ending anything? This is my confusion… because if I access just one element of the list manually by index number, it has no issue. It is when I then try to loop into the list, it says the key is not there.

Is it the way I am storing the data into the list? The loops are being entered after the list is created and stored, and it is in the same indentation level, so I am not seeing it as a local variable problem or something? There is no ending logic at all in the game (as can be seen by the zip), and I only am getting this error when trying to for loop through the list.

I’m not sure what the zip is supposed to be showing. It’s a good idea to simplify posted blend files to the most base situation where a bug, problem, or other issue occurs to assist with troubleshooting, without any comments or anything like that in codew to “fix” the problem, since it’s just more work to locate and identify which comments cause the issue.

I’m unsure as to why the console prints “Zombie Object” when I uncomment the “for gg in test:” block, though I can say that it doesn’t happen if you don’t access the test list using the actual “gg” GameObjects from test (which you should not do, because those objects are already from the “test” list). Instead, just use the objects from the test list directly. Basically, when you use a “for object in list:” loop, it’s looping through each object in that list, not returning numbers to look up the lists later. So:



for ob in object_list:
    print (object_list[ob])  # Bad, because ob is already a retrieval of each index in object_list.

for ob in object_list:
    print (ob)  # Good.


If you wanted to grab an object from its list using indices, then you should do that with ranges:



for i in range(len(object_list)):
    print(object_list[i])  # Corresponds to ob above; i is a number from 0 to the length of the object_list, so it can be used to look up to retrieve the object in every index of the object_list.


But unless you need to use the indices for other lists or something, it’s more Pythonic to just grab the objects.

I think you might do well to look up how for loops work in Python and pay attention to how you’re using them; I notice that in addition to the actual problem you’re running into, you’re doing things in an un-Pythonic way (i.e. using a while loop to loop through a list to alter the contents of that list).

Yes I was trying to take from one list and move to another if I needed to in the future, your code is what I needed. Thanks a bunch.

And yeah, I am just learning Python coming from a C background.

Looking at the internet and API is there any other tips you can give me with looping and lists? The Blender API says the append() function can cause blender game to crash if it’s used, which is not ideal. How to avoid this?

Are extend/insert functions better to use?> How to remove from said list? I see the API does not list a remove function built in, so I assume it is manual in BGE?

Sorry to derail my own question a little, but the more I learn about lists in python the more I feel I must learn.

You do not need to end an object via code. There are several possibilities to end objects.

  • explicit ending via end object actuator
  • explicit ending via endObject
  • implicit ending via ending a parent
  • implicit ending via switching scenes

Where does it say the append() function could cause a crash? If you want to learn more about how Python works differently from C or C++, I’d suggest the Python manual here. Just work your way down (or skip to For statements), and you should be able to pick it up without too much issue. The BGE API just sits on top of the existing Python language, so there’s not really too many oddities or tricks in the API. For example, learning how to remove an item from a list in Python should be the exact same in the BGE.

http://www.blender.org/documentation/blender_python_api_2_63_17/bge.types.html?highlight=orientation#bge.types.KX_GameObject.orientation

On this API it says it can cause it to crash when it’s used internally by game engine.

I have tried using the other python built in functions for manipulating lists, but I think Clists must not be able to use all of them?

Two lines of code I tried:

listTwo.remove(tmp)
vari.remove(tmp)

The first one listTwo is just a normal list I created and loaded with a value tmp, vari is the Clist created from using the children function. listTwo does remove the object exactly as expected, but then the second line throws an error saying that the Clist has no attribute remove.

And yes monster thanks, I have experimented with endObject and got that result working correct.

Edit:
Another issue I am not having is that the script is for some reason running twice. I have an if statement, if hit endObject and return, which it does correctly, but then it seems it is running the script again despite the return statement. My sensor is a keyboard set to tap, so I am not sure it is the one triggering it twice. I know that is pretty vague, but anybody got any guesses of what I may be doing off here?

I thought return with no value is essentially just exiting the function, and since this is my main function, exiting the program.

I suggest you read the first couple of guides that you can find in the link of my signature.
If that does not help there is an FAQ at the same page. But you really need an understanding how the BGE is working.

Okay yes, I have fixed my double firing of the script, I did not know that the python cont will fire for both negative and positive pulsing.

Thanks again monster.