IRC Client inside BGE using Python.

So I coded an IRC client in python using the built in sockets module. I run it from the command line, no pygtk/gui nonsense. Quite straightforward because I am aiming to implement it in to my game in BGE. The only issue I think that may arise, is threading. It runs a loop in the main code-flow to basically check for new messages from the IRC server, strip the messages to only show the actual message being sent, and then print them. But once it successfully logs in, it spawns one thread that is a loop to check for user input, and then it will send a message if the user presses return.

I just don’t know how to really implement this into BGE. This is how far I am / what I am thinking of trying. Any help is heaps appreciated! :slight_smile: So tell me if my methodology/thinking is wrong!

My plan, is to have a scene that will act as a “HUD” and can be toggled. This scene will show the chat, players online on IRC, and chat prompt to send messages.

So I have the HUD scene, and I can toggle it with “overlayscene” and “removescene.”

If I have the IRC code run in the HUD scene, when it gets toggled, it is “removed” so it would terminate the code, right?

If that is true, then I thought that I could just have the code run in the main scene and then store the chat buffer into globalDictionary and whenever the HUD scene is toggled it will call that to populate the text UI. But this is assuming that the code will still be running when the main scene is suspended. Is that true?

Another problem arises when the player enters other levels/scenes completely. If I put the code into the main scene, then it would be terminated when switching to another scene, right?

So I guess my main question is: How will I be able to keep my two loops (one is a thread, of course) running when switching to different scenes?

If the IRC script could run in the background somehow, then all I would have to do is send the messages from the server to globalDict and I could access it from any scene.

I was thinking that I could just use a “overlayscene” thingie, and have the script run in that “HUD” scene. The only problem is I don’t know if the IRC code will be terminated when the scene is toggled…Idk, I feel quite lost.

Thanks guys in advance!! :slight_smile:

Are you using blocking or non-blocking sockets for your IRC client? If your sockets are setup in non-blocking mode then you can get rid of the client thread by replacing it with an “Always” sensor that checks for new IRC traffic once a frame.

As far as keeping your IRC client running, one way is to implement your IRC client in a Python module. A module can keep data separate from the scene lifecycle. You can create an object that manages the IRC connection and stores all the chat information and that object will stay around as long as the BGE is running your process. When you add your HUD scene, the HUD should query the IRC client to see what it should be displaying.

Ohkay thank you so much!

One other question: If I put a max of 18 lines, 64 characters each line max, into a globalDict entry, would that be ohkay to do? It seems to be working like this:

import bge
def printlog():
controller = bge.logic.getCurrentController()
owner = controller.owner
bge.logic.globalDict[“chatlog”] = “”“Christa: Hi guys
TOM32: I’m 42, not 32 years old!
Jimskinator: Haha what an old fart!
explosiondestroyer123: lol wut an00b
Christa: Awe he’s not a noob… Stop being meanies!
TOM32: I’m 42, not 32 years old!
Jimskinator: Haha what an old fart!
explosiondestroyer123: lol wut an00b
Christa: Awe he’s not a noob… Stop being meanies!
TOM32: I’m 42, not 32 years old!
Jimskinator: Haha what an old fart!
explosiondestroyer123: lol wut an00b
Christa: Awe he’s not a noob… Stop being meanies!
TOM32: I’m 42, not 32 years old!
Jimskinator: Haha what an old fart!
explosiondestroyer123: lol wut an00b
Christa: Awe he’s not a noob… Stop being meanies!
Christa: Awe he’s not a noob… Stop being meanies! Awe he’s not a k
“””
# 64char/line and 18 lines.
owner[‘Text’] = bge.logic.globalDict[“chatlog”]

I was planning on just storing the chat log into globalDict, so I tested it with the above code just creating fake chat and putting it into globalDict.

So when the HUD scene is toggled, it will just grab the chat from globalDict, which will be constantly updating through the python script (module).

Does that seem a good way to do this?

Personally, I would store the chat history as part of the IRC client in the same module. If you wanted to save it between game runs then you would have to do the manual saving/loading but it would free you up to use a more natural storage format. Like just keeping each chat line as a separate piece of data and storing that. It would free you up from the arbitrary limits 18 lines of 64 chars max each. That is less than 1024 bytes and honestly not anything to worry about even on a phone these days.

For reference I sometimes have to use uncompressed bitmaps that are 1024x1024 on smartphones and those are 4 MB in size. You would need 4,000 of your 18-line histories to match that in size.

Ohkay thanks!

I’m stuck right now though… Whenever I start the game, it freezes as the IRC client module loops. The game won’t continue until the loop exits. How do I set it up to loop, and yet still be able to run the game?

Like you said you can set the sensor on an object to “always,” but then when I leave that scene, I lose the connection to the IRC server because it stopped looping. <----- It freezes like the looping way

