LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

MPSET & MPGET

Root / Programming Questions / [.]

MZ952Created:
I was attempting multiplayer functions earlier, and I couldn't get MPSET and MPGET to function as I thought they would. The manual labels them as a sort of "register," which I had assumed were registers which could be read from and written to universally from all connected users. This is the general code I was using: HOST SYSTEM
MPSTART 2,"1"
WHILE 1
 LINPUT"";T$
 IF LEN(T$)>0 THEN MPSEND T$
 MPSET 0,1
 WHILE !MPGET(1,0)
  WAIT
 WEND
 WAIT
WEND
GUEST SYSTEM
MPSTART 2,"1"
WHILE 1
 WHILE !MPGET(0,0)
  WAIT
 WEND
 MPRECV OUT ,T$
 PRINT T$
 MPSET 0,0
 WAIT
WEND
Just in case the code is wrong, the purpose of the program was to take input from the host system, send it over to the guest system and wait for its confirmation, then start over again. The output of the program was constantly printing out T$ to the guest system regardless, while when I had stopped the program to check the state of the registers using MPGET, I found MPGET(0,0) was 0. I'm not quite asking for a solution to my problem, I just want to know if there are any special things about MPGET and MPSET I should know. Do they take up more than one frame to read and send, while still maintaining program execution? Could it be the MPSEND which creates some kind of delay? MPGET requires for its first parameter a value denoted as the 'Terminal to read from' or something like that. Why would MPGET need to know from which terminal to "read" from if the registers are universal among all connected systems? It must mean that the registers are not universal, and that each register pertains to its own system, right?

Check the usage of the first OUT parameter of MPRECV. I believe a negative value indicates that no new message was received, meaning the contents of T$ is undefined. EDIT: I should say, the effect of the command, on the contents of T$, is undefined.

Check the usage of the first OUT parameter of MPRECV. I believe a negative value indicates that no new message was received, meaning the contents of T$ is undefined.
So the halt and continue system I'm trying to use is not relevant because I can check the first OUT parameter for a negative value? That's actually useful. I read in the manual that using MPSEND over some (undefined) rate will result in a Stack Overflow error, which seems to be untrue for repeatedly changing the values of the registers. The registers seem to be a valuable tool for multiplayer communication, and I just don't understand why my setup didn't work. Edit: Could it be that MPSET on the guest system cannot change the value of a register on the host system because the registers are not universal among all connected systems?

MPSET/GET access the same variables on all connected systems. The first argument is just the variable number, it doesn't matter which system you're on. Wait nevermind I was wrong MPSET only sets the variables on YOUR system. To access them from another system you need to use MPGET(system,variable)

Yes, MPSET has the advantage that it will never generate a communications-related SmileBasic error. It has the disadvantage that not every update to the variable will necessarily be propogated to all consoles (and that a small set of numerical values just isn't as expressive as a string for some communications). So, for indicating "The player just moved 1 step forward!", MPSEND is best, for indicating "This is the number of steps forward the player has moved:...", MPSET is best. I would use MPSET as much as possible, and where I use MPSEND, throttle its use and ensure enough MPRECVs are being executed (otherwise, some messages may get silently lost - EDIT:so, I guess, "not every update to the variable will necessarily be propogated to all consoles" is not a disadvantage of MPSET that MPSEND doesn't suffer from too).

It's too bad there's no way to check how full the MPSEND buffer is. If you send more than 4 strings without them being received, data will be lost. note: The strings I used for testing this were all 128 characters long, so you might be able to send more smaller strings. But there is a hard limit around 15 where the Communication buffer overflow error happens.

Yeah, I've played around with the functions a little more. So long as you're running a loop at a two-frame-and-above delay, Communication buffer overflow errors are far less frequent. You can pile thousands of maximum-sized MPSENDs onto each other, and the propogation delay of MPSET makes it far less useful than just waiting a frame and bussing a 128 character long string around. It seems that MPSEND stores the data it "sends" onto the system-that-sends; no information is transmitted when MPSEND is called, only when MPRECV is called. (I wonder what the Communication buffer overflow error really is ... )

It's too bad there's no way to check how full the MPSEND buffer is. If you send more than 4 strings without them being received, data will be lost.
MPSTART 2,"1"
WHILE 1
 MPSEND"A"*128INC N?N
 WAIT 2
WEND
It seems to send it without error continuously, but it loses its data? Edit: I tested this, and it seems to replay the hundreds of MPSENDs "sent" to it.

Having a 2 frame delay seems like it would make the game really slow and laggy. I think we need to investigate MPSEND more, since it doesn't seem to be very well understood. The only thing I've used it for is sending files, where the goal was to send a lot of data as fast as possible, but if you're using it in a game, you'll want it to send smaller amounts of data with no delay, which is very different.

... I think we need to investigate MPSEND more, since it doesn't seem to be very well understood ...
I think you're right. When I started using these commands, I noticed right away some things happening which didn't seem right.

I investigated this a while back, and I thought I reported my findings on SBS, but I can't find it. Maybe it was moved or deleted, or maybe I'm misremembering.
It seems that MPSEND stores the data it "sends" onto the system-that-sends; no information is transmitted when MPSEND is called, only when MPRECV is called. (I wonder what the Communication buffer overflow error really is ... )
I don't think this is quite accurate. I think when MPSEND is executed, it stores the message in an outbound queue stored locally on the console. Periodically (maybe approx. once every 2 frames, IIRC), everything in the outbound queue is transmitted, regardless of MPRECVs happening or not happening on other consoles. An overflow error occurs if this outbound queue overflows. When messages get received, they get added to a 16-deep inbound queue. If a message is received when the queue is full, no error occurs, the last element of the queue gets overwritten. I hope I'm remembering all that right. EDIT: here it is: http://smilebasicsource.com/forum?ftid=171 Odd: it belongs in Bug Reports, I'm pretty sure I didn't put it in Programming Questions. Someone misfiled it, apparently. - Hey 12, you're an admin, can you put it back where it belongs? And, now that I see this, it has me a little concerned - is there an easy way to find out if other posts of mine have been misfiled?

I investigated this a while back, and I thought I reported my findings on SBS, but I can't find it. Maybe it was moved or deleted, or maybe I'm misremembering.
It seems that MPSEND stores the data it "sends" onto the system-that-sends; no information is transmitted when MPSEND is called, only when MPRECV is called. (I wonder what the Communication buffer overflow error really is ... )
I don't think this is quite accurate. I think when MPSEND is executed, it stores the message in an outbound queue stored locally on the console. Periodically (maybe approx. once every 2 frames, IIRC), everything in the outbound queue is transmitted, regardless of MPRECVs happening or not happening on other consoles. An overflow error occurs if this outbound queue overflows. When messages get received, they get added to a 16-deep inbound queue. If a message is received when the queue is full, no error occurs, the last element of the queue gets overwritten. I hope I'm remembering all that right. EDIT: here it is: http://smilebasicsource.com/forum?ftid=171 Odd: it belongs in Bug Reports, I'm pretty sure I didn't put it in Programming Questions. Someone misfiled it, apparently. - Hey 12, you're an admin, can you put it back where it belongs? And, now that I see this, it has me a little concerned - is there an easy way to find out if other posts of mine have been misfiled?
I might have accidentally moved it while I was cleaning up the bug reports forum a while ago. It's back now.