Click here to Skip to main content
Click here to Skip to main content

Skype Game Infra

, 1 Nov 2006
Rate this:
Please Sign up or sign in to vote.
Using Skype as infrastructure for multiplayer games.

Sample Image

Introduction

If you have written a nice multiplayer game, which can be played only by users on the same computer (as you never had time to even start thinking on making it online) – this article is for you. It presents a simple approach for all those “networking” tasks, and comes with a simple library implementing it. So make you game online in five minutes (well, probably two hours).

Contents

Making online games

For this discussion, I want to divide this task to two separate parts:

  1. create desktop game and
  2. allow users to play online.

The first part is interesting and difficult by itself, but is totally out of the scope of current article. For example, for chess game it includes UI and game engine that will allow two people to play chess on same computer. For my demo application, I use great chess board control, created by Gregory Prentice. In addition to the nice UI, it has a fully functional chess engine which validates the moves, fires events both for UI changes (move) and game notifications (Mate!), and so on. You can read its description here, or download the most recent version from here.

Let’s look deeper into the second task – going online. Here we should look separately at:

  1. connecting users and
  2. supplying additional online services.

Opening connection between two users:

  • server-less. Connect directly to other user’s IP? Ugly and won’t work in many cases, where the user does not have external IP address (you can’t play at work!). And this is just for finding the opponent IP, take into account the firewalls, and you will see that this solution is useless in many cases.
  • with dedicated server. Obvious advantages: all users connect to known gaming server, they can see who is online etc. Building such server from a scratch is very problematic and time-consuming task. Even if you are using some existing code (for example, I saw online games based on IRC protocol), you need to manage an online server with known IP address – not something each one wants to do.

Additional services include chat window, which is a must for a game, and optionally other communication channels – voice over IP, video, etc.

Well, currently this all seems very complicated.

Using Skype as infrastructure

As you can already guess, this paragraph will explain how Skype can ease all those tasks.

Skype

I started using Skype couple of years ago for VOIP – talking to my friends and family in different countries in great sound quality. Over the time they added chat and video functionality, including conference calls.

Similar to other programs of this type, you create Skype account, mange list of contacts, see when each of your friends is online etc.

Skype API

In addition to those features, there’s a Skype Public API, which allows developing new application based on Skype capabilities. The API gives full access to all basic functionality: contacts, chats, voice calls etc. Current solution is mostly based “Application Streams” – data channels which can be created between 3rd-party applications.

Next section describes Skype API in more details. But the concept should be already clear – we will use those data streams to exchange game-specific info between players which will be all connected to Skype. This approach solves most of the difficulties in making online games:

  • All users are logged in to Skype servers and you don’t need to worry about the network layer but can use reliable connection to exchange data
  • You always know who is connected to Skype at any moment
  • Chat window, voice conversations and even video calls are available in Skype

Using Skype API

This section describes basic Skype API and a COM API, when special attention is given to topics related to “Application Streams”. The API is well documented, and can be found here. You can also use developers' forum to find answers on subjects that are not explained well in the documentation.

In the next section you can find description of SkypeGameInfra library, which wraps all relevant functionality in convenient way. You can even skip current section for now, and go back to it only when you need to get more details, or make changes.

Skype API for Windows

Application exchanges data with Skype using WM_COPYDATA Windows messages. The format of the messages is called “Skype Protocol”, which defines set of commands that can be sent to Skype. Full description of commands can be found here.

Skype4COM

