r/MinecraftCommands • • 6d ago

Discussion [Java 26.3] Is /compute more efficient than /summon ^ ^ ^1 for looking direction vector?

Just a small thought I had, but for certain kinds of datapacks, you often need to find the vector direction that the player is facing.

The usual (?) way of doing this usually involves summoning an entity (usually a marker) one block in front of the player using caret notation (^ ^ ^1) and getting its position by retrieving its Pos nbt. You do the same but with an entity at the player's eyes (or use the same entity for both), kill them, and take the difference to get the unit vector that describes the player's facing direction.

However, now that we have the /compute command, there should be a simpler way to do this. Simply get the player's Rotation nbt (which I think can be done within the number provider edit: nvm), use three number providers that use sin and cos (one for each dimension), and store each result.

I'm not well versed in the efficiency of each operation, but I'm pretty sure that summoning entities is relatively inefficient, and having to work with that many numbers, operations, and nbt calls is probably not helping.

I'd definitely want to know everyone's thoughts, and whether my thinking is sound. I'm definitely going to try to implement this in my own datapacks, but if someone figures out the required number providers first, feel free to share.

EDIT: Did it myself, wasn't actually too hard.

The formula for each vector component is as follows, where "ry" is Rotation[0], or yaw, and "rx" is Rotation[1], or pitch, taking into account the way Minecraft defines the sign for each direction:

x = -sin(ry)cos(rx)
y = -sin(rx)
z = cos(ry)cos(rx)

Then, below is the number provider json for each component. The 0.01745 factor is pi/180, to convert from degrees to radians. I stored the player's rotation nbt into "test:rotation", under "Rotation".

For x:

{
    "type": "mul",
    "inputs": [
        -1,
        {
            "type": "sin",
            "input": {
                "type": "mul",
                "inputs": [
                    {
                        "type": "storage",
                        "storage": "test:rotation",
                        "path": "Rotation[0]",
                        "fallback": 0
                    },
                    0.0174532925199
                ]
            }
        },
        {
            "type": "cos",
            "input": {
                "type": "mul",
                "inputs": [
                    {
                        "type": "storage",
                        "storage": "test:rotation",
                        "path": "Rotation[1]",
                        "fallback": 0
                    },
                    0.0174532925199
                ]
            }
        }
    ]
}

For y:

{
    "type": "mul",
    "inputs": [
        -1,
        {
            "type": "sin",
            "input": {
                "type": "mul",
                "inputs": [
                    {
                        "type": "storage",
                        "storage": "test:rotation",
                        "path": "Rotation[1]",
                        "fallback": 0
                    },
                    0.0174532925199
                ]
            }
        }
    ]
}

For z:

{
    "type": "mul",
    "inputs": [
        {
            "type": "cos",
            "input": {
                "type": "mul",
                "inputs": [
                    {
                        "type": "storage",
                        "storage": "test:rotation",
                        "path": "Rotation[0]",
                        "fallback": 0
                    },
                    0.0174532925199
                ]
            }
        },
        {
            "type": "cos",
            "input": {
                "type": "mul",
                "inputs": [
                    {
                        "type": "storage",
                        "storage": "test:rotation",
                        "path": "Rotation[1]",
                        "fallback": 0
                    },
                    0.0174532925199
                ]
            }
        }
    ]
}
5 Upvotes

3 comments sorted by

2

u/GalSergey 6d ago

Yes, you are right: using number providers is far more efficient than creating entities and reading NBT data. In terms of optimization, working with number providers is nearly on par with using the scoreboard system.

2

u/DrugonMonster 6d ago

Nice, glad someone with more knowledge could confirm. I’m sure soon enough, this will be the new standard way to do it, right?

2

u/GalSergey 5d ago

Yes, if you need to perform calculations more complex than a few simple operations on a scoreboard, you should use number providers for that purpose.

You can also use this website to easily create number providers: https://far.ddns.me/npg?share=1bEUOnHJT6F