Misleading and/or incomplete API documentation: user object access, room variables visibility
Posted: 20 Jun 2024, 16:52
Hi,
I think I discovered some incoherent/misleading/incomplete documentation as to the client-side (JavaScript) access of user objects.
I got the impression that client-side access to user objects of other users is unwanted. There might be good reasons for that design, but I would have appreciated having found some words about this philosophy in the documentation. Similar situation as to the visibility of room variables: I had posed questions about this topic in a forum thread (viewtopic.php?f=33&t=32697&p=107226#p107194), and my questions had been fully answered (thanks again), but I think, it would have been even better having found such details more clearly documented in the first place.
In detail, as to the accessibility of user objects: From my experience about the limited visibility of room variables (they are only visible to everybody who can see the room if the "global" flag is set, room variables without that flag are only visible to users who are already in this room), I supposed that this might be similar for user objects of other users. To my surprise, I found that these SFSUser objects of other users are not even accessible from users within the same room (or I have some bug in my code). There is, e.g., the client-side (JS-)method "getUserById", both for instances of SFSRoom and for the SFSUserManager (by the way: when to use which, what is their intended purpose?). However, they both return "undefined" for other users' IDs, even within the same room. The API documentation for these methods say "Returns SFSUser An object representing the user, or undefined if no user with the passed id exists in this Room" for the SFSRoom method and "Returns SFSUser The SFSUser object representing the user, or undefined if no user with the passed id exists in the local users list" for the SFSUserManager method. The respective SFSRoom documentation is plainly wrong (given that I don't have a bug in my own code) and incomprehensible in the SFSUserManager case: What excactly is the local users list? What exactly is meant by "local" if it is not the current room?
Anyway: If the client-side access to foreign user objects is unwanted/prohibited, why does the method "getUserById" exist at all in the client-side API?
In case you asking why I tried to use the getUserById method in the first place, I describe my use case. You can judge yourself how exotic it is: It is the match making phase of a multiplayer, turn-based board game. I have read your documentation about your Game API, but I don't feel that your suggested invitation logic is the most appropriate design for my game: Rather than the creator of a game invites other players according to some matching criteria, in my case it should be the potential co-player's choice which game to join. Therefore, the creator of the game announces its game at some kind of blackboard, together with its specific initial board configuration, the number of intended players and the number of AIs among them. A potential co-player then scans the blackboard according to his/her preferences. Once the specified number of human players have joined a game, each one gets the name and whether it is a human or an AI from each co-player (AIs are joined server-side from the room extension on room creation automatically). This is the point where I wanted to get the co-players' user objects to access their respective user variables. Possibly, I can access the name property of another user without need to get access to the full user object (I have not tried this), but I definitely need to store the information whether the user is a human or an NPC (Non-Player Character) in a user variable since - a SmartFox design decision - a user's property of whether to be a normal user or an NPC can be accessed server-side only. So, once I need to encode this in a user variable anyway (as I thought), I can do the same with a user name since, once again, it was not clear from the documentation whether a user name needs to be unique or what exactly happens if another user with the same user name is already logged in and since I cannot guarantee a unique user name as the user can a) freely choose it and b) there is no way before login to see all already existing user names, but the user name has to be given together with the login request.
All these complications are manageable: I have created a room variable of type SFSArray that records the names and their human/AI-property of all players. However, I wished I had already read about your access philosophy of user and room data in the documentation. Moreover, I expected my match-making scenario to be very ordinary and therefore was really surprised to need to make-up these rather cumbersome workarounds just to get data about co-players (and room data for not-yet-joined users, as they still want to decide whether to join or not). If you share my suspicion that the match making scenario I have described here is not really uncommon, I suggest to rework the access-related aspects of your documentation. The exact circumstances under which the getUserByID methods return undefined should be clarified in any case, I think.
Nevertheless, thank you for your product and I hope that my feedback helps to improve it.
I think I discovered some incoherent/misleading/incomplete documentation as to the client-side (JavaScript) access of user objects.
I got the impression that client-side access to user objects of other users is unwanted. There might be good reasons for that design, but I would have appreciated having found some words about this philosophy in the documentation. Similar situation as to the visibility of room variables: I had posed questions about this topic in a forum thread (viewtopic.php?f=33&t=32697&p=107226#p107194), and my questions had been fully answered (thanks again), but I think, it would have been even better having found such details more clearly documented in the first place.
In detail, as to the accessibility of user objects: From my experience about the limited visibility of room variables (they are only visible to everybody who can see the room if the "global" flag is set, room variables without that flag are only visible to users who are already in this room), I supposed that this might be similar for user objects of other users. To my surprise, I found that these SFSUser objects of other users are not even accessible from users within the same room (or I have some bug in my code). There is, e.g., the client-side (JS-)method "getUserById", both for instances of SFSRoom and for the SFSUserManager (by the way: when to use which, what is their intended purpose?). However, they both return "undefined" for other users' IDs, even within the same room. The API documentation for these methods say "Returns SFSUser An object representing the user, or undefined if no user with the passed id exists in this Room" for the SFSRoom method and "Returns SFSUser The SFSUser object representing the user, or undefined if no user with the passed id exists in the local users list" for the SFSUserManager method. The respective SFSRoom documentation is plainly wrong (given that I don't have a bug in my own code) and incomprehensible in the SFSUserManager case: What excactly is the local users list? What exactly is meant by "local" if it is not the current room?
Anyway: If the client-side access to foreign user objects is unwanted/prohibited, why does the method "getUserById" exist at all in the client-side API?
In case you asking why I tried to use the getUserById method in the first place, I describe my use case. You can judge yourself how exotic it is: It is the match making phase of a multiplayer, turn-based board game. I have read your documentation about your Game API, but I don't feel that your suggested invitation logic is the most appropriate design for my game: Rather than the creator of a game invites other players according to some matching criteria, in my case it should be the potential co-player's choice which game to join. Therefore, the creator of the game announces its game at some kind of blackboard, together with its specific initial board configuration, the number of intended players and the number of AIs among them. A potential co-player then scans the blackboard according to his/her preferences. Once the specified number of human players have joined a game, each one gets the name and whether it is a human or an AI from each co-player (AIs are joined server-side from the room extension on room creation automatically). This is the point where I wanted to get the co-players' user objects to access their respective user variables. Possibly, I can access the name property of another user without need to get access to the full user object (I have not tried this), but I definitely need to store the information whether the user is a human or an NPC (Non-Player Character) in a user variable since - a SmartFox design decision - a user's property of whether to be a normal user or an NPC can be accessed server-side only. So, once I need to encode this in a user variable anyway (as I thought), I can do the same with a user name since, once again, it was not clear from the documentation whether a user name needs to be unique or what exactly happens if another user with the same user name is already logged in and since I cannot guarantee a unique user name as the user can a) freely choose it and b) there is no way before login to see all already existing user names, but the user name has to be given together with the login request.
All these complications are manageable: I have created a room variable of type SFSArray that records the names and their human/AI-property of all players. However, I wished I had already read about your access philosophy of user and room data in the documentation. Moreover, I expected my match-making scenario to be very ordinary and therefore was really surprised to need to make-up these rather cumbersome workarounds just to get data about co-players (and room data for not-yet-joined users, as they still want to decide whether to join or not). If you share my suspicion that the match making scenario I have described here is not really uncommon, I suggest to rework the access-related aspects of your documentation. The exact circumstances under which the getUserByID methods return undefined should be clarified in any case, I think.
Nevertheless, thank you for your product and I hope that my feedback helps to improve it.