(Solved) How to send a message

i know this is a very basic question, but after looking at blender documentation, youtube, and forums i thought that for sure i had the syntax of this script correct and that it should be working, but that must not be the case because it is not working.

OBJECT1 script snippet (sending):

bge.logic.sendMessage("!allow","78","player_head","NPC")
print("Working")

**Note: the format is (subject,body,to,from) i filled in all slots just to be sure it knew which part was the object to send to, but i would like an alternative

OBJECT2 script snippet (receiving):

bpy.ops.logic.sensor_add(type='MESSAGE', name="Message_1")
message_1 = owner.sensors["Message_1"]
message_1.subject = "!allow"

if message_1.positive:
   print("Working2!!")

Any help is greatly appreciated,
Thank You

bpy does not work in game engine.

http://bgepython.tutorialsforblender3d.com/GameObject/sendMessage

to recieve use a logic brick (message) connect to python.

def recieve_message(cont):

    sensor = cont.sensors['sensor_name']

    if sensor.positive:
        #do stuff
        if sensor.subject == 'any_subject':
            #do specific stuff

or you can use a global variable

global var
var = "message"

@Daedalus_MDW It works, but erk…

@littleman27 you shouldn’t use the bpy API inside the BGE, as it is the Blender Editor API (BGE and Blender are two different entities).

So if you want to use BGE’s messages you would have to use a message sensor on each object that should receive messages, and only then use the Python API to send messages (this means that AFAIK you can only send and not receive using pure Python, you have to depend on a sensor brick for the reception, but you can then fetch the data from the sensor in Python !)

@Cotaks has something that should work.

The alternative way would be to implement a small messaging module so that everything feels neat and tidy, but maybe you don’t want to spend your time on that :slight_smile:

how often has anyone considered using bpy with packaged blender that runs the game on startup?..

I don’t know how plausible this is…

either way, there should have been a sticky years ago that states bpy and bge are not compatible. :grin:

Here you can read about it - it is really basic and maybe this website will help you to find an answer http://bgepython.tutorialsforblender3d.com/GameLogic/sendMessage

Okay bge does not mix with bpy. I was just trying to use pure python code. if there is a way to create sensor and actuators in bge, please let me know. Otherwise thank you for telling me it is impossible so i don’t waste more time lol.

@wkk I am unfamiliar on what message module you are talking about, could you elaborate so that i could consider making it, if i know how and if it’s worth it

in the bge are a messagesensor and actuator for it or you can code it.

for example
logic.sendMessage(‘hit’,’’,‘player’) ### this means the subject ‘hit’ will be sending to the obj ‘player’

yeah it’s working now with

Receiving:

message_1 = cont.sensors[“Message_1”]

But i still wonder about Sending:

bge.logic.sendMessage(subject,body,to,from)

is there a way to only have subject and to?

i just noticed that your did “” for the body, is that the fix?

# send the message around the blend to any sensor that is looking for a message to recieve
bge.logic.sendMessage(subject)

# set the tag without caring about the position.
bge.logic.sendMessage(subject,to = 'object that needs to recieve it')

Or you could indeed put the body on blank with ‘’ as the above sample shows.

good when it’s working now :slight_smile:
send a message with only subject + to is not working because the body is in the middle of them - if you don’t need the body use ‘’ for empty body.
when more objs will become the same message use only the subject, but use it carefully

did not test it but should work, you set the to = ‘’, so it knows the receiver, thus skipping the body.
its like the animation system obj.playAnimation(name,start, end, speed =0) works as well while speed is the 6 option or so in that action string.

if it works - it’s fine and good to know^^ thanks :slight_smile:

My opinion:

Message work the best when the sender does not know the recipients. Therefore a “To:” is not necessary.

The big benefit is, both objects (the sender and the recipient) can work independently. It does not matter if the other exists (what it is or if there are more of them).

On a 1:1 situation (the sender knows the recpient, there are other options, e.g. accessing the recipient’s properties, or running code with the recipient.

what i think i understand from what you said is that, it is better to have 1 script on 1 object. using that one script and having somthing like

objects = bge.logic.getCurrentScene().objects
    player_body = objects["player_body"]

to control what OTHER objects do.

Is that correct? Is that possible?

@Cotaks i don’t think that bge.logic.sendMessage(subject, to="player")

for two reasons, (1) as @ChaosfuchsGameDev mentions the body field is in between them, and i that is what i initially did and then realized the message was not being send. (2) the console always tells me that the “sendMessage” module, does not take keyword arguments (Example: to=“player1” ((or)) from=“player2”) but it does take integer arguments (i think that is what it’s called) which is like (hello, player, player2) in a format that would be, subject,to,from and yes i know that is not valid but just for an example.

I greatly appreciate all of the suggestions. Do you think i can say that, No i can not skip the “body” field, and that i have to use “” if i want an empty body field?

Yes, that is possible.

You already know the sender object (the current one).
You can find the recipient the same way you let the message system find it: by name. So your code does that (Remark: it finds just one object with that name).

Is that correct? This depends on your design. When both objects should have a strong dependency, I do not see why not. Just be careful with the responsibilities. In this case, the current code has responsibility for both objects.

Regarding the function call in Python: optional parameters are always after mandatory parameters. They are still positional paramters (´the position needs to be preserved), you can’t skip in-between parameters. So yes, you need to explicitly set the body field to it’s default “”.

yeah, to=“player1” won’t except from the bge, because the variable name = to
so this means:
bge.logic.sendMessage(subject, body, to, from) ## this informations tell you, for what the variables are standing
bge.logic.sendMessage(‘hello’, ‘’, ‘messageHolder’, ‘messageSender’) ### so it is correct, you can use only strings for the variables - for example for dynamic sending:
own[‘intProp’]=2
‘hit’+str(own[‘intProp’]) ### maybe for the sound effects

If you want to use pure python (No logic bricks) don’t send a message. Instead, maybe, get the scene object.

sce = bge.logic.getCurrentScene()
PHB = sce.objects[‘player_head’]
arm = sce.objects[‘player_armature’]

if something something:
PHB.do something
arm.playAction(“something”, blah, blah,blah)

or player health.

if something happens:
PHB[‘Health’] = 0

Something like this, Not at my gaming PC, ATM. code, spelling may be wrong.
But you get the idea.

P.S. when I do use a message, I only use the subject.