In addition to Skype API, which isn’t very friendly to use, there’s a COM wrapper which represents the Skype API as COM objects with properties and events. Again, full description can be found here. I will describe the parts relevant for creating “Application Streams”.

  1. Skype is the top-level object. To create an instance:
    SKYPE4COMLib.Skype skype = new SKYPE4COMLib.Skype();
    

    This operation will pop-up a message in Skype, saying to the user that new application is attaching. The user should allow this operation (it’s recommended to use the “never ask again” option).

    Note: if by mistake you’ve disabled your application from using Skype, you can go to C:\Documents and Settings\WINDOWS USER NAME\Application Data\Skype\SKYPE USER NAME, and find your application in config.xml, UI/AccessControlList/ClientX node – just delete this whole node (make sure the numbering of Client nodes remains correct)

  2. In order to check whether you could connect to Skype, test AttachmentStatus property:
    SKYPE4COMLib.ISkype iskype = skype as SKYPE4COMLib.ISkype;
    if (iskype.AttachmentStatus == 
              SKYPE4COMLib.TAttachmentStatus.apiAttachNotAvailable) 
        { /* error */ }    
  3. Next you have to register your application. Each “application” connected to Skype has a unique name, by which it can be identified.
    SKYPE4COMLib.Application app = 
              skype.get_Application(APPLICATION_NAME);
    if (app != null) {
          app.Create();
    }
    
  4. And we also need to register on two events: ApplicationStreams and ApplicationReceiving.
    skype.ApplicationStreams += new 
       SKYPE4COMLib._ISkypeEvents_ApplicationStreamsEventHandler(
       skype_ApplicationStreams);
    skype.ApplicationReceiving += new 
       SKYPE4COMLib._ISkypeEvents_ApplicationReceivingEventHandler(
       skype_ApplicationReceiving);
    
  5. When you are ready to open connection to another Skype user, just call:
    app.Connect(skypeHandle, false);
    // skypeHandle is just Skype username
    // of the user you want to connect to

    Note: The connection is received by application registered with the same APPLICATION_NAME as your application. If no such application was registered, no connection will be opened.

  6. When the connection is finally established, you will receive ApplicationStreams notification, and from now on you can use the stream to send and receive messages.
    void skype_ApplicationStreams(SKYPE4COMLib.Application pApp, 
         SKYPE4COMLib.ApplicationStreamCollection pStreams)
    {
        SKYPE4COMLib.ApplicationStream stream = null;
        foreach (SKYPE4COMLib.ApplicationStream 
                 astream in pStreams)
            if (stream == null)
                stream = astream;
    }    

  7. To send a message just call:
    stream.Write(“My message”);    
  8. And, finally, messages are received through ApplicationReceiving events:
    void skype_ApplicationReceiving(SKYPE4COMLib.Application pApp, 
         SKYPE4COMLib.ApplicationStreamCollection pStreams)
    {
        foreach (SKYPE4COMLib.ApplicationStream 
                 astream in pStreams) {
            string msg = astream.Read();
            // process message
        }
    }

    As an example, see the GameCommunications class in the SkypeGameInfra project.

Skype Contact List control

In addition to those APIs you can use one of two ActiveX controls to automatically get list of contacts defined in Skype: “SkypeContactList” and “SkypeContactCombo”. The use of those controls is pretty self-explanatory – just add one of them to your Form.

They can be downloaded from here - “Skype ActiveX Tools”

SkypeGameInfra wrapper

It’s .NET wrapper on top of Skype COM API which encapsulates all functionality needed for a game between 2 players.

DemoSkypeChess is an example project which uses this API.

  1. Creating new instance:
    SkypeGameInfra.GameCommunication skypeWrapper = 
          new SkypeGameInfra.GameCommunication("DemoChess");

    Note: replace “DemoChess” with your unique name

  2. Let’s say the user is connected as Alex in Skype. To invite other Skype user to a game, call:
    string username = skypeWrapper.SelectUser();
    if (username.Length > 0)
        skypeWrapper.InviteOpponent(username);
    

    SelectUser opens a dialog with list of all contacts, and the user should select one of them. InviteOpponent opens “Application Stream”, and sends an invitation to selected contact.

  3. At this point, your application on the remote computer (let’s say, Bob’s), which have also performed step 1 of creating GameCommunication object with same name, will receive InvitationReceived event. In the application level you will, probably, want to show a nice dialog to the user, asking to accept or decline the game.
  4. Based on Bob’s action in step 3 AcceptGame of DeclineGame should be called, and Alex will receive OpponentAccepted or OpponentDeclined event. Starting from this point the communication channel is established: Alex plays white, and Bob – black.
  5. Each player in his turn should make a move, resulting in following call:
    skypeWrapper.Move(position);

    position parameter is arbitrary game-specific string, which will be received by the other side in OpponentMove event.

  6. Finally, the game ends when one of the parties is invoking StopGame function. This will release the “Application Steam” channel for both users, and bring the system back to the state it was after sep 1.

