DirectPlay:
Basics
By: Jack Hoxley
Written: July 2000
Without a doubt internet gaming
is going to be huge in the next year or two (depending on when you read this).
As you, the games writer, you will probably want to jump on the band wagon and
join in. Luckily, DirectPlay allows us to do this with as little hassle as possible.
There are two (connected) problems
with making a DirectPlay application; the main one being resources. Most games
will use a main server - do you have one? unlikely. There are several different
communication types - do you have enough hardware to test all of these? You
may well be able to get a friend to help you out by playing dummy for your testing
- but it could take hours, if not days to sort something high quality out; will
your friend be able to give you that much time (it's possible).
There are a few words, terms
and processes that you will need to understand before embarking on your voyage
into DirectPlay:
Term/Word |
Meaning |
Service
Provider |
A service provider
can be thought of as the hardware that will serve your connection between
computers. The four main ones available to you are: Serial Cable, IPX (LAN),
Modem (Normal net connection)and finally TCP/IP. It is possible to create
your own, but there is unlikely to be any need with these four (common)
providers available to you. |
GUID |
Your program
must have a unique identification string. This is required so that you dont
accidentally join an online game for a different game (ie, Quake or Red
alert). This GUID has to be unique - DirectX has a method (explained later)
that you can use to get a completely random string. This GUID must be the
same for EVERY copy of the program - you cant choose a new one each time
you start the program up.... |
Initialising
a connection |
This isn't actually
where you connect to the server, or other players - this is where you check
if things are working correctly. In almost all cases IPX connections will
appear in the enumerated list, but it is quite unlikely that there will
actually be any hardware present - the IPX driver is built into windows.
This process checks the connection and reports back to you if it succeeded
or failed. |
Starting
or Joining a game |
This is where
we choose either to be the host of the session or to join a session started
somewhere else. Both require different operation by your program - which
can be where DLL's come in handy. If you are the host you have to control
everything, set things up etc... If you're a "joiner" then you
can effectively sit back and do very little.... |
Players |
This should
be fairly obvious, you'll need to create a player for yourself when you
enter the game - this keeps track of sending you the correct messages and
updating the correct things. Some games will have a limit on the number
of players that are allowed. |
Gameplay |
When there are
enough players connected you can start a game - Directplay doesn't care
how many, the number is up to the host and/or the programmer. You normally
get between 2 and 32 player games. The gameplay section also involves sending
information between players - such as messages (that the user will see)
or packets of data that update your computer (the player will not see these). |
Terminating
a player or a game |
Although you
can often get away without explicitly closing everything down it is a good
idea to do it. Because a player can leave at any time you may well want
to tell the server this - so it can make changes (allow another player,
or alert other players) |
Getting Started
As mentioned earlier you will need several objects to link with DirectPlay;
and you will also need a GUID. To get a guid, try this method:
1. Start a new application; this
can either be the project you will use to make a DirectPlay program, or a new
one.
2. It must be connected to DirectX - See Linking DirectX
to your project
3. Put this code in the Form_Load procedure and run your application:
Dim Dx as New DirectX7
Clipboard.Clear
ClipBoard.SetText Dx.CreateNewGuid |
|
|
|
4. Now run your application and
close it again. Now paste (Ctrl + V) into the IDE and you will get a completely
unique string. For example; the one I got was:
{8EC1E2EC-5266-11D4-811C-AD15B9B82C76}
Don't use this GUID for your application, because I have already got it - generate
your own.
Now you have a GUID we can start
to create our DirectPlay application. This next piece is from the Declarations
section of the example project:
Option Explicit
Dim Dx as New DirectX7
Dim Dp As DirectPlay4
Dim DpEnum As DirectPlayEnumConnections
Dim DpAddress As DirectPlayAddress
Dim Session As DirectPlaySessionData
Dim DpEnumSessions As DirectPlayEnumSessions
Dim PlayerIDNum As Long
'Remember: dont use the GUID shown below for your
own games.
Public Const MyGuid as string = "{8EC1E2EC-5266-11D4-811C-AD15B9B82C76}" |
|
|
|
Host or Player?
Now we need to choose whether or not we want to be a host, or a player...
(A host still plays though)
Normally you should let the player
decide this, when playing a game you normally want the person with the fastest
connection doing the hardest work (ie. the host). Your application will have
to differ slightly in the initialisation process depending on what the user
wants to do.
First, we need to create a list
of the available connections; remember that a connection will appear even if
the user's computer cant actually use it.
'First we create the DirectPlay
object
Set Dp = Dx.DirectPlayCreate("")
'Then we fill the enum object with details of the
available connections
Set DpEnum = Dp.GetDPEnumConnections("", DPCONNECTION_DIRECTPLAY)
'Then we list them in the listbox control....
Dim I As Integer
For I = 1 To DpEnum.GetCount
List1.AddItem DpEnum.GetName(I), 0
Next I |
|
|
|
Then, we have two different pieces
of code - the first one creates a new session (Game) that others can join. The
second just looks for games that have already been created.
'This creates a sesson -
so we have [almost] complete control of the settings.
Set DpAddress = DpEnum.GetAddress(List1.ListIndex + 1)
Call Dp.InitializeConnection(DpAddress)
Set Session = Dp.CreateSessionData
Session.SetMaxPlayers 8 'only allows up to 8 players
in the game
Session.SetSessionName "ThisNameWillAppearWhenOtherPeopleLookForGames"
Session.SetGuidApplication MyGuid 'The game will use
our GUID
'These two flags should be fine for almost any application
required.
Session.SetFlags DPSESSION_DIRECTPLAYPROTOCOL Or DPSESSION_MIGRATEHOST
'Now we create a session based on the information
we
'just provided.
Call Dp.Open(Session, DPOPEN_CREATE)
List1.Enabled = False |
|
|
|
'Assuming this all connects
properly, we should be left with a list of all the games being played. This
'Is where testing becomes difficult.
Set DpAddress = DpEnum.GetAddress(List1.ListIndex + 1)
Call Dp.InitializeConnection(DpAddress)
Set Session = Dp.CreateSessionData
Session.SetGuidApplication MyGuid
Session.SetSessionPassword "" 'Set this to be nothing
to search for non-passworded games
Set DpEnumSessions = Dp.GetDPEnumSessions(Session, 0, DPENUMSESSIONS_AVAILABLE)
Dim T As Integer
For T = 1 To DpEnumSessions.GetCount
Set Session = DpEnumSessions.GetItem(T)
List2.AddItem "[" & Session.GetCurrentPlayers & "/" & Session.GetMaxPlayers
& "] " & Session.GetSessionName
Next T |
|
|
|
Now, We need to create a player
for us.
Remember, assumingt hat someone else is playing, all these commands will be
mirrored - the program only ever creates 1 player in code - but because it's
being run lots of times it will end up creating lots of players.
'Some variables to hold
the data
Dim tmpFriendlyName As String, tmpFormalName As String
'Get some input from you regarding what player you
want...
tmpFriendlyName = InputBox("Please enter your nick name, or 'friendly name':",
"Create Player")
tmpFormalName = InputBox("Please enter your formal name, ie. Jack Hoxley
(for me)...", "Create Player")
'Now we create a player - the function returns a number
(ID) that we can use
'To identify ourselves with later....
PlayerIDNum = Dp.CreatePlayer(tmpFriendlyName, tmpFormalName, 0, 0) |
|
|
|
Assuming that everythings going
to plan, people should be joining the game; this next part is only relevent
to the Host section of your code. Although we've specified so far that we will
allow up to 8 players, we dont actually need that many - that number is just
a limit. The host could decide to start play with 2,3,5,7 players - if you (the
programmer) allow it, he/she could decide when to start the game. When you start
the game, you must stop other people from joining it mid-game.
'First we create us a data
object
Set Session = Dp.CreateSessionData
'then we retrieve the current session data
Dp.GetSessionDesc Session
'then we add JOINDISABLED to the current flags in
place
Session.SetFlags Session.GetFlags Or DPSESSION_JOINDISABLED
'We stick the modified data back in again....
Dp.SetSessionDesc Session |
|
|
|
Now no one can jump into our
game.
See the Messaging
Tutorial for the real insides of DirectPlay.
Closing things Down
The final stage of a game is where it all finishes; this can either be when
all the players have left; the game is over, or an individual player has left
the game. This is fairly simple really and doesn't necessarily have to be done.
If just a player is leaving it
is a good idea to send a message to all players that you're leaving; although
DirectPlay should do this automatically, you may want to include additional
data.
Other than a terminating message;
all that is left is to destroy the objects that we created:
'It is a good idea to destroy
the root object last; in this case Dp is the root object.
Set DpEnum = nothing
Set DpEnumSessions = nothing
Set Dp = nothing |
|
|
|
Finished!!
You should be able to knock something simple up fairly easily now. From then
onwards it's about refining and adding to the code. Where possible, using two
computers will help a lot with writing a multiplayer element into your games.
|