Details on multiplayer demo in the BGE?

I received a message in my inbox, asking for further details about networking in the BGE. The content hasn’t any sensitive information, so I think it is best to answer here:

Hey @Koto

I can understand why it is hard to follow, the goal was not for people to understand how it internally work, but I was hoping to develop a framework that people could use, making things simplier. Turns out I gave up both on the framework and the BGE. Ha.

In my implementation, I used the callback approach: because we don’t know exactly when we will receive a message, you can register a function that would be called by my system when a message finally arrive. The game could continue while my library was doing the waiting somehow.

But since I don’t plan on maintaining this extension, either try to reverse engineer the BGEz framework, or learn how to make your own.

Note: If someone wants to reverse engineer the framework, you should definitely read the test suites that we wrote, we tried to cover most of the code base, testing most use cases. It should give good hints on how things are designed and how it works. You will then be left with understanding implementation details.

I would still recommend making your own thing, since I think you have more chances of doing something yourself than waiting for someone else to do it for you. If it is not there, don’t wait for someone to do it, else forget about it.

Now if you don’t know anything about scripting, let me tell you that unless someone makes an easy script/addon for you, you are fucked. You will have to learn a lot about programming and networking.

So if you are serious about making multiplayer work in a game engine, you must know that the BGE doesn’t help you at all here. You should try to learn about the following:

  • Get familiar with Python programming
  • Get familiar with concurrent programming (notably how to handle asynchronous code)
  • Get familiar with Python’s networking modules
  • Learn how to use these modules in the BGE
  • Search a way to use Python + a concurrent model + socket/networking library inside the BGE

This can take up to multiple months of learning + experimenting, your mileage may vary.

But maybe some people can shim in here and provide all kinds of links and/or explanations too :slight_smile:

2 Likes

its best to make your own system to suit your needs. that way you can optimize it more. I used struct to compact the data being sent and it worked great

I would be willing to seriously, hypothetically, consider joining a supergroup dedicated to improving the knowledge and norms regarding networking in the Bge, if and only if the following, extremely limiting conditions were met.

The only part of the project I would work on is Python and documentation.

The project limited it self exclusively to non blocking tcp and or reliable udp. It would explicitly not provide higher level functions such as remote procedure calls, attribute reproduction, or predictive logic.

Some one with reasonable upload speeds provided a server they had physical access too. The server would be in the dmz, would have vnc access, and the host should be prepared to easy wipe the server.

The project would be distributed as part of UpBge. In addition, UpBge would resume distributing compiled Linux versions, and the compiled versions would be accessible threw deep links.

Note that this post is meant to state needs, initiate discussions, and judge interest. It is not meant to be socially binding, ether for me or for respondents. It may move in that direction, tho.

Edit:
Sorry, it looks like I accidentally hit the wrong reply button. This was meant to reply to the thread as a whole.

If you only do TCP/UDP template for the BGE, what good is it to have a server? What would you host?

Meanwhile, if you want a repository to upload your sources to, you can either start making Pull Requests on UPBGE’s repository, or make your own GitHub/GitLab/BitBucket repository.

What I was considering is a networking library specifically designed for the bge, that covers transport-session-presentation.

Transport
I have looked at some of your networking code. I believe you used a library to support asincio. I figured, but did not check, that the library is compiled. This means someone would have to compile it. Seems like no one wants to compile UpBge, including myself. In addition, I need UpBge to be accessible threw deep links for another project. Not having to deal with distributing compiled libraries would be sort of like part of the payment for my labor.
Reliable Udp wouldn’t need an extra library, but I might need help doing it. Personally I would prefer tcp/udp combo, but this is apparently controversial.

Session
The library would assume a server/client architecture, and would have functions for both. It is feasible that I could run the server and client on the same computer, but I don’t intend to. Theirs weird stuff like nat hole punching, no test for lag and local caches. It’s just different. I might also experiment with other services such as 0mq. I have some experience doing networking, and I don’t really want to go there again unless I have a real server.

Presentation
The library would reproduce messages using sendMessage(). People would be expected to know what to do with those messages once received.

It is important to note that I cant really do all this on my own, so who ever else was there would have a say as well. If no one else wants to do it, or we cant get what we need, then that’s just what it is. Also, let me be clear on this, I will not be coding in C.

I feel like this bit could do with more elaboration and emphasis: The BGE does not have any multiplayer in it at all. When we add multiplayer, what we’re actually doing is using native Python to do all the heavy lifting, and communicating the results to the BGE. In my networking game, the network communication is so separate that you could use it all without even using the BGE. In fact, the server side is literally just a Python script.

It feels counter-intuitive, but resist the urge to put “BGE” in any of your Google search terms when learning networking, because it isn’t BGE related. You can try it all out in a Python terminal first, then add it to your game.

Tip:
Any command that you put into the Python terminal that doesn’t immediately return (i.e. not letting you type another command instantly) is referred to as blocking. Any command that is blocking will also hold up frames when put into BGE, thus making your game look like it’s frozen up. The reason people shy away from TCP is because by default, trying to receive will block the thread until it gets data.

1 Like

I did use asyncio, but it is not compiled. It is part of Python’s standard library since 3.5+. I did try to use the uvloop library that was supposed to be an event loop drop in replacement for asyncio, but this one used to be compiled indeed, and since it didn’t run on Windows IIRC, I dropped it and went back to vanilla asyncio since it works out of the box everywhere.