Links

Chess control by Gregory Prentice:

Skype links:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Michael Gopshtein
Web Developer
Israel Israel
No Biography provided

Comments and Discussions

 
QuestionCan't able to run, PinmemberVinish Kumar26-Jul-13 0:22 
Generalgreat article! Pinmemberiamveritas26-Feb-12 13:09 
GeneralGreat Idea PinmemberSamNaseri1-Nov-11 14:24 
General[Message Deleted] Pinmemberit.ragester28-Mar-09 5:35 
GeneralExcellent Sample [modified] PinmemberOleksiy Sokolovskiy17-Jul-08 16:50 
Generalabout skype API Pinmembermarcelaviles8-May-08 4:58 
GeneralRe: about skype API PinmemberMichael Gopshtein8-May-08 6:07 
QuestionStream Pinmemberfreediver21113-Dec-07 16:29 
AnswerRe: Stream PinmemberRobinBlood8-Jun-08 1:52 
If you have a 2nd PC (or VMWare) I would suggest to install C#-Express on both and register a 2nd Name on Skype.
In this case you can debug on both while initializing the communication.
Just make sure you leave the current Method on one PC before you look at the "ApplicationStream" of the 2nd.
 
For a quick hint:
'Alex' selects a User -> 'Bob'
while he's OPENING_CONNECTION app.Connect() is called.
 
'Bob' receives an ApplicationStream with the PartnerHandle: 'Alex'
and skype invokes an AppicationStream back to 'Alex'
 
'Alex' receives the mentioned stream with PartnerHandle 'Bob' and
compares with the invited Opponent -> MATCH !
Alex writes Game_Invite on the stream.
 
'Bob' ApplicationRECEIVING: "Game_Invite" and writes Invite_ACK back on the Stream
 
'Alex' ApplicationRECEIVING: "Invite_ACK" and sets status to 'Waiting for Bob to Accept'
 
'Bob' presses the YES Button on the MessageBox and Game_Accept is written on the Stream.
Status changes to "Waiting for Alex to Move" and the Board is flipped
 
'Alex' ApplicationRECEIVING: "Game_Accept" and calls OpponentAccepted()
Status changes to "Playing with Bob, your move"
-----------
Now the Game is played and who is in control calls wrapper.move and set Status to
"Waiting for Opponent to Move"
 
This invokes opponent.move on the 2nd PC and sets Status to "Playing with Opponent, your move"
 
The Complete Game is played over the Stream (calling ApplicationRECEIVING). From Time to time,
Skype updates the Stream calling ApplicationStreams but you don't recognize while playing.
 
Thanks for the Artikle and Best Regards
RobinB
GeneralThis is great! Pinmembercairoso20-Aug-07 16:21 
GeneralCool indeed! Pinmemberzeev.blac14-Aug-07 21:33 
GeneralThanks Pinmemberhimalayantravel19-Apr-07 8:20 
QuestionWhy? PinmemberALEXNG8811-Apr-07 22:45 
AnswerRe: Why? PinmemberMichael Gopshtein11-Apr-07 23:04 
GeneralRe: Why? PinmemberALEXNG8818-Apr-07 23:19 
GeneralRe: Why? PinmemberMichael Gopshtein19-Apr-07 5:34 
GeneralRe: Why? PinmemberALEXNG8819-Apr-07 7:14 
GeneralCool! PinmemberSteve Echols1-Nov-06 19:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140814.1 | Last Updated 1 Nov 2006
Article Copyright 2006 by Michael Gopshtein
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid