Still trying to understand =D

Options
Sladix
edited June 2011 in DotNet
Hi,

So, after many cries and sweat showers, I've decided to resume my Photon learning.
What seems confused to me is still a bit due to the architecture (I'm just saying that it's not quit easy to learn for a n**b like me).

So, I'm studying the realtime demo example and here is my question. To raise custom events, I see the function that use OpRaiseEvent and I understand the function EventAction which dispatch the events, regarding the event's byte code.

But I don't understand what's going on on the server side. Has the event to be defined server-side ? Or does it need to be defined Only if the server need to raise it ?


edit: when an Event constant is defined e.g:
internal const byte EV_MOVE = 101;
How can we be sure that the code "101" is not already used by another lite/litelobby photon event ?


edit2: I've made some experiments in the real demo in order to set up a fire function.
So I've my script Gun.js attached to a player model, I've created a updateFire function in usePhoton.cs and I wonder how to access the Gun script. I've tried
playerTransform = PlayerTransformDict[player.playerID];
					Gun script = playerTransform.transform.GetComponent(Gun);
but it doesn't work ...



Regards,
Sladix
«1

Comments

  • Tobias
    Options
    Effectively, the client does not send an event but calls the operation RaiseEvent. So on the server, the (custom) content of your event will go through the operation RaiseEvent and there it's put into a custom event object.
    If you want to peek into events server-side, this is the place.
    Alternatively, you could create new operations and let them send events as needed. In this case, you get parameters mapped into the operation object as expected.
  • Kaiserludi
    Options
    The Photon core functionality does not know any specific operations, including opRaiseEvent, but just principle of operations via opCustom.
    However the serverside so-called applications, built on top of it, give this operations meaning.
    You can build your won applciations with custom game-logic, but we already provide some often needed functionality in some applications, shipped with the sdks, like Lite, LiteLobby or MMO.
    opRaiseEvent is implemented by the Lite application on the server side and on the client side it is implemented by the class LitePeer.
    raiseEvent will send the Hashtable, you pass to it, to the server and the server then will raise an event with that Hashtabl as content to oher clients. As Lite is implementing a room-concept on top of Photon, these events can only reach clients in the same room (although you do not have to use this room-concept for your applciation, MMo for example implements a concept based on the distances in the ingame-world between the clients, it really depends on the type of game, wich concept will suit your needs). You can provide opRaiseEvent a list of receivers in the same room. If you do not pass such a list, the event will be raised for all clients in the room ecept the sending one by default.
    If the behavior of opRaiseEvent does not suit all your needs, you can either modify Lite's behavior serverside (not recommended, as you would have to merge potential futere changes from our side) or implement your own serversie-application, which can inherits from Lite, if you want to use some of its funtionality. This way you could override raiseEvent's functionality. You also could implemnt your own operations, which itnernally would call Photons opCustom. Use of custom operations will most likely be needed, if you want to implement any game-speicif server side behavior on certain operations, while pure client-side game-specific behavior can in most cases by implemented with opRaiseEvent.

    eventCodes: Lite only uses codes between 90 and 100 internally at the moment, so you could use every code below 90 and above 100 for your game-spcifi events at the moment. Same for opertation-codes. However, for both, eventcodess and operation-codes, 0-100 are reserved for applications, provided by us and although most of them are not used curently, they could be used in future, so it is best, to only use codes above 100. It is worth to mention, that the codes are sent as bytes and that some client platform languages like Java (which is used for the Android SDK) do not know unsigned numbers, so you have to pay attention, when using codes above 127.
  • Sladix
    Options
    Thanks for your clear answer.

    But the point I might not get is the way I'm supposed to build my events listenner/raiser.

    Let me explain a bit :

    In the real time demo, positions are updated in the Game. I see that the movements are first recieved by the game.cs update function and "displayed" in the usePhoton.cs update function by calling Gaminstance.update().

    Does that mean that I should create :
    -a sendShot() function in Game.cs
    -an updateFire() function in Usephoton.cs
    -a sendEvShot() function in Player.cs ?

    Plus the Gun script in .js with the Fire() function that would be called in the updateFire() function ?


    Is my reasoning right ?


    Regards.
  • Kaiserludi
    Options
    Thats purely code structuring of the demo.
    You call raiseEvent, if you want to send an event and you call service regularly, to receive events in eventAction.
    Where in your code you want to call raiseEvent and which functions you want to call from eventAction, to pass them the data to handle certain events, doesn't really matter. You could handle all the game logic for a received event in the eventAction or you could do all raiseEventCalls from the same location in code, being a giant switch of the different eventCodes, you are using. That would work too. The only reason, not to do it, is, that such code would be more difficult to maintain and hold up to date than a more object orientated approach.
    But this really isn't a Photon-specific topic, but a general question of code style, -design and -architecture, same category as questions like, when to split up some functionality into separate functions or about the disadvantage of one huge function for the whole program.
  • Sladix
    Options
    Thanks a lot !

    I think I'm on my way to understand !!! But it's quit hard to assimilate when you've done only php and a few js =p


    So thank you again !

    Regards !
  • Kaiserludi
    Options
    Then probably it is a good idea for you, to read a good book or online tutorial about object orientation and C# to give yourself a better understanding about how to do things in object oriented languages in general and C# in particular.
  • sebako
    Options
    yeah there are a few differences between php & c# ;)
    I luckily had ruby for development before I came to Unity & C# and then to photon, so no big deal for me since Ruby is the most object orientated language I'd know of :)
    Starting with a book is a good Idea, I know some german books, but no idea about english ones.
  • Kaiserludi
    Options
    sebako wrote:
    Starting with a book is a good Idea, I know some german books, but no idea about english ones.
    Well, that is something, I would not have expected, from someone, stating Ireland as his/her location.
  • sebako
    Options
    Kaiserludi wrote:
    sebako wrote:
    Starting with a book is a good Idea, I know some german books, but no idea about english ones.
    Well, that is something, I would not have expected, from someone, stating Ireland as his/her location.

    Hehe, let me enlight you ... I am german but I live here at the moment. There are not so many good gaming company's in germany sadly :(
  • Kaiserludi
    Options
    sebako wrote:
    Kaiserludi wrote:
    sebako wrote:
    Starting with a book is a good Idea, I know some german books, but no idea about english ones.
    Well, that is something, I would not have expected, from someone, stating Ireland as his/her location.

    Hehe, let me enlight you ... I am german but I live here at the moment. There are not so many good gaming company's in germany sadly :(
    Well games industry is not so small here, as most people think, although its quite small still in somparison to Uk or France, not to talk about US or Japan, but we still have a few companies with over 500 employees here, like Crytek or Bigpoint. Not to forget the huge amount of small developers (about 150 games industry companies only in Hamburg for example).
  • Kaiserludi wrote:
    However, for both, eventcodess and operation-codes, 0-100 are reserved for applications, provided by us and although most of them are not used curently, they could be used in future, so it is best, to only use codes above 100.

    I've been working with Photon for a few months now and didn't ever see a note about this reservation. This is good information to have. Is this noted in comments in code or the documentation somewhere that I may have just overlooked? I'll have to go and update my code usage now so I don't run into an issue later.

    This also explains why the LiteLobby demos "chat" event starts at event code 101. I was always wondering if that number used was just arbitrary or if there was a reason for it.
  • Kaiserludi
    Options
    Good question. The info does not seem to be very widespread.

    Originally this reservation has been set for Neutron and as Photons life has begun as "Neutron Realtime" Extension in the past, Lite-Codes started at 90 to be under the 100 limit, used by the game's custom stuff and o above the ones used by Neutron. Now, with Photon being completely separated from Neutron, 0-89 currently are not in use by Lite, but other applications from us make use of other parts of the 0-100 range like for example the masterserver application (which is not available in the normal SDKs in the moment, as it only is of use for tasks like distributing players and games to different gameservers, if your game needs multiple gameservers), which is using 1-9 currently.

    I guess, a deocumentaion-entry of this reservation has been lost, somewhere on the way of Photon becoming a product of its own.
    All demos only using codes 101 and up (not sure about MMO application and it's demo, never had to do much with them personally) seems to be the only public "info" at the moment. We will change that.
  • Boris
    Options
    code 0 = error code
    code 1 = dbg message
    code 60 = event/operation code

    the rest is app specific and can be changed/used as you like
  • Boris wrote:
    code 0 = error code
    code 1 = dbg message
    code 60 = event/operation code

    the rest is app specific and can be changed/used as you like

    Forgoing the addition of new reserved codes, these are the current codes that are reserved by Photon?

    @kaiserlundi, thanks for the bit of history on Photon as well. :)
  • Kaiserludi
    Options
    Boris wrote:
    code 0 = error code
    code 1 = dbg message
    code 60 = event/operation code

    the rest is app specific and can be changed/used as you like

    Forgoing the addition of new reserved codes, these are the current codes that are reserved by Photon?

    @kaiserlundi, thanks for the bit of history on Photon as well. :)
    No, seems, there is a misunderstanding.
    The codes, mentioned by Boris are parametercodes, not operationcodes, nor eventcodes.
    Photon itself does not know anything about certain operations or events and does not reserve any codes for them.
    Photon itself only reserves the 3 codes, mentioned by Boris, as parameter codes.
    Lite and other applications also reserver some parametercodes (Lite currently uses 4, 9-17, 30 and 42), but additionally the also reserve operationscodes (Lite: 90-95) and eventcodes (Lite: 1-2, 90-92).
    For parametercodes you are save to use 61 and up.

    Oh and about this: "the rest is app specific and can be changed/used as you like".
    I would recommend to use codes, not used by any application but your custom ones and if they are not enough for you (very, very unlikely, as you have over 150 in the range over 100), at least use the codes, not used by the applications, you inherit from.
    When you begin to change the codes of the applications, your custom app is inheriting from, like Lite, than you will practically have to overwrite all operations, you are using, if you do not accept their original codes. So, if you are using Lite, especially avoid to use codes 90-100 for operations or events.
  • Ok, so to be safe using any existing application like Lite, LiteLobby, MMO, etc, the following codes to use would be:
    Parameter Codes: 61 and up
    Event and Op Codes: 101 and up

    Correct?
  • Kaiserludi
    Options
    Yes.

    btw.: Parametercodes can be reused for other purposes in oterh operations, if you want to, so, you are not restricted to 195 different parametercodes for the whole app, but you have 195 different ones avaiable for every operation.
    This should be enough for every realistic scenario and saves you traffic in comparison to the codes being shorts instead of bytes (this could sum up to considerable amounts of traffic for operations, sent multiple times every second, with many parameters and received by many other players).
  • Sladix
    Options
    I'm glad my question wasn't totally useless !

    After a few days I decided to get back to my experiment.

    And I created the function UpdateFire in UsePhoton.cs.

    Here it is :
    void UpdateFire()
    	{
    		
    		if (GameInstance == null || GameInstance.Players == null) 
    		{
    			return;
    		}
    		
    		foreach (Player player in GameInstance.Players.Values)
    		{
    			Transform playerTransform;
    				if(player.shooting)
    				{
    					playerTransform = PlayerTransformDict[player.playerID];
    					playerTransform.GetComponent(Gun).Fire();
    					
    				}
    		}
    		
    	}
    

    But unity says
    Assets/Photon/usePhoton.cs(158,70): error CS0103: The name `Gun' does not exist in the current context
    

    Am I missing something ? Am I not calling my script the right way ?

    I have a script Gun.js attached to my playerModel prefab...

    Thank you =D
  • You should probably be using GetComponent<Gun>() unless GetComponent(Gun) was a typo.
  • Sladix
    Options
    Yes, I've already tried
    foreach (Player player in GameInstance.Players.Values)
    		{
    			Transform playerTransform;
    				if(player.shooting)
    				{
    					playerTransform = PlayerTransformDict&#91;player.playerID&#93;;
    					Flingue other = playerTransform.GetComponent&lt;Flingue&gt;();
    					other.Fire();
    				}
    		}
    

    But it didn't worked. It says
    Assets/Photon/usePhoton.cs(158,41): error CS0246: The type or namespace name `Flingue' could not be found. Are you missing a using directive or an assembly reference?
    
    ...

    Sorry for my first attempt, I didn't read the unity documentation. But this time I did ! :p
  • sebako
    Options
    what is Flingue? Is it the name of your gun script?
  • Sladix
    Options
    Yes, I've tried to change it's name, in case of whatever ....
  • It may be because you are mixing javascript and C#. If you have unity pro, try putting both scripts into the Plugins folder. See this thread here in the Unity forum:
    Mixing-C-and-Javascript-how

    Hope that helps.
  • The simplest solution is to convert your scripts into a single language as suggested in the thread I linked. Like their recommendation, I also suggest converting the scripts from Javascript to C#.
  • Sladix
    Options
    Yes, thank you very much.

    I'm raping my brain out trying to learn C# / Photon logic / Unity logic by myself in english (I'm french lol) but I'll surviiiiive =D
  • Sladix
    Options
    So now that pieces of my codes seems to compile (not work lol) I'm wondering what to do in my sendEvShot function.

    By looking at SendEvMove I see that a hashtable is sent, containing X and Y position.
    So what should I store in the EvShot hashtable ? the shot quaternion euler angle ? By defining something like
    internal const byte STATUS_SHOT_QUATERNION = 49;
    
    in the constant region ?
    how should I store this ?
    Or maybe at first I thought that I could just raise a shot event without hashtable (and the players would always shot in the same direction ...)


    The thing I don't really understand is the update function in Game.cs
    Where am I supposed to raise the shot event and locally makes the localplayer fire ?
    When the fire button is pressed, I set a bool (shooting) to true and I check this bool in the updateFire function I show you previously.


    Am I thinking right ?
  • Kaiserludi
    Kaiserludi admin
    edited June 2011
    Options
    It depends a bit on your game (what info do you have, what does the opponent need to know), but typical information, you would send for a shot would be:
    - the coordinates, where it is created - depending on size of the map and needed accuracy this would be a short, int, int64, float or double for each, x, y and z coordinate, meaning 3 values overall for this info
    - the speed of the shot, on every axis, another 3 values
    - the acceleration of the shot, if it has some non-zero value for it, again for every axis
    - some type info, so the receiving client knows, which type of ammo has been fired, so it can display the correct graphic model and effects, the correct sound, calculate the correct damage, and such things, a single byte will be enough here normally

    your would put all this info in a hashtable as values and define some key-constants for them. in eventAction you would read out the values, you find in the hashtable for theses keys.
  • Sorry I won't be much help with the shooter game as I haven't looked at the code for that yet. Floor is open for anyone else to jump in though. Also, it's awesome to see someone learn so much new stuff while working across languages like French and English. I need to pick up my Japanese learning again. >_<
  • Sladix
    Options
    Thanks, it works now. I'm sooo happy xD.
    After, like 2 month from scratch I can now understand/code little things in C# with unity. Hallelujah !

    But I've still some questions (I'll always haaaavve) :

    How could I write something like

    "When W is pressed, send a message that tells you are moving forward, and when W is up, send a message that tells you stopped"

    Same thing for the directions but with rotation.

    What I don't get here is how to let the rotation/movement go on until the keyp up / event is recieved.
    I suppose it's in the update position (now in the new DemoGuiAndInput.cs) but I don't know how to do.


    Hope my message is still readable =D
  • Tobias
    Options
    To synchronize keys, the first thing would be to learn in Unity how to detect those two state changes. I don't know the code but the reference will help.
    Then you have to take into account that you want to apply the same effect due to key-presses on all clients. Means: You have to have a fixed game/frame rate on all clients. Let's say: While w is pressed, move 10 times per second forward. Otherwise a faster machine will move more than slower ones.

    To update others of your key-presses, you could either send the key events when a key changes, or you check keys at some point in your game loop and send changed key-states. Send an event "key state" e.g. with key 'w' as true (down) or false (up). cache the last received key-value on all clients and apply it (e.g.) 10x per frame.

    This won't give you awesome results yet. The time for an event to travel between one client and others might differ and it arrives delayed. Next step would be to timestamp the event and catch up the effect on clients that get this key-change only by event.

    That's at least the idea. I'd say.