Mmorpg

It’s good. Though graphics could use work (textures look very flat). Other than my critiques, it’s definitely coming along. Also, you say don’t want to use the latest Blender updates. Well, how do you plan on making builds with your game in 2.49? Just some things to think about.

(You could model in one Blender and use the other for your games if you’re concerned with hotkeys, just another thought).

So, I started programming it a week or so back, but then I came upon something that must be decided before going forwards;

anytime you have multiple objects sending information (virtually at random) to one object; it becomes an I/O (input/output) operation which demands some level of user instancing.

I mean, I can do it on a first come first served basis, that’s easy, can’t really do that
with battle stuff though too much animation-time lag. This means each message must be received with an additional time stamp message. simple I know, but then you have multiple channels too, if channels can be mixed, then we also need ‘channel priority’ as a message as well. And that opens up a user instancing can of worms: what happens when a player adds a channel to a chat tab? does it merely merge future messages for the added channels to that document? or does it reorder all the messages from all chat logs into one document?

when is the chat re-instanced? (when does it say, “OK I should start clean and reorder everything”) or does it only do so on log-in?

this is what I need to decide between. Typing this helps me decide by clearly visibly laying out my alternatives.

From this I gather it’s best that the chat only re-instances on character login, and merges/un-merges future messages for added/removed channels.

now I know what I need to do next.

I made the lighting kinda strong on purpose which made the textures look more flat than they are. that was only for my masters presentation.

as for builds, blender 2.49 has save as runtime if needed, but I will be releasing the client in source as a .blend so I can claim ownership of it and apply a non-gnu license. there will be instructions given with it of how to ‘install’ the game as a runtime using blenderplayer but a disclaimer along with it that it’s not necessary and that if you do so does not void the license or instate a gnu license.

my license is pretty similar to GNU, but if you use it (the project bane files) for profit or gain profits directly or indirectly from the game or anything associated with it, then you gotta pay $1 per paying player per year. and you must state that the files were originally part of project bane whether edited or not.

basically what I’m doing here is making the groundwork for blender MMOs, so it’s a game engine with-in a game engine. the goal is for people to use it to make their own games, where as copying mine (or someone else’s) and trying to make money off it is going to be prohibited.

it’s not just the hotkeys, there’s a lot of python code pre-3.0 that is really necessary here, where as the python devs in their attempts at modernizing the code framework omitted some of these features in versions over 2.7, especially in 3.0.

I will eventually try to port this to newer versions of blender, but if the code/interface wont support it then… it wont support it.

having problems trying to refine the user instancing, does blender/python do it’s own user instancing?

like if I have 30 objects sending messages to one object and that one object is set to perform a task (lets say subtract 1 from an int property) for each message, but each object may be sending it’s message at nigh the exact same time or exactly the same time. if they all happened at exactly the same time would the outcome be int -1 OR int -30?

The point of user instancing is to allow multiple objects/players to all have access to a single field, property or object to tell it to do something, and to tell the objects/players what to do while waiting for access (also known as I/O programming).

Currently I tried looping two functions triggered by a starter function.

like this: (where wait is a bool property, and WaitBool is a property actuator, Num is a int property, and subtract is a property actuator set to add -1 to Num)


def Check():
 if sens.positive:
def goTo():
if own.get("Wait") == "TRUE":
goToLoop()

def goToLoop():
if own.get("Wait") == "FALSE":
WaitBool.setValue("TRUE")
cont.activate(WaitBool)
cont.deactivate(WaitBool)
cont.activate(subtract)
cont.deactivate(subtract)
WaitBool.setValue("FALSE")
cont.activate(WaitBool)
cont.deactivate(WaitBool)

else:
goTo()

goToLoop()


but I’m getting an error (“RuntimeError: maximum recursion depth exceeded”) which is telling me that although the code is switching the Wait to false the script cannot see that it became false during it’s looping. this leaves me to have to run it again for the desired effect.

