Keyerror u'npc1' when generating multiple NPCS (solved)

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Keyerror u'npc1' when generating multiple NPCS (solved)

#1 Post by noeinan »

So, I've got my NPC generator working for generating just one NPC like so:

Code: Select all

    $npc = NPCList(racelist, typelist, procaselist, 1)

    "Num: [npc.num] Race: [npc.race] Type: [npc.type] Procase: [npc.procase] Level: [npc.level]
    Insecurity: [npc.insecurity_str] Health: [npc.health] Build Desc: [npc.builddesc]"

However, I'd like to make a function where I can generate multiple NPCs at a time. I think I've almost got it working, but when I try to set up a for loop it gives me a KeyError...

Code: Select all

    python:
        def GenerateList(npclist):
            for i in range(len(npclist)):
                new_npc = npclist[i]
                new_npc = NPCList(racelist, typelist, procaselist, 1)
                return new_npc

    $ GenerateList(npclist)

    "Num: [npc1.num] Race: [npc1.race] Type: [npc1.type] Procase: [npc1.procase] Level: [npc1.level]
    Insecurity: [npc1.insecurity_str] Health: [npc1.health] Build Desc: [npc1.builddesc]"

    "Num: [npc2.num] Race: [npc2.race] Type: [npc2.type] Procase: [npc2.procase] Level: [npc2.level]
    Insecurity: [npc2.insecurity_str] Health: [npc2.health] Build Desc: [npc2.builddesc]"

    "Num: [npc3.num] Race: [npc3.race] Type: [npc3.type] Procase: [npc3.procase] Level: [npc3.level]
    Insecurity: [npc3.insecurity_str] Health: [npc3.health] Build Desc: [npc3.builddesc]"

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 59, in script
    "Num: [npc1.num] Race: [npc1.race] Type: [npc1.type] Procase: [npc1.procase] Level: [npc1.level]
