# Thread: Regions and their usefulness

1. The purpose on this thread, is to shed light on map regions and some really usefull information that comes with those. Alot of people don't know some things I'm gonna lay out here, and I know that simply because of the fact I have never seen anyone use them. Also this information could be used by people that want to get 570+ login.

If you don't feel like reading this from top to bottom you might as well fuck off now, because I don't like replies like the first two below my post .

We do have a few variables in our servers, that everyone has, that are related to the location of a player or npc. For example everyone has these in their server:

Code:
``````private int regionX;
private int regionY;
private int absX;
private int absY;
private int localX;
private int localY;``````
We are gonna ditch this list and make some new variables named after their real meanings. RegionX and regionY, represent a coordinate for a region you would suppose. In fact they represent coordinates for 8 x 8 pieces of map, and not coordinates for complete regions. Regions are 64 x 64 map pieces. Out of this we can conclude that the name regionX and regionY are inapropriate as a name for the variable that represents 8 x 8 pieces of map. To give an example:
RegionX = 400 and regionY = 400, represent the coords for a piece of map from 8 x 8, with its absolute base coordinates being (3200, 3200). The coordinates for the regions where this 8 x 8 piece of map is found are (50, 50).
If a region exists out of 64 x 64 tiles, then there are 64 map pieces with the size of 8 x 8 tiles in one region. Conclusion: the variables called regionX and regionY should have another name as they do not represent region coordinates but 8 x 8 pieces of map. We will call these variables region sections. Those region sections can be of great use, but that will come later. First we will gather our other variables with their correct names.

So we have:

Code:
``````private int regionSectionX = getAbsX >> 3; // Represents an x coordinate for 8 x 8 tiles map pieces
private int regionSectionY = getAbsX >> 3; // Represents an y coordinate for 8 x 8 tiles map pieces``````
We got rid of the names regionX and regionY, but of course we have coordinates for our regions. Those coordinates are not used in any server yet, so let's get an idea of how to retrieve them:

Code:
``````private int regionX = getRegionSectionX() / 8; // Represents an x coordinate  for a region, bare in mind those are not absolute coords
private int regionY = getRegionSectionY() / 8; // // Represents an x coordinate for a region, bare in mind those are not absolute coords``````
So right now we have coordinates for our regions, being blocks of 64 x 64 tiles, and coordinates for the sections within the regions, being blocks of 8 x 8 tiles. It could be usefull to know how to calculate the relative positions within these blocks, and for that we need to be able to calculate the absolute coordinates of the bases of those blocks.

Code:
``````private int absX; // Represents an x coordinate for the absolute position
private int absY; // Represents an y coordinate for the absolute position

private int regionSectionX = getRegionSectionX() << 3; // Represents an absolute x coordinate for the position of the region section block
private int regionSectionY = getRegionSectionY() << 3; // Represents an absolute y coordinate for the position of the region section block

private int regionSectionLocalX = getAbsX() - getRegionSectionsBaseX(); // Represents the relative position within the particle
private int regionSectionLocalY = getAbsY() - getRegionSectionsBaseY(); // Represents the relative position within the particle

private int regionBaseX = (getRegionX() << 3) * 8; // Represents the absolute position of the base of the region
private int regionBaseY = (getRegionY() << 3) * 8; // Represents the absolute position of the base of the region

private int regionLocalX = getAbsX() - 8 * (getRegionX() - 6); // Represents the relative position within the region
private int regionLocalY = getAbsY() - 8 * (getRegionY() - 6); // Represents the relative position within the region``````
Now we have all those new and renamed variables, we might as well put them to use in our servers. Let's put down my Location class:

Code:
``````package net.maximemeire.rs2pro.world.entities;

/**
* Represent a location in the world.
*
* @author Maxime Meire
*
*/
public class Location implements Cloneable {

private int absX;
private int absY;
private int z;

private boolean isNewInRegion = true;

public Location(int x, int y, int z) {
setAbsX(x);
setAbsY(y);
setZ(z);
}

public void setAbsX(int absX) {
this.absX = absX;
}

public int getAbsX() {
return absX;
}

public void setAbsY(int absY) {
this.absY = absY;
}

public int getAbsY() {
return absY;
}

public void setZ(int z) {
this.z = z;
}

public int getZ() {
return z;
}

public int getRegionLocalX() {
return getAbsX() - 8 * (getPaletteX() - 6);
}

public int getRegionLocalY() {
return getAbsY() - 8 * (getPaletteY() - 6);
}

public int getPaletteX() {
return getAbsX() >> 3;
}

public int getPaletteY() {
return getAbsY() >> 3;
}

public int getPaletteBaseX() {
return getPaletteX() << 3;
}

public int getPaletteBaseY() {
return getPaletteY() << 3;
}

public int getPaletteLocalX() {
return getAbsX() - getPaletteBaseX();
}

public int getPaletteLocalY() {
return getAbsY() - getPaletteBaseY();
}

public int getRegionX() {
return getPaletteX() / 8;
}

public int getRegionY() {
return getPaletteY() / 8;
}

public int getRegionBaseX() {
return (getRegionX() << 3) * 8;
}

public int getRegionBaseY() {
return (getRegionY() << 3) * 8;
}

public int getPaletteId(int x, int y) {
return ((((getRegionY() + y) * 8) - 6) / 8)
+ ((((getRegionX() + x) - 6) / 8) << 8);
}

public void setNewInRegion(boolean isNewInRegion) {
this.isNewInRegion = isNewInRegion;
}

public boolean isNewInRegion() {
return isNewInRegion;
}

@Override
public boolean equals(Object other) {
if (!(other instanceof Location))
return false;
Location loc = (Location) other;
return loc.absX == absX && loc.absY == absY && loc.z == z;
}

@Override
public String toString() {
return "[" + absX + "," + absY + "," + z + "]";
}

}``````
The reason why I renamed the previously called variable regionX and regionY, is because I wanted to have the real regionX and regionY. Why? Because this gives me the oppertunity to select the regions I want to select. You see that method getRegionId(int x, int y);? That method allows me to grab the id of a region that is x regions west or east and y regions north or south away from the current region. This allows you to select 4 regions, that might contain data you need to load for player updating, but only those 4 that you really need. Example:

Code:
``````	private static Region[] getRegionsToLoad(Player p, Region r) {
Region[] regions = new Region[4];
regions[0] = r;
if (p.getLocation().getAbsX() < 32) {
regions[1] = getRegion(p.getLocation().getRegionId(-1, 0)); // Region to the west from current region
if (p.getLocation().getAbsY() < 32) {
regions[2] = getRegion(p.getLocation().getRegionId(0, -1)); // Region to the south from current region
regions[3] = getRegion(p.getLocation().getRegionId(-1, -1)); // Region to the south west from current region
} else {
regions[2] = getRegion(p.getLocation().getRegionId(0, 1)); // Region to the north from current region
regions[3] = getRegion(p.getLocation().getRegionId(-1, 1)); // Region to the north west from current region
}
} else {
regions[1] = getRegion(p.getLocation().getRegionId(1, 0)); // Region to the east from the current region
if (p.getLocation().getAbsY() < 32) {
regions[2] = getRegion(p.getLocation().getRegionId(0, -1)); // Region to the south from current region
regions[3] = getRegion(p.getLocation().getRegionId(1, -1)); // Region to the south east from current region
} else {
regions[2] = getRegion(p.getLocation().getRegionId(0, 1)); // Region to the north from current region
regions[3] = getRegion(p.getLocation().getRegionId(1, 1)); // Region to the north east from current region
}
}
return regions;
}``````
We also had our region section blocks. Those variables would gives us the oppertunity to select 64 of those block to form a block the size of one region. If a player is in the middle of that, it is more than big enough to load every region property (players, npc's, ground items and objects) that would be within sight on the client, but reduces loading data size by aproxemately 75%.
Example:

Code:
``````# PART OF METHOD #
int startX = getStartingX(p);
int startY = getStartingY(p);
for (Region r : regionsToLoad) {
for (Player pl : r.getPlayers()) {
if ((p.getLocation().getAbsX() >= startX || (startX + 64) >= p.getLocation().getAbsX())
&& (p.getLocation().getAbsY() >= startY || (startY + 64) >= p.getLocation().getAbsY())) {
}
}
}
# PART OF METHOD #

private static int getStartingX(Player p) {
int regionSectionX = p.getLocation().getRegionSectionX();
int nRegionsBack = p.getLocation().getRegionSectionsLocalX() < 4) ? 4 : 3;
return p.getLocation().getRegionSectionsBaseX(regionSectionX - nRegionsBack);
}

private static int getStartingY(Player p) {
int regionSectionY = p.getLocation().getRegionSectionY();
int nRegionsBack = p.getLocation().getRegionSectionsLocalY() < 4) ? 4 : 3;
return p.getLocation().getRegionSectionsBaseY(regionSectionY - nRegionsBack);
}``````
That would load 64 particles of players, npcs and whatever you include in your regions, the size of one ordinary region.

I want to conclude this thread with saying that the example code I used is based on two maps, one with active and one with idle region objects. Every region object holds tea data for the region, id for the region, players, npcs, grounditems and objects information.

I hope I wrote it down fairly understandable, any questions and I'll answer them.

2. The current names are fine imo, while your ones are rather confusing. What's the advantage of having these extra variables?

3. Yea what is the advantage? Does it help with something?

4. You would know if you read everything, the last part explains the usefulness. I'm sorry to say, but you are both retarded for not reading the complete thread, though you are asking questions that are answered in the thread.
This is needed for 570+ login, and can be used to reduce region based update systems from 4 regions to 1 region (64 particles). That means the complete networking io can be reduced by aproxemately 60-70%. The names are not confusing, it's just you having a problem understanding it.

5. Originally Posted by Maxi
This is needed for 570+ login, and can be used to reduce region based update systems from 4 regions to 1 region (64 particles). That means the complete networking io can be reduced by aproxemately 60-70%.

Also, give an example of your "region-based update system", as what you're saying doesn't make any sense.

6. Originally Posted by iKilem

Also, give an example of your "region-based update system", as what you're saying doesn't make any sense.
If you want to be a smart ass, go ahead and I'll stop caring to try explain and learn you something. I reckon the reason you are stating those questions, is that you can't pick out the information, either because you didn't read it or you're (with all respect) not that smart.

7. Thanks for this Maxi, it was a good read.

8. Originally Posted by Maxi
If you want to be a smart ass, go ahead and I'll stop caring to try explain and learn you something. I reckon the reason you are stating those questions, is that you can't pick out the information, either because you didn't read it or you're (with all respect) not that smart.
I guess I didn't make myself clear. I want an example of the actual protocol where your variables are used.

9. Originally Posted by iKilem
I guess I didn't make myself clear. I want an example of the actual protocol where your variables are used.
There's a reason why only 2 people have 570 login...

10. Originally Posted by iKilem
I guess I didn't make myself clear. I want an example of the actual protocol where your variables are used.
Have a look at the regions in 570+.

Page 1 of 5 123 ... Last