I have another way to deal with it that’s more complex and I’m trying to avoid it, it involves using the message body to send a unique object/user name then pairing this name with the requirements into a list, which requires the following list editing skills (from easiest to hardest):
1: writing to a text entry in virtual memory to treat as a list
2: reading from a text list; text.split(", ")[entry #]
3: adding an entry to the end of the list; text + ", “+ entry
4: removing an entry from the start of the list; text.split(text.split(”, ")[0])[1]

and the biggest problem is that this requires user instancing of it’s own, because multiple requests are being made on one object.

the second problem is what if text[0] is the same as other text in the list? for example the same object/user spams a message, the second message would cut off all messages following it from being retained from all users.

this requires the addition of message timing to the list where each entry is [user, message, time] instead of [user, message]

this requires message sorting based on time when writing to the list.

and even then you have the problem of 170+ computer controlled objects all spamming their message at the exact same time. so what does that need? User Instancing! now each user not only has a name but a number designated to filter their own spammy requests. so the entry becomes [#, user, message, time] from where it has to know if it should filter it as a duplicate or add it to the list. If it adds it to the list then it needs to record how many iterations of this message are open and where to find them in the list, and needs to do that for each user.

suddenly the user instancing object is a mess, because all these entries need to be stored outside the script so that they can be referenced by another script when it runs to check what to do next. that means massive amounts of file writing OR storing it in a logic brick. as the number of users may change or be randomly massive that means creating one ‘port’ for each user which in this case is a file, globalDict entry (globalDict is also a file so I avoid it, I try to stay in memory or virtual memory to keep from wearing out the hard drive) or a logic brick.

so, Help. Please.

does blender/python do it’s own message sorting/prioritization? (AKA am I making this hard on myself by not trusting Blender/python’s inherent code handling capabilities?)

or is there a better way to do user instancing?

Blender/Python does not have native user instance handling.

I was right to not trust it.

I made the most simple of all tests, I set an object with an Int property of 100, I set it to subtract 1 from this if it receives a message. then I made another object which sends the message when T is pressed, I copied that object 20 times (20 total objects sending the message when T is pressed), the outcome was when T is pressed the Int Property become 99. it should be 80 if there is any native user instance handling.

Test result: FAILURE.

I tried prodding it with code to distinguish that there were multiple different messages coming in, I even gave each message a body containing a Unique entry. the only way it would recognize those is if I manually program a bend for each one.

that may end up being what I have to resort to making 1 bend for each possible entry. that will be a massive script. :(:no:

OK the network message system was a nice option, but ultimately it looks as though I need something with a bit more control, or at least a smarter base code, for example scripts know to run parallel to each other if the script is already in use.

the problem with the network sensor (I hope you are listening blender devs!) is that there is only ‘bodies’ or ‘subjects’ there is no ‘get most recent body, getBody’ and the sensor currently doesn’t differentiate between messages with the same base subject but different bodies.

so as per usual I’m going to have to go the nonstandard way: scene.objects[‘OBobjectname’].activate(thing) in this case ‘thing’ will be:

controllerName = scene.objects['OBobjectname'].controllers['controllername']

In this way I’m skipping over non-UI sensors directly to the script which has UI capabilities.

it does make for headaches when messing about with dynamic objects or spawned objects (pity I can’t rename objects once spawned, well I could but if done more than once the game will crash.) but that’s why I need python 2.7 or earlier and not 3.0, the way things like getParent() return their information is non-replace+able.

I can also fix the headaches when dealing with dynamic object names, but I have not yet tested spawned objects. If the lack of UI in the network message sensor is any evidence I assume that if I do ‘add object’ 2 times adding the same object and parenting them to something, then proceed to do a .getChildren()[#].name and use that name as the object name to send a network message to, Both spawned objects will get the message (because from earlier tests of printing their object names I found both had identical object names!) but even that can be solved if you’re careful. just gotta know where a non-interference is in the parenting chain.

looks like that’s the only viably dynamic option.

Can’t comment on message sensors because I never really use them, but the object-renaming thing is in UPBGE:

However - you’ll get better performance (both CPU and bandwidth) by giving objects a unique ID + caching them in a separate list. Dict lookups are expensive, especially when that dict holds the entire scene.

# Define the object list somewhere
sellf.objects = []

# Spawning an object
ob = scene.addObject('Cube')
object_id = len(self.object_list)
self.object_list.append(ob)
ob['id'] = object_id

# Receiving a packet, assuming json for simplicity
object_id = packet[0]
data_type = packet[1]
data = packet[2]

ob = self.objects[object_id]

if data_type == 1:
    # Let's say 1 is for position
    ob.worldPosition = data

I’ve got a few playable examples over here:


It’s long been abandoned and the codebase is a complete mess, but it’s got stuff like chat, physics, even a half-assed vehicle demo. Maybe you can draw some inspiration from it.

There’s a cleaner version in the works, but I stopped working on it after the flagship game got ported to another engine. Perhaps when 2.8 comes around…

forgot; you can’t activate a controller from a kx_gameobject, but you can get the controller then activate an actuator defined by it, I just forget how. I used to do it for the game shown earlier. so it’s possible but right now I’m getting an error ‘can;t activate an actuator from an inactive controller’

Thanks! I just saw the reply, I’ll give this a look through!

I took a brief look yesterday, yes a lot of it will be helpful if even as a second opinion on networking code for the actual online portions.

I also tried nigh everything I could to trigger User instancing without programming it, the last test involved one object that checked if the UI object was in use before sending a value and triggering it (the idea was that if the objects themselves check the state of the value and time themselves to activate in an orderly manner that would allow the object messages to come in separately rather than all at once. but the problem here was the same problem elsewhere, the program wont wait properly, if using time.sleep() it freezes the whole game so nothing else happens in the meantime.

this means the fix is threading. basically any time I need a program to wait, I’ll have to start a thread this thread could be named by the object or some other identifier. I am a bit worried that a thread would be even more disconnected from the game and not notice changes while looping.

I fixed the lack of noticing the property change by saving the property value to an actuator field and having the program check that.

however I used a “while: continue” loop for if the property is in use, and that froze my game on it’s own and during the freeze would not accept key presses so I don’t know if it will see the property change or not. I assume it will. I will have to do the while: continue loop in a thread, luckily for me the time.sleep command is in the while:continue loop so I only need 1 thread. I know how fragile stuff like threads are I want to avoid bugs so I’ll be limiting my usage of them.

Lesson relearned.

so I was looking at threads, a series of dicts and pages of complicated sorting code. this was wrong.

any time you subject yourself to such for practically any operation you are failing to take advantage of blender’s full abilities. I failed to take advantage of it’s abilities because I was stubbornly trying to do everything in code, and code has it’s limits with how it can interact with blender for any given frame.

and frames were indeed the problem here; when you trigger a script it collects all information about it’s trigger into memory for that specific frame (there are 60 frames per second) the it instances that frame from memory. this means if you somehow extend that script past that frame and look for some sort of change in your blender game, the script wont even check the actual game, it will check it’s memory of the game as per the frame it started.

there are exceptions to this rule but they require a single bend not a loop and though can be made dynamic it can be a headache.

for example:

if sens.positive:
if not sens.positive:

the second reversal makes it check again on a new frame.

but I didn’t use that method, because even that is beating around the bush.

Yesterday I figured out that this whole problem could be solved by exiting the script by triggering a property that would run the script again. this guarantees that the script is seeing a new frame.

What came from it was Success (even though I haven’t actually tested it, I know it’s going to work, I will be completely bewildered if it doesn’t because it would defy everything I know about blender/python)

and that success was the most basic UI in a short script, no threads, no dictionaries or lists.

what is a basic UI you might ask?: The basic core of any UI; a system of control where only one user may access a field at any given time and all others wait their turn.

I went from feeling like an idiot that can’t accomplish anything to a feeling of hope where I can now see how I’m going to accomplish everything ahead of here.

Eh? Dicts are the underlying data container that Python is built upon. They’re a hash-table, and therefore very fast at lookups.
Lists are (in CPython) arrays of pointers, so there’s still a pointer chase anyway, which is likely to determine the bulk of the lookup time (vs the hash function for a basic int)

I’m not sure quite what you’re discussing in later posts, but I’d suggest this:

Networking is code-based. Therefore, your backend needs to favour use of code. If you choose to write a frontend that uses logic bricks (as my networking addon did) then that’s good too, the best of both worlds. I haven’t worked on my addon / network library for a while because fundamentally, doing bit-level work in Python is slow, and I’d probably go for something less engine-like in future (more framework based). Also, aside from that, I quite liked the declarative serialiser framework by Tomer Filiba (Construct), but it required a very different take on data handling, so it requires its own framework.

At this point, it needs to be said that, although attempting a multiplayer framework is a nice idea, I would seriously consider dropping the M for massive. Massive MORPGS are built using highly tuned server architectures, load balancers, expensive-distributed servers and a lot of work. Most of them will avoid a scripting language.

Just a quick tip for builds. Make a runtime that on start open any .blend in the same dir at start, then place your .blend and the runtime in the same dir. This way the runtime is general and can be used to run any. Blend and your .blend is still under your license. To be even safer you can make an installer that place the files where they are needed and provide the. Blend and the runtime separate. Doing so will workaround the license problems.

Put this to the test and got about 20% better performance using int lookups, but given the size of the data I was kinda hoping for more. My whole life has been a lie. Damn you CPython.

thanks for the reply.

yes I know most massively multiplayer instancing is done via expensive servers with their own instancing systems. but from doing this and asking around I found the way that those servers handle massive amounts of users is, comical at best. they basically decide that in order to do UI they have to make a UI to handle the UI and maybe a UI to handle the UI of that UI. in reality all they are doing is passing the buck, in this case the buck is a message conflict when one object receives two messages at the exact same time.

I can’t stress it enough: Only one object can write to another object at any given frame. the moment you have 2 objects writing to it is the moment you have a conflict.

it doesn’t matter if the conflict is on the player object or a dictionary being fed to the player, or in a thread feeding the dictionary which feeds the player, there is still a user conflict. it’s why many modern games have those shops which randomly eat items. “yay SUPER RARE item, I’m gonna sell it for loads of monies” drag from inventory, drop on the shop. disappears. “NOOOOOEEEEEE!!!”

it’s happened to most MMO players at some point or another. it’s a UI conflict. just so happens that the shop itself is a database. 1 whole database. and that one database is a list that is being written to by thousands of users. they separate each user’s shop list into a dictionary/list entry so the user can write to that without a problem, but then that dictionary/list must be written to the database before it can be displayed. suddenly UI conflict. Item is gone. the game ate it, your write to the database was ignored because there was no User Instancing and someone else was users()[0].

so learning from other game’s mistakes, you can’t always rely on servers’ native UI handling. there’s gotta be a system in game to handle it.

I’m not saying a Dict is bad, Dicts are very useful. but they are just passing the buck if used as your only UI method. only one user can write to a dict at a time, parallel writing is not supported.

right now I’m working on testing offline User Instancing to sandbox any problems my scripting might create before going online so that I know that any problems after this are networking script problems.

I am using code and logic. we’ll see how it ends up working on the actual character object. I’m trying to add as little as possible to it because the character already has a slew of stat properties and logic running it, I really don’t want to go over a page of logic. on the plus side I may make the stats into a single dict/list with what I’ve learned since then that should shrink the amount of logic used.

esoneson: Thanks for the tip, I may use it just to be on the safe side of things.

UPDATE : I built it the way I said and ran it, there are some timing conflicts and for some reason the script runs the logic bricks which run the script again and then the script fails to run the logic bricks again causing it to only loop once/twice. (at closer inspection it’s a timing conflict where the script is too fast for the logic bricks).

I managed to get it working though. I had to put in a stop or each object just continues responding to the UI object which means only one object gets repeatedly served and all the others keep waiting. Right now I’ve got 20 objects trying to write to one property on one object. I know a system to fix the looping problem: more communication. in fact instead of looping at all I could output the results of any calculations to an actuator value field and just have the object wait till the UI Object calls “NEXT!”

… lol… just had visions of lines here in china 3 and 4 people wide lines all trying to funnel into one service desk that can handle one persona at a time, bus doors etc. there’s only one desk but the users don’t care. it’s so relevant here; Stand behind the yellow line and wait till called. Basic User Instancing at it’s core.

Advanced user instancing performs sorting, comparing and grouping of users for a given amount of frames based on preset variables(like time). that’s the only difference. Chat will require this because of channels.

At least I can see where I’m going now. I do need to practice more with networking code so all these comments are helpful! thankyou all again!

UI Complete success.

at least AoE style message UI is a success. in AoE (area of effect attacks) things are backwards from single target or targeted attacks.

I just need to get into the mood to apply it. the test game I was going to make to apply it could do with n00b UI so I’m kinda put off it.

whats n00b UI? get the number of messages or list/dict entries. do something based on the number of entries without communicating specifics.

it’s one of those days now, where I ground through a tough bit and don’t know what to do next.

options:
1: apply the UI system to the chat then continue working on the chat.
2: apply the UI system to the test puzzle game and make more levels.
3: change of pace; make graphics like trees
4: change of pace; fix the hips rigging of the character base model
5: change of pace; modify the character base model to obtain a female character base model.
6: more code; apply newly discovered coding techniques to the main game’s system.
7: change of pace; dev work: write out the context of the game or design maps.

ok dev work sounds attractive today.

Actually no, it needs basic UI after closer inspection. So I began building the UI in to the test game which I will release in the not too distant future.

this is a welcomed change from test files, which though I could release them one by one are not entertaining at all, such as the test file for UI, open it, press T and property in question counts down to 80 while the various objects print messages to the console window describing what part of the process they are doing (for debugging so I could see where it was hanging up).

the test game is not the thing you’ve seen, it’s a simple game. I’m hoping to make it level based and add in a ton of levels. so it may take a while or become a side project. I will build the UI into the chat some time this week, I made a chat test file while at work last saturday, I got a message from file and sent it via a message actuator to another object and had that object print it and ascertain how many lines of text it was (for spacing).

seems I’m always making test files not the actual game, but that’s because I don’t want to break the game.

and with that the test game should be practically functional. whee. I expect some minor errors like having used Objectname instead of OBObjectname, or missing some capitalization etc., the error system will pull those though.

next is to move the objects into the proper layers and do any necessary scaling or rotating. then I can build levels, technically. I still need to make the special spawners, meh those are easy.

blender corrupted my file. it opens and seems to work OK but it’s adding “''” to certain entries. like own.name returns ''“OBObject”'' not in list

doing .split(“'''”)[1] returns: index out of range. returning [0] gives the same thing. this means it’s in how blender is looking for those names.

also some of my sensors are not being seen in the GE unless the object is Dynamic. given that they are collision sensors they need to be on a Sensor type object to work right but on a sensor type object the collision sensors go missing yielding errors. I found an old post saying it’s a problem with blender and blender needs to be reinstalled.

blenderartists.org/forum/archive/index.php/t-235391.html

odd. but from what I see it may have infected this particular file so even after a reinstall I’m worried the file will still be corrupt.

well so much for the test game I really don’t want to have to rebuild it. last time I had a similar bug it could be fixed by starting fresh (because other files still work as they are supposed to.)

reinstalling did not fix it, blender saved the file with it’s bug. would have to rebuild the file. maybe another day.

well so much for the test game I really don’t want to have to rebuild it. last time I had a similar bug it could be fixed by starting fresh (because other files still work as they are supposed to.)

Dunno if it’s possible for you(or to late) but open the blend1 file, and hope that he is bug free.

I would love to see your network setup, I’m working on a muliplayer game also.