Basic question: how to count number of players?

PaulT
edited May 2012 in Any Topic & Chat
Hi all, first-time Photon user here.

I adapted your code sample into my Marmalade-based game and was able to get basic command sending back and forth.

Apologies for the noob question: How do I count the number of players currently in the game? I couldn't quite glean this from the documentation.

Comments

  • Hi.
    When you join a room, then you will receive a join response from the server. This join response will hold the list of actors as an array. Just read out the length of the array from its wrapper-object and you know, how many actors are currently in the room.
    After you have joined a room, you will receive an event for every actor joining and every actor leaving the room, until you leave it yourself, again, so you can just increase/decrease your player count on every received join-/leave-event.

    PS: This is a client-related question and you are interested in information for Marmalade clients in cases in which the client-platform matters like concrete code-smaples. You should alway post client-related questions into the according subforums (which would mean "Native" for Marmalade), so that the people, who can help you best, will be more likely to see your thread.
  • Thanks, Kaiserludi! I really appreciate your swift response.
  • Kaiserludi wrote:
    Hi.
    When you join a room, then you will receive a join response from the server. This join response will hold the list of actors as an array. Just read out the length of the array from its wrapper-object and you know, how many actors are currently in the room.
    After you have joined a room, you will receive an event for every actor joining and every actor leaving the room, until you leave it yourself, again, so you can just increase/decrease your player count on every received join-/leave-event..

    Hi Kaiserludi,

    How exactly do I go about reading the length of the array from its wrapper object? I notice I do get an EV_RT_JOIN call to the PhotonPeerEventAction() in my listener class, but I only get one call for the joining player, so that player ends up counting to 1 player instead of 2.

    Your sample code has the following:
    ExitGames::Hashtable* eventData = ((ExitGames::ValueObject<ExitGames::Hashtable>*)photonEvent.getValue(ExitGames::KeyObject<nByte>((nByte)EV_RT_KEY_DATA)))->getDataAddress();
    

    So presumably I can use that to get the event data? How then do I query it? It's a hash table, so presumably I need to know the key in order to find the appropriate value among the key/value pairs ...
  • OK ... I figured out that I can do the following:
    case EV_RT_JOIN:
                    case EV_RT_LEAVE:
                    {
    			        ExitGames::ValueObject<ExitGames::Hashtable>* actorList = (ExitGames::ValueObject<ExitGames::Hashtable>*)photonEvent.getValue(ExitGames::KeyObject<nByte>((nByte)EV_RT_KEY_ACTORLIST));
                        if (( actorList != NULL ) &&
                            ( actorList->getSize() != NULL ))
                        {
                            m_Game.SetNumPlayers( *actorList->getSize() );
                        }
                        break;
                    }
    

    So that's good, but then how do I iterate over that actor list and figure out which one is the local client?
  • Hi.

    You can do the following on receiving the event:
    int p = 0, amountOfActors = 0;
    int* actors = 0;
    if(returnValues.getValue(ExitGames::KeyObject<nByte>(P_ACTORNR)))
    	p = ((ExitGames::ValueObject<int>*)(photonEvent.getValue(ExitGames::KeyObject<nByte>(P_ACTORNR))))->getDataCopy();
    if(returnValues.getValue(ExitGames::KeyObject<nByte>(P_ACTORS)))
    	actors = ((ExitGames::ValueObject<int*>*)(photonEvent.getValue(ExitGames::KeyObject<nByte>(P_ACTORS))))->getDataCopy();
    if(returnValues.getValue(ExitGames::KeyObject<nByte>(P_ACTORS)))
    	amountOfActors = *((ExitGames::ValueObject<int*>*)(photonEvent.getValue(ExitGames::KeyObject<nByte>(P_ACTORS))))->getSize();
    
    Now in p you have stored the actor number of the client, who has joined the room, actors is the list of the players, currentyl in the room, including the joining player / excluding the leaving player and amountOfActors is the arraysize of that list.

    To iterate over that array, simply do it like for every c-array:
    for(int i=0; i<amountOfActors; i++)
    {
    	if(actors[i] == localActorNr)
    
    		doSomeLocalActorStuff();
    	else
    		doSomeOtherStuff();
    }
    

    You will receive the actorNr of your local client in the PhotonListener::OperationResult()-callback, when it is called with opCode == OPC_RT_JOIN (this is guranteed to happen before you receive the first join event).
    You can also already read out the actorNrs of clients there, who already have joined the room before your local client.
  • Thanks! I will give this a shot ASAP.
  • OK, this definitely isn't working correctly for me. I often get a player count of 2 right when the game starts and only 1 player is in the game, and it can go up to 4 when another player joins.
  • This pretty much sounds like you are joining a room, then not leaving it correctly and rejoining it, bevor your previous connection has times out. Can you reproduce it, when waiting a minute or so between joins?
  • Kaiserludi wrote:
    This pretty much sounds like you are joining a room, then not leaving it correctly and rejoining it, bevor your previous connection has times out. Can you reproduce it, when waiting a minute or so between joins?

    Actually, this happened the first time I ran it today.

    Could it be due to the fact that I'm using the Photon sample code, and therefore running on the demo server? Maybe somebody else was on there at the same time? Have you ever seen that kind of behavior?
  • "Could it be due to the fact that I'm using the Photon sample code, and therefore running on the demo server."
    Yes, of course, there is the possibility that you are not the only one on the server, when you run the demo without any changes. For some serious development you should really set up your own server, which is pretty easy.
    Fo a quick test, if this was be the reason, you can also stay on the demo server, but change the name of the room, which you are joining.
  • Hmm. I assume you mean the gameID that I pass in to my ExitGames::LitePeer::opJoin() call ... so yes, that was already unique, so it's odd that the Photon system would count 3 or 4 players at various points in a 2-player game.
  • Can you print me those actorlists to the debugout and pprovide it to me, please?
    You can use Hashtable::toString() therefor.
  • Hey -- I just figured out that the bug was on my end.

    I was unintentionally calling my Photon initialization code twice, thus joining the game twice, and also causing a memory leak due to the original pointers to the Photon stuff getting stomped.

    You'd think I'd know by now to use asserts and the like to make sure that sort of thing doesn't happen!

    Thanks for offering to check it out for me :)
  • Hi -- what's the recommended way to count the number of players on Photon 3.x? It seems to have changed significantly since 6.x ...
  • As far as I can recall, it has not changed aside from the fact, that the events and operationReponses are now wrapped in their own class-instances, but in this thread I see, that the example code uses our C++ API, while in the thread, which you have just opened in the native subforums, your sample code is using our C API. That would explain the signifcant differences, which you are experiencing.
  • Hmmm .... I'm just building this code based on the code in "network.cpp" in the Marmalade example ...
  • Which one of the Marmalade examples?
    Appeareantly the C example.

    Just use the helloWorld or better the advanced one and the used API should look much more familiar to you.

    You could also use the loadBalancing one (you have to start isntanceLoadbalancing isntance of instance1 on the server in that case) in case that you would potentially need to run multiple server machines.
  • Hmmm ... Where is the Marmalade C++ example?

    The only one I see for Marmalade in Photon-Marmalade_v3-0-3-2_SDK is

    Photon-Marmalade_v3-0-3-2_SDK\Demos\demo_marmalade_photon_c

    I don't see anything C++ specific in that folder or anywhere else in Demos. I am going based off of Network.cpp -- I'd assumed by the fact that it says ".cpp" rather than ".c" that it was a C++ file. Is there a C++ version of "Network.cpp", or if not, why isn't there?
  • the _c in demo_marmalade_photon_c means, it is a demo for the C API. As most demos are for the C++ API, we have removed the _cpp at the end of them and only have those endings left for non C++ demos.

    There are Photon-Marmalade_v3-0-3-2_SDK\Demos\demo_helloWorld, Photon-Marmalade_v3-0-3-2_SDK\Demos\demo_advanced, Photon-Marmalade_v3-0-3-2_SDK\Demos\demo_realtime and Photon-Marmalade_v3-0-3-2_SDK\Demos\demo_loadBalancing.

    However v3.0.3.3 is available since today, so it would be a good idea to upgrade (no API-changes, its just a bugfix for an encryption bug).
    The equivalents for Network.cpp in those demos would be Photon_lib.cpp for helloWorld and advanced, CPhotonLib.cpp for realtime and NetworkLogic.cpp for loadBalancing.