Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / DarkNET problem with multiplayer

Author
Message
Maniek2512
8
Years of Service
User Offline
Joined: 7th Aug 2015
Location: somewhere in the Internet
Posted: 8th Aug 2015 00:30
Hello, I'm new there. I'm looking for something like "how to add stable ID to multiplater or something"

Firstly - my firend it's writing a game in DarkBasic Pro but he doesn't know english and don't know anything about multiplayer.

I helped him to do the multiplayer but we don't know how to give the option to change cars for players.

I think we need stable ID- then we can create accounts on website (using mysql etc.) there we can save to accounts- what cars players have but we need how to send the information about car (TCP/UDP ?).

I think the best way to understand this it's a simple sample program.. but I didn't found any of them.

Could sb help me how do this?
Using example from DarkNet (CubeWorld).

Add to this example option to change car (cube,sphere etc.).


Sorry for my english (I learn this only 4 years by myself).
If u can't understand something write there I try to explain this more.

Thanks a lot !
MrValentine
AGK Backer
13
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 8th Aug 2015 15:38
Maniek2512 Welcome to the TGC world, if you feel you struggle to make your point in English, try both, your origin language [it helps if you tell us what it is too lol] and then also English...

I think your message above is clear enough...

I am not currently that well in tune with Networking to really explain anything at this point...

It might also help if you explain what your game engine is designed for, is this a persistent game world? like World of Warcraft? or a per game mode like Counter Strike?

If it is either, I would suggest an Online Profile System... if like WoW, then I would suggest an Extended Profile System...

Good luck!

Cescano
9
Years of Service
User Offline
Joined: 4th Sep 2014
Location: Italy
Posted: 8th Aug 2015 15:48
As stable ID you probably mean a static IP.
You can have it by renting a dedicated server or a VPS (Virtual Private Server), which is cheaper.

Implementing multiplayer in your game it's not that easy:
you need to know how to setup the server you are renting, you should be able to code in php, and if you want a database like you are requesting you should be able to code in mysql as well.
You also need to know how to let communicate the dbpro game with the server, there are a lot of obstacles actually.

If you don't know how to code in php and mysql, then your first step would be installing xampp, a php editor, and practice with these 2 languages offline, when everything works offline rent a server and test the php and mysql code there.
Maniek2512
8
Years of Service
User Offline
Joined: 7th Aug 2015
Location: somewhere in the Internet
Posted: 8th Aug 2015 18:05
We want to create a racing game.
People can create their own servers like in Counter Strike.
I know PHP and MySQL so it's not a problem. My friend know DarkBasic but he never use multiplayer (DarkNet). So I want to help him how to do this.

We test connection with php and DarkBasic in other project and all it's work fine.

But we want do the multiplayer. Connection works, cars showed etc.
Only one thing what we don't know it's how to give option to change cars for every players.

For example:

We have:
server
player 1 car: cube
player 2 car: cube
player 3 car: cube

now all players have the same car for example they have cube
I want to know how do something like this:

When u connect to server u can choose between- cube and sphere (for example)

So then we should have something like that:

server
player 1 car: cube
player 2 car: sphere
player 3 car: cube

etc.

I want to write something in DarkBasic to help my friend but I don't know this language
I do something like this:



Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 10th Aug 2015 10:19
Quote: "Sorry for my english (I learn this only 4 years by myself)."


You've done very well! English can be very difficult to learn!

Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 10th Aug 2015 13:35
Dark NET provides nice examples that you can play with, practice with and build from. Use the TCP connections to arrange new games and transmit chat messages; use the UDP for vehicle updates, and away you go.

Check out the cube world example, it is a good starting point.

Maniek2512
8
Years of Service
User Offline
Joined: 7th Aug 2015
Location: somewhere in the Internet
Posted: 16th Aug 2015 14:06
I know this examples. We try to write that what we need but it not works. For example:
when 1st player join he saw his car (CAR ID: 1)
when 2nd player join he saw player 1 car (CAR ID:1) and his car (CAR ID:2) but player 1 see his car (CAR ID:1) and player 2 car has the same car as player 1- CARE ID:1 (but he takes CAR ID:2).

We don't know how to send info for all players what car each player choose.

It will be nice if sb can explain this, or write short example on cubes- changing colors or making cube, sphere etc.


I show u on picture what we want to do:
Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 17th Aug 2015 11:56 Edited at: 17th Aug 2015 12:04
One of the difficult things when learning how to develop multiplayer games is rushing, and not paying attention to the details which is what makes it more complicated than it should be.

The first thing to do is to slow down, and take one step at a time. The more you concentrate, the sooner you will get the job done.

The second thing to realise is to break down the requirement into simple instructions.

Problem
We want to let each player know what cars the other players chose.

Local Solution
Set each player object source or array field to the required car.

Local to Remote
Send each player object source or array field to the required car.

Remote Solution
Receive each player object source or array field for the required car. Then set it on the other machine (or window).

So...


You have broken down the requirement into 2 smaller requirements; you need a local (on the same PC) array of players with selected cars, and a remote version of the same thing.

You need to SET locally, and SEND to the remote PCs; then you write the code to RECEIVE the instructions.

Now that we have the solution, turn it into code.

Code solution

Find where each player sends their client ID; and send also their car ID; or even the name of the car model if you required.

Do not focus on security and optimization at this stage which is premature in this context and level of programming; leave that for later when you get some more experience and a working engine.

So here is where the players find out who joined:

You already know how to set your data, Here is the place to send your data.



Send a new SizeT or use mn Add Int to send a car ID; or mn Add String to send a string if you want to send the model file for testing purposes. Generally you only need to send IDs for things, the only strings you send are names, messages and string settings. You want to send it to all the players expect the one doing th sending... Thats the packet at the end of the above snippet.

This seems like a good place to receive your data.



You must receive the in the same sequence as you send. If the first packet field is the operation, and the second is the player ID, the third is your car ID.


So think set, send and receive; set, send and receive.

Invest some to learn how to use memblocks (and Matrix1 Banks), they can make the task a little easier by sending and receiving arrays instead of scattered variables. Perhaps next week after you complete the current task.

Maniek2512
8
Years of Service
User Offline
Joined: 7th Aug 2015
Location: somewhere in the Internet
Posted: 18th Aug 2015 00:03
Ok thanks. I know where the server should send packet to player and I know where players receive this.

Only one thing what I don't know is where I can send info about CAR ID.
I don't have idea for this ;/


Now I do something like:
when 1st player join then server don't send info about what car he have
when 2nd player join then server send info about 1st player
when 3rd player join then server send info about 1st and 2nd player
when 4th player join then server send info about 1-3 players but then 1st and 2nd player have carid = 1

I know there is propably a simple error but I don't know that language that good and my friend don't know nothing about multiplayer ;/

I translate him what u write there but he also don't know where the client should send info to server about his car.

I really want to help him but I don't know how.

I will but there what I'm write:

Client:






Server:

Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 18th Aug 2015 21:48 Edited at: 18th Aug 2015 21:54
You can pick object IDs on the server; send an additional entry containing the client ID (playerID) on the server. Don't bother to make objects on the clients using their own ID numbers, unless you want refer to them through a UDT array.

Send them their IDs from the server; the players need not pick their object IDs; unless you want to get into key/value dictionaries.