Sorry for asking so many questions =( Thanks for your help!! :slight_smile:

PS: I guess what I’m asking is how do I have my IRC client stay active when going to other scenes? SOLVED

You should only execute you IRC loop once each frame (e.i. don’t loop at all). An Always logic brick set to pulse mode will handle the execution of your client each frame for you.

As for the client persisting across multiple scenes, I would recommend creating a scene dedicated to your client (and any other code that needs to maintain it’s state when changing scenes. Just use and overlay scene that you never get rid of with an empty that has the necessary logic bricks to run your code.

First of all, thanks for helping a noob; me! :slight_smile:

I now have it setup with an overlay scene and the empty has an always with pulse mode, connected to a python module “irc.main.” (to check for ping-pong from the server, check for messages; to keep the connection alive.) and then an always connected to a python module “irc.login.” (to initially connect to the server).

It connects to the IRC servver and channel, but my game freezes until the script stops, like when I had it looping. =(

Your socket communication is probably “blocking”. That mode is the default mode for sockets so if you didn’t change it yourself then that is what mode you are in.

In a nutshell, when a socket is in “blocking” mode, then when you make a call to read data, the program will not continue until some data has arrived. In “non-blocking” mode, the call returns immediately and you have to check to see if any data arrived.

I’m assuming that your original system had the socket code in a separate thread. That would not freeze your program because the thread with the socket could wait for data and you had another thread that kept the UI alive.

The suggestion for the BGE is to change that a little bit because the BGE seems to like to have only one thread. (I have never tried to use multiple threads so I’m not sure what the specific issues are.) The way you have to change your code is you have to put your socket into non-blocking mode and drive it with the Always sensor. This lets the Always trigger your network code once a frame, and you check to see if there is data. If there isn’t any data to read then you just return and your script will check again on the next frame. If there is data then you process it.

The fact that your script can return is what keeps the BGE from getting frozen.

Check out these threads for some discussion about the specifics of setting up non-blocking mode.

http://blenderartists.org/forum/archive/index.php/t-281324.html
https://blenderartists.org/forum/showthread.php?303237-Blender-Game-Networking-using-TCP-IP

Also, this is a sample program that I wrote that demos non-blocking TCP communication in the BGE.

Another option is to try keeping your thread. As long as it is not doing too much work and you are using proper thread synchronization techniques then I don’t see a technical reason why the BGE should have a problem with it. But once again, I have never tried this myself so I’m not sure.

Attachments

bgeServer.zip (68.1 KB)

Ohhhh!! Ohkay thanks so much I finally got it working! Thanks to you guys of course! :slight_smile:

Two other problems which are unrelated are:

  1. When I press enter, BGE registers when I press enter and when I let go, yielding two messages being sent.
  2. My text is really low detail and I can’t figure out how to make it “better.” Like I tried changing the resolution in the “text” panel, but that didn’t work. The game is running at 1280x720, so it’s not that…

Here’s a screenie:


This is normal. Sensors trigger every time they change state so you can detect when they turn on and when they turn off. You want to run your “Enter” keypress logic only if the the key sensors is positive.


enterPress = cont.sensors["enter"]

if enterPress.positive:
  # do stuff

  1. My text is really low detail and I can’t figure out how to make it “better.” Like I tried changing the resolution in the “text” panel, but that didn’t work. The game is running at 1280x720, so it’s not that…

Here’s a screenie:
[ATTACH=CONFIG]292929[/ATTACH]

Unfortunately, I have not tried to do text in the BGE so I cannot comment here.

For your text why don’t you check out the blf module. There’s a pretty good example of how to use it on the modules page, and you can change the fonts dpi so you can have nice and crisp text.

Here’s a link to the blf documentation: http://www.blender.org/documentation/blender_python_api_2_69_1/blf.html

Thanks Kastoria that worked! (=

Kevin, thanks for the suggestion, I’ll definitely try it out next release!
I’m trying to release it today, on my birthday =P, but I’m running into “file not found” errors. =( So I have to figure something out to fix those before I re-make the whole text “system.”

If you guys have any ideas on the file not found errors, that would make my day :slight_smile: But I know this is getting way off topic on this thread though =/


Thanks guys though for all your help! IRC is now seamlessly working!!! Yay!

I’m guessing those messages are what you’re getting when you try to pack your resources (and each path is one of the resources)? Make sure the paths are correct and relative (not absolute). You can make paths relative in the External Data menu (File > External Data > Make All Paths Relative).

As for the text resolution, have you tried using a simple Python script to adjust the resolution of the text? This should do it:



from bge import logic

cont = logic.getCurrentController()

obj = cont.owner

obj.resolution = 5


Beware not to use too high a number, as it can hang Blender for a long period of time.

Thanks Solar! That helped, but it’s still pixel-ated, not nearly as much though.

It seems that it’s capped at 32.

hmm… I saw that someone else made a blenderirc… I want to be able to do that myself XD