# [Java] Best datatype to store object position/Snap to grid?



## Ensefalon (Dec 15, 2019)

Hey guys, I've been designing a 2D, CLI-based space MMO ( sort of like EVE, meant to give the shit your brains experience as Aurora 4x/Dwarf fortress for those who know what that is) and I've been trying to figure out what are the best datatypes to store object position on a "massive scale" universe?

I use trigonometry to move the ships along a path towards the intended destination. But in doing so, I tend to have really large decimals and even if I round, I lose precision, and the objects

You'd expect in the perfect world that these ships would just snap to their nearest intended coordinate while moving there (without a decimal) and the world is happy and maybe I could store these values as longs instead of doubles.



My attachment

```
public class ShipPhysics {
    //THIS CLASS GETS CALLED EVERY FRAME, THIS TELLS ALL SHIPS TO UPDATE THEIR PHYSICS IN CASE OF DESTINATION CHANGE!
    public static void updateMovement(){
        for(int i = 0; i < lists.ships.size(); i++){
            ship s = lists.ships.get(i);
            double gotoX = s.getDestinationX();
            double gotoY = s.getDestinationY();
            double speed = s.getSpeed();
            double dx;
            double dy;
            double dir;
            dy = Math.abs(gotoY - s.getYPos());
            dx = Math.abs(gotoX - s.getXPos());
            dir = Math.atan(dy/dx);
            //System.out.println(i + " x: " + dx + " y: " + dy + " slope: " + slope);
            if(gotoX != s.getXPos() || gotoY != s.getYPos() ){

                if(gotoX < s.getXPos()){
                    s.setXpos(s.getXPos() - (speed * Math.cos(dir)));

                }
                if(gotoX > s.getXPos()){
                    s.setXpos(s.getXPos() + (speed * Math.cos(dir)));

                }
                if(gotoY < s.getYPos()){
                    s.setYpos(s.getYPos() - (speed * Math.sin(dir)));

                }
                if(gotoY > s.getYPos()){
                    s.setYpos(s.getYPos() + (speed * Math.sin(dir)));
                }
            }
        }
    }
}
```
Here  I send the battleship at coordinate (0,0) to coordinate (100,50) and takes a straight slope path to get there(trig), but yields this awful result. Sending the other ships to coordinate 100,50 results in numbers that round to (101, 51)





However, I wish for the grid to always snap to the nearest whole number.

Thanks ~ Sal


----------



## FordGT90Concept (Dec 15, 2019)

Use round() after you do math to get it back to the grid.  Alternatively, yeah, change to longs.

Remember that computationally, longs are much quicker than doubles.  If you're going to end up copying from long to double to do math getting a double result which you have to convert to long again, just leave it double and round as needed.

I guarantee you cos() and sin() are returning doubles or floats so best to just keep it double.  The stupid thing is that round() returns longs or ints so you're going to have to do senseless casting no matter what approach you take with Java.


----------



## Ensefalon (Dec 15, 2019)

FordGT90Concept said:


> Use round() after you do math to get it back to the grid.  Alternatively, yeah, change to longs.
> 
> Remember that computationally, longs are much quicker than doubles.  If you're going to end up copying from long to double to do math getting a double result which you have to convert to long again, just leave it double and round as needed.
> 
> I guarantee you cos() and sin() are returning doubles or floats so best to just keep it double.  The stupid thing is that round() returns longs or ints so you're going to have to do senseless casting no matter what approach you take with Java.



Thanks for the quick reply . What I have done is that I round once the object has finished moving to the pseudo-correct position. Maybe that patches in the hole. The issue I am later to be faced with, is size of the universe. I was thinking maybe big double, or something along those lines. But it's best I keep things simple for now as is before moving to the more extreme datatypes

Thanks ~ Sal


----------



## FordGT90Concept (Dec 15, 2019)

You're not going to want to do anything larger than double because processors will have to take multiple clocks to handle each operation.

If you know for a fact that you're going to be perfectly okay with pinning everything to a whole-number grid and longs are big enough for you, then go with longs.  Java round() already forces you to that, from what it looks like.

Most games address the problem you're describing by having grids inside of grids.  e.g. a universe grid, a cluster grid, a galaxy grid, a star grid, and a planet grid.  Each has its own scale and when you hit a coordinate on one, you move to the next down position relative to the approach.  This is how they were able to make a game like Star Control back in the 90s on 16-bit processors.


----------



## Ensefalon (Dec 15, 2019)

FordGT90Concept said:


> You're not going to want to do anything larger than double because processors will have to take multiple clocks to handle each operation.
> 
> If you know for a fact that you're going to be perfectly okay with pinning everything to a whole-number grid and longs are big enough for you, then go with longs.  Java round() already forces you to that, from what it looks like.



It's what additional position variables are for .


----------