Done, just write Python, I don’t see why we would need native code at the moment :slight_smile:

:thinking: Running a server on localhost should be as good as running a server remotely. Most of the struggle when working on remote servers is that people often don’t configure their NAT correctly, but if you can get 2 local sockets to do what you want, then it will work on a bigger network as well.

I would go as far as saying: You should make lots of terminal-only / pure-Python experiments before trying to apply that to the BGE. But it is up to you :slight_smile:

Hence why I cannot emphasis enough: If you want to learn programming AND networking, then you should look for resources about concurrent programming. It is essential in my opinion.

A bit of a heavy read, but the following article seems to explain the problem properly:

Edit: I should add that most async/networking tutorials assume that you are in control of your “main” function for your program. In the BGE, you don’t control the “mainloop”, but you are called on each “tick”. You then need to think about giving the control back to the BGE if you don’t want to freeze your game.

1 Like

The following code blocks. I looked at some of your code to see what you did. I remember it using websockets. The tutorial you linked uses aiohttp. Those both have compiled libraries. If we use a local host then there is no way to test lag, so it wont block anyways. What am I doing wrong? I’ve done something similar to what @TheDave is referring to and if I could use asincio then I would very much prefer it.

import bge

if 'frameTime' in bge.logic.globalDict:
    bge.logic.globalDict['frameTime'] += 1
else:
    bge.logic.globalDict['frameTime'] = 0
print('\n-'+str(bge.logic.globalDict['frameTime'])+': tick-')


from asyncio import get_event_loop, sleep, open_connection
from random import randint
import requests

event_loop = get_event_loop()

async def longTask(taskId, secs):
    print(str(taskId)+': sleep for '+str(secs)+' secondes.')
    path = 'https://archive.org/download/AboutBan1935/AboutBan1935_edit.mp4'
    r = await requests.get(path)
    print(str(taskId)+': slept for '+str(secs)+' secondes.')

event_loop.create_task( longTask(bge.logic.globalDict['frameTime'], randint(1,10)) )

print(0)
event_loop.run_until_complete(sleep(0))
print(1)

You are using the standard requests library, which is blocking. So when you do:

r = await requests.get(path)

What actually happens is that the requests.get(...) call will block, and then the result will be handed to the await statement. For it to properly work with asyncio, you want functions that either return coroutines or Future/Task objects.

See: https://stackoverflow.com/a/22414756/7983255

On the other hand, while I use asyncio in the most recent versions of BGEz, it wasn’t always the case. I had a hard time understanding the library, so I preferred doing my own full implementation of an event loop and the infrastructure required to run coroutines using it:

bgez-network-test1.zip

This demo uses simple UDP running on my own event loop, pure Python.

But in the end I removed everything to finally use asyncio since there is a big ecosystem around it, and my implementation was quite naive.

Stop bringing the “compiled libraries” argument, the biggest issue with things like aiohttp is to correctly get pip to install it for you. But this can already be done in a similar fashion than what I already did for a different game (the one that used websockets):

Or you can work around blocking code thanks to asyncio by running it in a thread, and wrapping the asynchronous operation into a nice little Future or Task object.

Asyncio is part of Python’s standard library, and hence is pre-built by default for all platforms. You don’t need to care about whether or not it needs to be compiled, it is already there and ready to use.

My original post was an offer not a request. Possibly, I am not qualified to make such an offer, but it still stands as stated. The initial prototype I made using the stackoverflow link you provided appears to be working correctly. I will not likely trust it until I test it in an implemented scenario, tho. Most of the parallelism tutorials I’ve read don’t quite work in the Bge. I appreciate your help. :thinking:

To be fair I don’t plan on doing any major work on the BGE anymore, but I am more than willing to help clear some things out, would that be required. The origin of this thread was simply to answer @Koto and maybe help others that would have questions on the topic of networking inside the BGE.

Yes, because most tutorials don’t assume that your script is not in control of the whole application. But if you understand the concept behind what is demonstrated, it usually isn’t a big issue to port to the BGE.

Going through it once again:

These make sense.

I don’t see the point here, so it will be up to someone else to provide this. IMO local development is more than enough. If you want to artificially increase latency you can always add sleeps in your code (in the non-blocking parts of course). But anything that works locally will work remotely, only the timing will be a bit different. Blocking calls will still be blocking, they will just block for more or less time, hence why everything should be thought happening asynchronously from the get go.

This can be done later, depending on the quality I suppose. It will involve asking the people maintaining UPBGE to integrate the work into their repository. Since the implementation can be pure Python, it will be the equivalent of distributing this networking py module to be usable out of the box by UPBGE projects. bgeio would be a funny name if it ends up using asyncio :wink:

On my end, what I offer is support with both low and high-level issues (quirks of some libraries, ways to get it to run in the BGE, how to think about it, etc…). Best case scenario and I’ll write a few lines to help, no guaranty.

^ that.

When I wanted to gauge latency, I did it the fun way by sending my friends zipped bundles with the project + dependencies and we had a great time testing/playing.

Hey can you make a tutorial how to do netwromg in UPBGE?

I’m sorry, it’s not someting I’m interested in doing. Most of the challenge is just basic network stuff with Python, which there are heaps of well made tutorials out there for.

You’re welcome to look into my network game (SpellShips - Multiplayer (TCP) MOBA) and I’d be happy to answer questions about how it works, concepts and such, or why I did things the way I did. You can even gut the network stuff out of it and use it to make your own game.

1 Like