Code archives/Networking/Tracking multiplayer objects

This code has been declared by its author to be Public Domain code.

Download source code

Tracking multiplayer objects by RifRaf2009
i found this to be an easy way to track objects that need to be found later over a multiplayer game. Such as Land Mines, Grenades, power up collection objects and especially player created items & objects. Basically all this does is use the millisec() timer to create a unique name that cannot be duplicated so you can create and find the same object

if its the server making the unique name, then I dont add a header , but if its a client making an object I give it a unique name with a header (such as the clients network id number) because the client and servers Millisecs wont match the header assures a unique name, and allows the server to know at any reference who originated the object


a short example would be a client sending the server a command to create a land mine. The server does so and makes a unique name. It sends the creation packet along with the unique name to all connected clients.. They then make the landmine locally , all using the same unique name as a field.

Later a mine is detonated and the server sends out the detonation command along with the unique name, now all the clients can remove the proper land mine.
Function Create_UniqueName$(time=5,header$="")
unq$=Mid$(Str$(MilliSecs()),time,time)
NowLen=Len(unq$)
needed=time-nowlen
If needed>0 Then 
	For i=1 To needed
		unq$=unq$+Chr$(Rand(32,120))
	Next
EndIf
Return header$+unq$
End Function

Comments

TaskMaster2009
That will get you random, but how do you know it will be unique? It could possibly create the same name twice. Unlikely, but possible.


RifRaf2009
I think you glanced at this and assumed too much, study it a bit. Its not random, and it cannot create the same name twice until millisecs flips the fith digit place, wich will take a bit. If you think you game object will exist for more than that time, just snag another digit, say 6th place wich is hours of time, or seventh for a loooong time.

I updated the function to allow a time field. indicating wich place in the timer to grab a name, the default is 5th place wich is a unique lifetime of about 99 or 100 seconds. 6th digit gives you a unique lifetime of about 999 to 1000 seconds and 7th 9999 to 10000 seconds.. and so forth.

The random values are fillers if the millisec timer is recently flipped and not long enough , but even if it is just 1 in length that will give the number a unique name all the time.


TaskMaster2009
So, you grab a Unique ID at Millisecs() of length 7.

Lets say it is 1234567.

It is entrely posisble that Millisecs() will return 1234567 again. Computers execute way more instructions that just one per millisec.

If you ask for two objects int he same cycle, it is possible they will both be 1234567.


RifRaf2009

If you ask for two objects int he same cycle, it is possible they will both be 1234567


thats why theres a header feature task. please look at the function closely. If you want to call more than one just add an id header. You would need to cluster your creations for this to be a concern at all. I dont do that in my project its all done case by case , not grouped so one millisecond is not a large enough span to cause problems. however if you do cluster creations, use the header


like this..
MineCount=MineCount+1
MineNAme$=Create_UniqueName$(5,"M"+str$(minecount)+"_")

NadeCount=NadeCount+1
NadeNAme$=Create_UniqueName$(5,"N"+str$(nadecount)+"_")

Now I dont put headers on anything , as I havent ran into the same name in months of testing tiny tanks.


TaskMaster2009
Hmmm, why not just start at 0 and index them, from 1 to 2 billion. If you happen to get to 2 billion without restarting the server, then you can start over at 0. :)


RifRaf2009
lol, well 2 billion!!

You could do it that way, but I prefer to let the timer do it for me. The concept is the same. Wich is the main thing I was sharing.

I thought that was obvious :)


Xzider2009
The way I tracked objects/users/npcs in my multiplayer game was simply an index starting from 0, and incrementing by 1 each time a new one was created. Very simple and works perfectly for my game.


Bobysait2009
It is entrely posisble that Millisecs() will return 1234567 again. Computers execute way more instructions that just one per millisec.

it's right ^^
And using a header to modify the different name is a solution, but I prefer not having to do extra-stuff for this kind of work ( in my opinion )

If you want I made something using string, that will give infinite different names based on string increment

( I updated it to add a "Header" feature as yours )

Global gCurName$="hdspovnbs"
; Feed should be 1,3,5,7,9,11,15,17,21,23,25
; +> for best "random" use 5,to 17
; ( Do not use 13 as 13*2 = 26, it will result in the sames 2 End-String letter rolling )
Function UnknownPlayer$(header$="",feed%=17)
	; iterate throw the string
	For l = Len(gCurName) To 1 Step -1
		curchar=Asc(Mid(gCurName,l,1))-Asc("a")+feed
		feed=0
		If curchar>25 curchar=curchar-26:feed=1
		p1$="" : p3$=""
		If l>1 p1$=Left(gCurName,l-1)
		p2$=Chr(curchar+Asc("a"))
		If l<Len(gCurName) p3$=Right(gCurName,Len(gCurName)-l)
		gCurName=p1+p2+p3
		If feed=0 Exit
	Next
	If feed gCurName="a"+gCurName
	Return header+gCurName
End Function

Graphics 800,700,0,2
SetBuffer BackBuffer()

For n = 1 To 180
	j=j+15
	If j>680 j=15:i=i+200
	Locate i,j:Print UnknownPlayer("["+RSet(n,2)+"]")
Next
WaitKey
End



_Skully2009
You can use an incremental numbering system, and if each player is creating them tack on their IP


Code Archives Forum