` Tell clients that a new client has joined
mn Add SizeT SendPacket, OP_NEWPLAYER
mn Add SizeT SendPacket, clientID
mn Add SizeT SendPacket, CARID
mn Send All TCP 0,SendPacket,0,0,Joined

Store clientID in ID
ID = mn Get SizeT(RecvPacket) // < Server's client ID; not client's client ID (which is always zero if I remember correctly )

Instead of
if CARID = 1 then Make Object Cube Player,50
if CARID = 2 then Make Object Sphere Player,50
if CARID = 3 then Make Object Cylinder Player,50
if CARID = 4 then Make Object Cube Player,50
if CARID = 5 then Make Object Sphere Player,50
if CARID = 6 then Make Object Cylinder Player,50

use something like
if CARID = 1 then Make Object Cube Player, ID
if CARID = 2 then Make Object Sphere Player, ID
if CARID = 3 then Make Object Cylinder Player, ID
if CARID = 4 then Make Object Cube Player, ID
if CARID = 5 then Make Object Sphere Player, ID
if CARID = 6 then Make Object Cylinder Player, ID

or
if CARID = 1 then Make Object Cube Player, ID + 50
if CARID = 2 then Make Object Sphere Player, ID + 50
if CARID = 3 then Make Object Cylinder Player, ID + 50
if CARID = 4 then Make Object Cube Player, ID + 50
if CARID = 5 then Make Object Sphere Player, ID + 50
if CARID = 6 then Make Object Cylinder Player, ID + 50

or
Dim Client(MaxClient) as ClientType
Client(ID).Object = 50+ID // Or Client(ID).Object = Reserve Free Object() in Matrix1

if CARID = 1 then Make Object Cube Player, Client(ID).Object
if CARID = 2 then Make Object Sphere Player, Client(ID).Object
if CARID = 3 then Make Object Cylinder Player, Client(ID).Object
if CARID = 4 then Make Object Cube Player, Client(ID).Object
if CARID = 5 then Make Object Sphere Player, Client(ID).Object
if CARID = 6 then Make Object Cylinder Player, Client(ID).Object

It is just a matter if you want object IDs to be global or local. If global, all object IDs refer to the same player; id local; then everyone's object ID is different on each client, but client IDs always refer to the same player anyway.

The easy way to is to stick with global IDs so that there are consistencies with reference numbers; except local client IDs and stuff not shared online.

[PC 1: ]
[PLAYER 1 OBJECT 1 CLIENT 1 LOCALCLIENT 0]
[PLAYER 2 OBJECT 2 CLIENT 2 LOCALCLIENT 1]
[PLAYER 3 OBJECT 3 CLIENT 3 LOCALCLIENT 2]
[PLAYER 4 OBJECT 4 CLIENT 4 LOCALCLIENT 3]


[PC 2: ]
[PLAYER 2 OBJECT 2 CLIENT 2 LOCALCLIENT 0]
[PLAYER 1 OBJECT 1 CLIENT 1 LOCALCLIENT 1]
[PLAYER 3 OBJECT 3 CLIENT 3 LOCALCLIENT 2]
[PLAYER 4 OBJECT 4 CLIENT 4 LOCALCLIENT 3]


[PC 3: ]
[PLAYER 3 OBJECT 3 CLIENT 3 LOCALCLIENT 0]
[PLAYER 1 OBJECT 1 CLIENT 1 LOCALCLIENT 1]
[PLAYER 2 OBJECT 2 CLIENT 2 LOCALCLIENT 2]
[PLAYER 4 OBJECT 4 CLIENT 4 LOCALCLIENT 3]

Simple is not always simple in the long run, but that should be good enough for now.

Maniek2512
8
Years of Service
User Offline
Joined: 7th Aug 2015
Location: somewhere in the Internet
Posted: 19th Aug 2015 22:43
Yes but I want to give players the ability to select a car model.
Now it's working like this:
player 1 join- have red color
player 2 join- have green color- player 1 didn't see him but player 2 see player 1
player 3 join- have yellow color- player 2 didn't see him but player 2 and 1 see player 3

etc..


link to my video test on YT: https://www.youtube.com/watch?v=gBjK3Nq1hNM

CLIENT:













SERVER:


Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 20th Aug 2015 12:52 Edited at: 20th Aug 2015 12:55
One problem is that you have set clientID = mn Get Client ID(0) on the client. You have two variables that have been confused. Client, and clientID. You have your player set clientID to its client ID, which is always 0...

If Object Exist(100+ID) <> 0 = FALSE

Because IF Object Exist(100 + 0) = TRUE


So firstly, clientID should be carID; the client already knows its own ID; which is zero. The other players will not add client zero, since client zero is always the local player

Second, since the carID is represents the car's object; lets make things easier to read by naming it carObjectID

Thirdly, as mentioned before; set the carObjectID on the server, not the client. So remove:
xxxxxx clientID = mn Get Client ID(0) xxxxxx - Server does not need this
xxxxxx mn Add SizeT SendPacket,clientID xxxxxxx - Server knows your global ID, infact it knows before you do!

mn Add SizeT SendPacket,Kolor ---- This is fine; the players can pick their car color, and car choice; but not the globalID
mn Send TCP 0,SendPacket,0,0,1


Server:
clientID = mn Get SizeT(RecvPacket) xxxxxxxxx - Server does not want players to tell the server their global ID.

CARCOLOR = mn Get SizeT(RecvPacket) - Yes, players can tell the server what color they want

---------------------------------------------------------------
Next, as was mentioned before, set carObjectID on the server, not the client:

Server
carObjectID = Client+100 // Tell the client who joined; the object ID's of the OTHER players
mn Add SizeT SendPacket,OP_NEWPLAYER
mn Add SizeT SendPacket,Client
mn Add SizeT SendPacket,carObjectID
mn Add SizeT SendPacket,CARCOLOR
mn Send TCP 0,SendPacket,Joined,0,0

Server to tell the new player their object ID
carObjectIDForNewPlayer = Joined+100 // Send the ID to the client who joined:
mn Add SizeT SendPacket,carObjectIDForNewPlayer
mn Send TCP 0,SendPacket,Joined,0,0


Client to receive their object ID
carObjectID = mn Get SizeT(RecvPacker)
Make Object Cube carObjectID, 1

---------------------------------------------------------------

Change the names of your variables; they will cause confusion:

Make sure your variable names are consistent; you have client, clientID, player, car all mixed up names making things very difficult to read. The name of the variable should be the same everywhere; the name of one thing here should have the same name elsewhere.

- Change the name of clientID to carObjectID; (you already have a variable named client which has the same meaning as clientID; it is confusing and could lead to human error.

- On the client you are using the name player = client | id = clientID; lol, too confusing.

Use:

mn Add SizeT SendPacket,OP_NEWPLAYER
mn Add SizeT SendPacket,Client
mn Add SizeT SendPacket,carObjectID
mn Add SizeT SendPacket,CarColor

Operation = mn Get SizeT(RecvPacket)
Client = mn Get SizeT(RecvPacket)
carObjectID = mn Get SizeT(RecvPacket)
CarColor = mn Get SizeT(RecvPacket)

Not


Operation = mn Get SizeT(RecvPacket)
Player= mn Get SizeT(RecvPacket)
ID= mn Get SizeT(RecvPacket)
CarColor = mn Get SizeT(RecvPacket)

mn Add SizeT SendPacket,OP_NEWPLAYER
mn Add SizeT SendPacket,Client
mn Add SizeT SendPacket,clientID
mn Add SizeT SendPacket,CARCOLOR


-------------------------------------------------------------

The more tidy the more easy

Maniek2512
8
Years of Service
User Offline
Joined: 7th Aug 2015
Location: somewhere in the Internet
Posted: 20th Aug 2015 21:11
I do that as u write.
I see all objects but the problem is color of objects.

What I noticed: color of object for 1st client is sent after 2nd client join
for 2nd client is the same color is sent after 3rd client join.

Client:



Server:

Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 21st Aug 2015 11:11 Edited at: 21st Aug 2015 11:14
Ok, this section pasted below is for telling the player who just joined the game, who is currently playing.

At the moment we have two problems.

1: The car colour being sent is the wrong one.
2: The for loop iterator variable i has been changed from [/u]client[/u] as is in the original example; so the code is sending the same client to the player who joins.

(SERVER)

for i=1 to MaxClients
carObjectID = Client+100 // Tell the client who joined; the object ID's of the OTHER players
mn Add SizeT SendPacket,OP_NEWPLAYER
mn Add SizeT SendPacket,Client
mn Add SizeT SendPacket,carObjectID
mn Add SizeT SendPacket,CARCOLOR
mn Send TCP 0,SendPacket,Joined,0,0

This sends all the cars to the player who joined, but it is sending the same colour. Change it to something like this, where you lookup the colour from the connected players:

for otherClient = 1 to MaxClients
carObjectID = otherClient+100 // Tell the client who joined; the object ID's of the OTHER players
If otherClient<> Joined And mn Client Connected(INST_HOST,otherClient)
mn Add SizeT SendPacket,OP_NEWPLAYER
mn Add SizeT SendPacket,otherClient
mn Add SizeT SendPacket,Players(otherClient).CarObject
mn Add SizeT SendPacket, Players(otherClient).CarColor
mn Send TCP 0,SendPacket,Joined,0,0
EndIf
Next otherClient


Use an array to store your player data when they join.

Maniek2512
8
Years of Service
User Offline
Joined: 7th Aug 2015
Location: somewhere in the Internet
Posted: 21st Aug 2015 22:07
I do again exacly that what u write but I had the same problem.
So I put this:




before




and the array shows me CAR COLOR when the Client join to server (not like earlier when 2nd player join)

I put this
and this is working as earlier - when 2nd player join then shows 1st player car color.

So i think problem is if structure.
I will try to solve this problem but if u know the solution it's could be nice if u share

BTW. Really big thanks for helping me
Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 22nd Aug 2015 13:02
No problem. Can you upload the whole project so I can take a closer look?

Maniek2512
8
Years of Service
User Offline
Joined: 7th Aug 2015
Location: somewhere in the Internet
Posted: 22nd Aug 2015 18:00
Client:





Server:
Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 23rd Aug 2015 11:43 Edited at: 23rd Aug 2015 11:48
A few changes to fix the problem.

1- The Dim Players and type declarations where moved to the start; these need not run more than once in this pattern of code.

2- The color is being sent after being joined, so a new operation was added: OP_SETCOLOR. Now the server sends the new client, and then receives the color options, and then relays the color options. Before, the server did nothing after receibing the color option after send the new player object without any color.

3- Players(otherClient) was changed to Players(Joined) on the server's new player procedure. Now only the player who joined is sent to the other players. Before it was sending the last possible player in the array, who happened to not be connected. The otherClient variable is an enumeration of the FOR otherClient to MaxClients section, so it happend to = MaxClients. You are sending the new player outside of that FOR loop using the global send command; mn Send All TCP .

4- GOTO command was replaced with Repeat : Wait : Until Scancode() because you should not use GOTO commands. There is only once or twice in 10 years you would ever need to use GOTO, and that's only when a nested For loop tree gets messy, and you need a quick fix to exit the loops before any refactoring (tidying) can take place, and it can be used for certain styles of error handling;

but DO NOT use it because there are better alternatives way more easier to work with.

You can improve your code by making it more tidy with indents (tabs/spacing), functions and good coding practices you can learn at School/University/Books.

Use Dark Dynamix for car racing games, much better than Dark Physics. Have you tested the Dark Physics vehicle engine?


Remember to put this stuff at the start of your program; atleast until you get more experience.

MaxClients = 10
type DataTest
CarObject as integer
CarColor as integer
endtype

Dim Players(MaxClients) as DataTest


Client


Server


Maniek2512
8
Years of Service
User Offline
Joined: 7th Aug 2015
Location: somewhere in the Internet
Posted: 23rd Aug 2015 12:32
Thanks a lot !

I use DarkPhysics only for this test. In our game we use DarkDynamix but we need to made good car physics. If u have may be some links how to setup car physics it's could be great

because now sometimes front of the car is goping up when u start or when u turn left or right car rolls over :v

Now I must show this for my friend and try to explain him what is for what and tell what u writing .

Once more- thanks !
Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 24th Aug 2015 11:47
No problem. Good luck

Login to post a reply

Server time is: 2024-04-25 18:25:05
Your offset time is: 2024-04-25 18:25:05