KeyError: u'npc1'

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 59, in script
    "Num: [npc1.num] Race: [npc1.race] Type: [npc1.type] Procase: [npc1.procase] Level: [npc1.level]
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\ast.py", line 706, in execute
    renpy.exports.say(who, what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\exports.py", line 1336, in say
    who(what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 1126, in __call__
    what = what_pattern.replace("[what]", sub(what, translate=True))
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 1115, in sub
    return renpy.substitutions.substitute(s, scope=scope, force=force, translate=translate)[0]
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\substitutions.py", line 253, in substitute
    s = formatter.vformat(s, (), kwargs)
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 563, in vformat
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 585, in _vformat
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 646, in get_field
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 605, in get_value
KeyError: u'npc1'

Windows-8-6.2.9200
Ren'Py 7.3.2.320
Fuck Game 1.0
Wed Apr 08 08:34:52 2020
It seems like it's not recognizing new_npc as defined, despite me having defined it in the loop? Any advice is appreciated!
Last edited by noeinan on Wed Apr 08, 2020 10:14 pm, edited 1 time in total.
Image

Image
Image

User avatar
MaydohMaydoh
Regular
Posts: 165
Joined: Mon Jul 09, 2018 5:49 am
Projects: Fuwa Fuwa Panic
Tumblr: maydohmaydoh
Location: The Satellite of Love
Contact:

Re: Keyerror u'npc1' when generating multiple NPCS

#2 Post by MaydohMaydoh »

From what I can see, there's a few problems. First the return shouldn't be inside the for loop. This will cause the loop to only run once before breaking away and returning.
Second I don't know what the npclist is for, but what is happening there is you're putting one of the list items into the new_npc variable, then overwriting it with the NPCList function and repeating this each time the loop runs.
Third, the reason is you're defining new_npc locally inside the function, so you won't be able to access it globally.

What you want to probably do is

Code: Select all

$ new_npclist = GenerateList(npclist)
to grab it after you return it from the function.
You'll probably also want to put whatever the NPCList function returns into a list instead of a single variable.

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Keyerror u'npc1' when generating multiple NPCS

#3 Post by noeinan »

Oof! I feel silly, thanks for pointing out my mistake with the return being misplaced and just overwriting my variable instead of what I was trying to do.

So, what I'm actually trying to do is this:

I've got a function that generates a random npc, with all the traits. It's a class that stores the npc's race, type, gender, and a bunch of other stuff. Normally, to use this function, I use this line:

Code: Select all

npc1 = NPCList(racelist, typelist, procaselist, 1)
I just wanted to make a for loop that would just run the function for npc1, npc2, npc3, etc. So I could just pick however many npcs I wanted and it would label them in incremented numbers, so I could then grab individual traits by referencing that. (Ex. if I wanted the second npc's race I'd just type "Race: [npc2.race]" and it would show up in the textbox, or I could use that for further programming.)

I wasn't really sure how to do this, so I just made a list with the labels I wanted (npc1-3) and was trying to use the for loop to plug those strings into my generator.

I was originally trying to use new_npc to get rid of the u'npc1' error I was getting, but I put things in the wrong order. It was supposed to be this:

Code: Select all

    $ npclist = ["npc1", "npc2", "npc3"]

    python:
        def GenerateList(npclist):
            for i in range(len(npclist)):
                npclist[i] = new_npc
                new_npc = NPCList(racelist, typelist, procaselist, 1)
            return new_npc

    $ GenerateList(npclist)
However, that also gives me an error...

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 99, in script
    $ GenerateList(npclist)
  File "game/script.rpy", line 99, in <module>
    $ GenerateList(npclist)
  File "game/script.rpy", line 95, in GenerateList
    npclist[i] = new_npc
UnboundLocalError: local variable 'new_npc' referenced before assignment
Not sure how it's being referenced early, since I literally set it in the first line... (trying to grab the result as a list instead via $ new_npclist = GenerateList(npclist) doesn't seem to affect this error either.)

My original code used this, which gives the u'npc1' error:

Code: Select all

    $ npclist = ["npc1", "npc2", "npc3"]

    python:
        def GenerateList(npclist):
            for i in range(len(npclist)):
                npclist[i] = NPCList(racelist, typelist, procaselist, 1)
            return npclist[i]

    $ GenerateList(npclist)
Last edited by noeinan on Wed Apr 08, 2020 7:24 pm, edited 1 time in total.
Image

Image
Image

User avatar
MaydohMaydoh
Regular
Posts: 165
Joined: Mon Jul 09, 2018 5:49 am
Projects: Fuwa Fuwa Panic
Tumblr: maydohmaydoh
Location: The Satellite of Love
Contact:

Re: Keyerror u'npc1' when generating multiple NPCS

#4 Post by MaydohMaydoh »

You're getting the error because the local variable new_npc inside the function hasn't been defined before you try to put it into npclist. You can probably get rid of that and use a dictionary inside the function, dynamically naming them instead.
https://www.w3schools.com/python/python ... naries.asp

Code: Select all

python:
    def GenerateDict(npc):
          ## npc is number of npcs you want to create
          npc_dict = {}
          
          for x in range(npc):
              ## add new dictionary entries named npc1, npc2, npc3 etc
              npc_dict['npc {}'.format(x+1)] = NPCList(racelist, typelist, procaselist, 1)
          return npc_dict
          
$ npc_dict = GenerateList(3)

"Num: [npc_dict['npc1'].num] Race: [npc_dict['npc1'].race] ...etc..."
Untested but that should possibly work.

Also remember that variables defined inside a function locally and outside globally are different. If you want to use a global variable in a function, you have to tell it

Code: Select all

$ testvar = "Hello"

def testfunc():
	global testvar
	print(testvar)

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Keyerror u'npc1' when generating multiple NPCS

#5 Post by noeinan »

Hmmm, it seems using dict I'm getting the exact same error?

Code: Select all

    python:
        def GenerateDict(npcnum):
            npc_dict = {}

            for i in range(npcnum):
                npc_dict['npc {}'.format(i+1)] = NPCList(racelist, typelist, procaselist, 1)
            return npc_dict

    $ npc_dict = GenerateDict(3)

    "Num: [npc_dict['npc1'].num] Race: [npc_dict['npc1'].race] Type: [npc_dict['npc1'].type] Procase: [npc_dict['npc1'].procase] Level: [npc_dict['npc1'].level]
    Insecurity: [npc_dict['npc1'].insecurity_str] Health: [npc_dict['npc1'].health] Build Desc: [npc_dict['npc1'].builddesc]"

    "Num: [npc_dict['npc2'].num] Race: [npc_dict['npc2'].race] Type: [npc_dict['npc2'].type] Procase: [npc_dict['npc2'].procase] Level: [npc_dict['npc2'].level]
    Insecurity: [npc_dict['npc2'].insecurity_str] Health: [npc_dict['npc2'].health] Build Desc: [npc_dict['npc2'].builddesc]"

    "Num: [npc_dict['npc3'].num] Race: [npc_dict['npc3'].race] Type: [npc_dict['npc3'].type] Procase: [npc_dict['npc3'].procase] Level: [npc_dict['npc3'].level]
    Insecurity: [npc_dict['npc3'].insecurity_str] Health: [npc_dict['npc3'].health] Build Desc: [npc_dict['npc3'].builddesc]"

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 92, in script
    "Num: [npc_dict['npc1'].num] Race: [npc_dict['npc1'].race] Type: [npc_dict['npc1'].type] Procase: [npc_dict['npc1'].procase] Level: [npc_dict['npc1'].level]
KeyError: u"'npc1'"

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 92, in script
    "Num: [npc_dict['npc1'].num] Race: [npc_dict['npc1'].race] Type: [npc_dict['npc1'].type] Procase: [npc_dict['npc1'].procase] Level: [npc_dict['npc1'].level]
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\ast.py", line 706, in execute
    renpy.exports.say(who, what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\exports.py", line 1336, in say
    who(what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 1126, in __call__
    what = what_pattern.replace("[what]", sub(what, translate=True))
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 1115, in sub
    return renpy.substitutions.substitute(s, scope=scope, force=force, translate=translate)[0]
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\substitutions.py", line 253, in substitute
    s = formatter.vformat(s, (), kwargs)
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 563, in vformat
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 585, in _vformat
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 654, in get_field
KeyError: u"'npc1'"

Windows-8-6.2.9200
Ren'Py 7.3.2.320
Fuck Game 1.0
Wed Apr 08 16:20:42 2020
And thanks, I got caught on not having global in front of some code earlier. Here I was hoping to make it work just using a local variable, since I have no use for it outside the function.

Unless I need to make it global to even get the function to return it? That didn't seem to be the case with my other functions though...
Image

Image
Image

User avatar
MaydohMaydoh
Regular
Posts: 165
Joined: Mon Jul 09, 2018 5:49 am
Projects: Fuwa Fuwa Panic
Tumblr: maydohmaydoh
Location: The Satellite of Love
Contact:

Re: Keyerror u'npc1' when generating multiple NPCS

#6 Post by MaydohMaydoh »

Oh ops,

Code: Select all

npc_dict['npc {}'.format(x+1)] = NPCList(racelist, typelist, procaselist, 1)
I put a space between the npc and the {} so the names are npc 1 and not npc1. Remove the space and it should work.

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Keyerror u'npc1' when generating multiple NPCS

#7 Post by noeinan »

Seems like I'm still getting the same u error, even after removing the space

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 94, in script
    "Num: [npc_dict['npc1'].num] Race: [npc_dict['npc1'].race] Type: [npc_dict['npc1'].type] Procase: [npc_dict['npc1'].procase] Level: [npc_dict['npc1'].level]
KeyError: u"'npc1'"

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 94, in script
    "Num: [npc_dict['npc1'].num] Race: [npc_dict['npc1'].race] Type: [npc_dict['npc1'].type] Procase: [npc_dict['npc1'].procase] Level: [npc_dict['npc1'].level]
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\ast.py", line 706, in execute
    renpy.exports.say(who, what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\exports.py", line 1336, in say
    who(what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 1126, in __call__
    what = what_pattern.replace("[what]", sub(what, translate=True))
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 1115, in sub
    return renpy.substitutions.substitute(s, scope=scope, force=force, translate=translate)[0]
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\substitutions.py", line 253, in substitute
    s = formatter.vformat(s, (), kwargs)
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 563, in vformat
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 585, in _vformat
  File "/home/tom/ab/x64lucid-deps/install/lib/python2.7/string.py", line 654, in get_field
KeyError: u"'npc1'"

Windows-8-6.2.9200
Ren'Py 7.3.2.320
Fuck Game 1.0
Wed Apr 08 16:39:30 2020
Image

Image
Image

User avatar
MaydohMaydoh
Regular
Posts: 165
Joined: Mon Jul 09, 2018 5:49 am
Projects: Fuwa Fuwa Panic
Tumblr: maydohmaydoh
Location: The Satellite of Love
Contact:

Re: Keyerror u'npc1' when generating multiple NPCS

#8 Post by MaydohMaydoh »

I made quick mockup and tested it

Code: Select all

    python:
        x = "one"
        y = "two"
        z = "three"
        
        class Test():
            def __init__(self, x, y, z):
                self.x = x
                self.y = y
                self.z = z
                
        def GenerateDict(npc):
            npc_dict = {}

            for i in range(npc):
                npc_dict['npc{}'.format(i+1)] = Test(x, y, z)
            return npc_dict
            
    $ test = GenerateDict(3)
    
    "[test[npc1].x] [test[npc1].y] [test[npc1].z] this is a test"
Works fine, the only difference between this and yours is the NPCList function. So my guess is the problem lies there.

EDIT: Ahh, I just realised something. Don't know if it will fix it or not but you have quotes around npc1 in the text interpolation.

Code: Select all

 "Num: [npc_dict['npc1'].num] Race: [npc_dict['npc1'].race] Type: [npc_dict['npc1'].type] Procase: [npc_dict['npc1'].procase] Level: [npc_dict['npc1'].level]
Try removing those to make it Num: [npc_dict[npc1].num]

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Keyerror u'npc1' when generating multiple NPCS

#9 Post by noeinan »

Looks like the quotes is what did it! Thanks, it's working now :D
Image

Image
Image

Post Reply

Who is online

Users browsing this forum: No registered users