About Vanilla NPCs

Published on Friday, March 17, 2023

Introduction

NPCs are kind of a dream for vanilla mapmakers as they open a new world of possibilities for immersion.

Since the recent public apparition of player skins NPCs, like Sir Roo's Vanilla NPC Shader, this now permits to have fake third person view of players in the game.


Our main concern now is to get a fully animated NPC using the player's skin. This means replicating the player's animations on the NPC such that the player can't differentiate the latter from a real player.

From body parts to NPCs

The Plan

I made this small project for a map - which will get released soon™️ - where I needed to have static NPCs which would be animated like humanoids entities (players).

For that, the plan of action was to:

  • Animate arms with the IDLE animation
  • Get the arms anchored to the torso, both in rotations and positions
  • Animate the head to follow the player's head when a player is near

By chance, just before starting this project, Mojang released the 23w06a snapshot, which introduced us the new display entites! And I must say, this is a game changer for the future, but has been a great help for this project!

Why so? Because they can handle multiple rotations at the same time, which means that it doesn't requires us to add the rotation of the anchor to the rotation of the animation transformation. So, the second part of our plan is now fully handled. This is a huge time saver!

The base animation

First step has been to grab from the game's code the players animations. I then ported them to Desmos.

What we can observe here is that the equation is non-cyclic; this is due to the fact that the animation is based on its previous state.

Though, I wanted to avoid a such situation for the NPCs, as it would require to store the previous state of the animation, which would be a bit more complex to handle.

So i reduced the number of cycles graphed, until i got this result:

Which shows an almost cyclic animation, which is perfect for what we want.

The second step has been to look at the variations of coordinates on the X and Z axis (we are here talking about the rotations in Euler's angles; Z represented by Y on the graph). Here below are in red the X axis and in purple the Z axis.

What we can observer here is that the two axis are sinusoidals, so I figured pretty quickly a new equation which was fitting the original one.

A=(sin(0.75t)cos(t))A = \begin{pmatrix} \sin(0.75 * t) \\ \cos(t) \end{pmatrix}

This equation makes the animation cyclic, and is a perfect fit for our needs. Technically speaking, the animation will look a bit too "perfect" once in game, but will be barely noticeable.

Importing into Minecraft

As we have a cyclic animation, we can just generate keyframes as mcfunction files, to which we can refer using a binary search tree for maximum efficiency. Special note with the recently added display entities, Minecraft is now capable of interpolating animations like this one over a single tick instead of a full second.

I also tried to interpolate over fewer keyframes (and thus reducing the number of updates to do), but the result was not as good as I expected. So I kept the 20 keyframes per second.

But here we are, we have now a fully animated NPC!