From The Mana World

This article is currently only a proposal

The features or design guidelines described in this article are only a proposal made by one or some persons. It has not been evaluated or accepted by the core development team yet. Feel free to add your personal opinion about them or make counter proposals.

Problem description

Problem: We want to implement pixel or near pixel-based movement in TMW. However, hit detection on such a system would be expensive at best, and could potentially cause a high amount of lag for the server.

Solution: Our world is tile based, even if players are pixel based, so there is no reason to make expensive rectangle checks for collision with world objects. To accomplish this, we should keep the tile grid used by our mapping system beneath the pixel coordinates where players walk. The player's current tile position is

XTile = XPixelPos / 32; YTile = YPixelPos / 32;

So, each time the player moves, this value would be updated, and a check would be done as follows (Assuming that the map is stored as a two dimensional array):

if (currentmap(XTile, YTile) == WALK_FORBIDDEN)
     return MOVE_FAIL;

This cuts the player's world collision detection nearly to what it was with a true tile system, adding only 2 assignment statements to the original check.

Hit detection

And about hit targeting. When a player attacks, how will we determine if he hits a monster? Whether he is sending a simple attack message, or the ID of the monster he is targeting, the server needs to verify that it is indeed possible for him to attack that monster.

So, we add a second array of coordinates, this time based on a 16 pixel grid (a quarter the player size). The player's current position on this grid, plus any other positions necessary, based on the direction he is facing, are checked if they match the monster's current position on this grid.

This also allows the type of weapon the player is weilding to have a different hit area, or for him to use different strokes, such as a thrust, wide slash, spinning slash, etc. This is important when fighting multiple monsters, since you may want to make an attack which hits several at once.

This type of hit detection takes a relatively few number of checks each detection attempt (depending on the player's attack range), and avoids building complex rectangle schemes and making the checks associated with them.

see also Realtime action combat protocol about how hit detection could be handled with keeping latency in mind.

Alternative to that thing above

Wouldn't it be easier to make a distance check between the two to see if one is in range of the other?

distance = sqrt((playerX - monsterX)^2 + (playerY - monsterY)^2);

if the distance is too high, the player is out of range. This requires no memory for grid coordinate storage, though the equation is slightly more complex, I think we can afford it once per attack. Of course, we would have to filter out checks against monsters that aren't close to the player, to save calculation time.


This is a subpage of server development.