20
\$\begingroup\$

I have a multiplayer game and I'm doing client-side prediction, but some players can drink a potion and become invisible...

The problem is that when they become invisible I don't share anything that the client could use to know he's there, so when a player tries to step into a tile occupied by a invisible player, he predicts that he succeeds, and then gets a ugly position correction sent by the server.

One solution would be to share something so the client can tell, but then hackers could use it to find out where invisible players are, cheating.

Btw I already solved regular movement prediction, it works perfectly.

\$\endgroup\$
5
  • 4
    \$\begingroup\$ Just send the info about all players. Cheaters gonna cheat. Don't cripple honest players' experience and think about creating flagging system for cheaters instead. \$\endgroup\$ Feb 10, 2014 at 5:53
  • 2
    \$\begingroup\$ @user1306322 By making it easier for cheaters you'll cripple honest players as well. A flagging system is a good idea, but if invisibility is a big part of the game, something preventive might be nessesary. \$\endgroup\$
    – ThatOneGuy
    Feb 10, 2014 at 11:02
  • \$\begingroup\$ @user1895420 it's usually good enough to not send such things in plain text, so that no average player can easily attain that data. If only a tech-savvy person can do it, then it's as good preventive measure as any. \$\endgroup\$ Feb 10, 2014 at 17:30
  • 1
    \$\begingroup\$ Or, perhaps, it's a better idea to change the invisibility mechanic a little bit so it does not work in very close proximity, so even those who are able to cheat their way through game's data can't really get any advantage. \$\endgroup\$ Feb 10, 2014 at 17:48
  • \$\begingroup\$ How about just sending the invisible player's position (with a flag to keep him/her invisible) only when a visible player is near? That should give you a couple of frames to avoid the over-movement issue, while it shouldn't give cheaters enough time to react. For two invisible players, I would just ignore the collision. If you have a central server that has all player's positions, you could also have it coordinate when to broadcast the position and when not. \$\endgroup\$
    – jdm
    Feb 10, 2014 at 21:30

3 Answers 3

30
\$\begingroup\$

This could be considered an animation problem. If a position correction comes back from the server due to an attempt to move into an invisible object, send back not only the correction but a flag indicating why the correction was needed. Instead of a player popping backwards, he may do a "woah" kind of reeling backwards animation, making it more believably look like he just ran into something.

In games using this approach, it's not uncommon to remove invisibility (at least momentarily) from anything that was run into. Among other things this gives incentive for invisible players to avoid crowds or getting too close to other characters, reducing the frequency that collision with an invisible player happens in the first place. Thus even if your animation for this kind of collision is weak (or non-existent), it's somewhat hidden by the invisible character popping into visibility and clearly telegraphing to everyone what just happened.

The animation need could be removed by not letting invisibility work at close range. This gives even more incentive to invisible players to avoid getting close to other characters. This is a common approach for stealth-based games and AI (replace "invisible" with "not visible to target") and can be seen in PvP games like World of Tanks. There's no need to worry about collision response with invisible characters if you nothing invisible is ever close enough to you to collide with (within latency limits).

Dracor's solution to just ignore collisions with invisible objects is also a good one. This does again require some animations (for the invisible players' client) so objects aren't just clipping through the player's avatar on his screen. If nothing else you can cause visible objects to always push invisible ones so that the invisible player is automatically moved out of the way on the server if someone collides with him.

Invisible-invisible collisions are a bit trickier. It may be advantageous to just disable collisions on them since nobody can see if two invisible objects are clipping together (assuming by "invisible" we mean that both objects aren't visible to the same client). If one of the objects becomes visible it automatically reverts to the visible-invisible collision response (push away the invisible object).

This all gets trickier if invisibility has complicated sets of who can see whom. The first or second solution above is likely best here if you need it. Not every problem like this needs a technical solution; many just need design solutions (e.g., don't allow this feature to your designers).

\$\endgroup\$
1
  • 5
    \$\begingroup\$ The game Team Fortress 2 uses that first approach...If an invisible spy touches another player the other player is able to see the spy (or if from behind, at least sense some obstacle). \$\endgroup\$
    – Xantix
    Feb 10, 2014 at 3:59
4
\$\begingroup\$

I really only see two options here if you don't want to tell the client where the invisible player is: 1) You ignore unit collision for invisible players - a simple solution, and players wouldn't be able to find the invisible players by collision tests either. 2) After deciding on the predicted path, you send the server the predicted path and correct the path itself on the server side, then send the new path back.

\$\endgroup\$
13
  • \$\begingroup\$ the problem with ignoring collision for invisible players is if a invisible player stops being invisible right when it is colliding with someone else. Also, it doesn't feel right. In my game I don't really have paths or pathfinding, players can only move in the 4 directions, one step at a time \$\endgroup\$ Feb 9, 2014 at 23:57
  • \$\begingroup\$ Then what remains is to send the predicted movement (either a single vector or an array of vectors) and do a server-side check. Or just animate the correction, as said bellow. \$\endgroup\$
    – Kanadaj
    Feb 10, 2014 at 0:54
  • 1
    \$\begingroup\$ If you have a grid based map and are checking every square one by one anyways, you may as well try to encode the location of the invisible characters on the server side with a one-way encoding, such as SHA-1 or SHA-2, then check you own path by encoding the checked coordinates with the same algorithm. Can't say it's performance-effective, but if you really want to do it on client side, this solution may work as well with a limited number of positions, and hacking might be really troublesome due to the sheer amount of grid points to encode and match with the data in memory. \$\endgroup\$
    – Kanadaj
    Feb 10, 2014 at 1:04
  • \$\begingroup\$ I can see that working. My smallest map has 1500 different positions. Should I use HMAC with the key changing every few seconds to prevent the attacker from precomputing all positions? \$\endgroup\$ Feb 10, 2014 at 1:55
  • 5
    \$\begingroup\$ No, any scheme you can come up with would not be "secure" against hackers. If the client can determine whether the player will collide against a given position, then someone can hack your game. HMACing with a rotating key will not prevent the client from doing 1500 HMACs a second. Do not attempt to do cryptography yourself. If you want to achieve the original goal, only send the invisible player position to the client if they are within 1 or 2 tiles of the player. Then you can only hack to know if someone is right next to you (which isn't useful because you could just move to check this). \$\endgroup\$
    – user41442
    Feb 10, 2014 at 3:22
2
\$\begingroup\$

Unless I'm misunderstanding something, the solution is simple. Don't send the client information on all invisible players, only those who are within range that they could be subject to collision within the limits of motion during the interval that's being predicted. In other words, if the client is only having to predict 200 ms into the future, only send information on invisible players within max_player_velocity units/sec * 1/5 sec units away.

\$\endgroup\$
3
  • \$\begingroup\$ I guess that could work, but my game is tile-based (forgot to say). \$\endgroup\$ Feb 12, 2014 at 3:29
  • \$\begingroup\$ So only reveal invisible players in adjacent tiles, or 2 steps away, or whatever. \$\endgroup\$ Feb 12, 2014 at 4:10
  • \$\begingroup\$ then it's not sure they would collide, and invisible players would have to stay away from anyone hacking to not get discovered \$\endgroup\$ Feb 12, 2014 at 18:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .