Load models from a server?

I’m working on a client / server space game. I have the server instancing objects and storing their locations in a dictionary, which I can send to the client.

But how can a client instantiate a range of objects based on what a server sends it? I know I can loop through the dictionary using eval to run it as code, but that seems risky. Is there a better way to send level data to clients?

Just read the entry and have a function interpret the resultant elements from the array.

You could use serializing or marshalling. The awkward terms usually mean writing your objects to a common file format like XML or JSON and sending that. On the client side you’d have to interpret the data and recreate the objects. By doing so you can perform various validity checks.

@Nemesis, thank you sir. That’s what I ended up doing. I have a YAML file that I read in on the server:

solarSystemObject: 
  planet:
    Mars:
      xpos:-2000
      ypos:-2000
      zpos:0
      scale:50
      parent:Sol
      model:/models/planets/planet_sphere
      texture:/models/planets/MarsMap_2500x1250.jpg
    Earth:
      xpos:2000
      ypos:2000
      zpos:0
      scale:90
      parent:Sol
      model:/models/planets/planet_sphere
      texture:/models/planets/EarthClouds_2500x1250.jpg
  star:
    Sol:
      xpos:3000
      ypos:3000 
      zpos:0
      scale:599
      model:/models/planets/star_sphere
      texture:/models/planets/suncyl1.jpg

So the server reads it into a dict, then loops through leaves (the dict is nested). Then for each leaf that matches the format, it instances the planets, setting them spinning, etc.

I have the server keep the dict updated as the planets move through their rotation; when the client requests the level, the whole dict is sent through and re-interpreted on the client. From there, it just checks individual objects (this is not yet working though) and adjusts accordingly.

This is really, really sloppy code, but for now, it works and that’s good enough for me. I’ll refactor later.

            elif "solarSystemObject" in data:
                try: data = ast.literal_eval(data)
                except: pass
                print type(data)
                # Load the level, baby.
                #x = obj(data)
                starsdict = data['solarSystemObject']['star']
                planetsdict = data['solarSystemObject']['planet']
                print starsdict
                print type(starsdict)
                print planetsdict
                print type(planetsdict)
                for k,v in planetsdict.items():
                    print k
                    singleplanet = {}
                    singleplanet = planetsdict[k]
                    singleplanet = singleplanet.replace(":", "':'")
                    singleplanet = singleplanet.replace(" ", "', '")
                    singleplanet = "{'" + singleplanet + "'}"
                    singleplanet = ast.literal_eval(singleplanet)
                    print("Type is " + str(type(singleplanet)) + "; value is:")
                    print singleplanet
                    print("Now, to convert numeric strings to integers.")
                    for k, v in singleplanet.items():
                        try: singleplanet[k] = int(v)
                        except: pass
                    print singleplanet
                    print("Now attempting to load it.")
                    self.loadModel(singleplanet['model'], singleplanet['xpos'], singleplanet['ypos'], singleplanet['zpos'], singleplanet['texture'], singleplanet['scale'], render)
                    # Now do the stars.
                print starsdict
                print type(starsdict)
                for k,v in starsdict.items():
                    print k
                    singlestar = {}
                    singlestar = starsdict[k]
                    singlestar = singlestar.replace(":", "':'")
                    singlestar = singlestar.replace(" ", "', '")
                    singlestar = "{'" + singlestar + "'}"
                    singlestar = ast.literal_eval(singlestar)
                    print("Type is " + str(type(singlestar)) + "; value is:")
                    print singlestar
                    print("Now, to convert numeric strings to integers.")
                    for k, v in singlestar.items():
                        try: singlestar[k] = int(v)
                        except: pass
                    print singlestar
                    print("Now attempting to load it.")
                    self.loadModel(singlestar['model'], singlestar['xpos'], singlestar['ypos'], singlestar['zpos'], singlestar['texture'], singlestar['scale'], render)

And then, my loadModel def.

    def loadModel(self, model, xpos, ypos, zpos, texture, scale, parent):
        self.m = loader.loadModel(ConstellaAssets + model)
        self.texture = loader.loadTexture(ConstellaAssets + texture)
        self.m.setTexture(self.texture, 1)
        self.m.setScale(scale)
        self.m.setPos(xpos, ypos, zpos)
        self.m.reparentTo(render)
        print("Successfully loaded an instance of the " + model)

Works nice; YAML rules. If you’ve recommendations on cleaning up my code, I’m happy to take them. Otherwise, I’ll tidy it up when I get back over there.
Thanks again, mate.