

t3ssel8r did the math to define three coefficients which alter animation predictably.
Now we can make changes to our three scalars and see directly how the system’s step response changes. (Somewhat unpredictably, as it turns out.) It’s just hard to adjust these numbers with any sense of competence or agency.
Game Feel by Steve Swink
delay time for an echoed sound effect
notes on a musical scale
Volume of left/right stereo channels
Color or brightness of one or more neopixel LEDs
Pixel coordinates on a neopixel LED strip
Abstract Space or Values
position of a solenoid or linear actuator
1D Coordinate or Position
The concepts explored in this space should be applicable to all of these types of movement, and more!
Direction and speed of a DC motor
rotation of a pixel around a ring
voltage applied to a transistor
rotation of a continuous rotation servo motor
Brightness of an LED
Position of a stepper motor
volume of a buzzer or other sound
Rotation or Angle
Vibration strength of a haptic motor
Strength or Intensity
flex
pressure
A servo motor is an obvious choice, but many other options can be explored
But in the end, whatever sensor system we use will eventually spit out a control parameter, and the knob on the arduino breadboard is a useful substitute for that parameter.
light sensors
accelerometers and gyroscopes
There are many other types of sensors. Interpreting and filtering sensor input is a subject worth study.
We can animate anything which can be controlled with a range between one number and another
analog microphone (returns sound volume)
Ultrasonic rangefinders
The potentiometer in the example is a stand-in for some kind of sensor or interpreted control value
Other types of sensors
Sidenote: other types of movers
public class SecondOrderDynamics
{
private Vector xp; // previous input
private Vector y, yd; // state variables
private float k1, k2, k3; // dynamics constants
SecondOrderDynamics (float f, float z, float r, Vector x0)
{
// compute constants
k1 = z / (PI * f);
k2 = 1 / ((2 * PI
k3 = r * z / (2 * PI * f);
// initialize variables
хр = x0;
у = x0;
yd = 0;
}
public Vector Update(float T, Vector x, Vector xd = null)
{
if (xd == null) { // estimate velocity
xd = (x - xp) / T;
xp = x;
}
y = y+T * yd; // integrate position by velocity
yd = yd + T * (x + k3*xd - y - k1*yd) / k2; // integrate velocity by acceleration
return y;
}
}

This has distinct similarities to simple harmonic motion

𝛇 >= 1: no oscillation, position
eases toward input

as 𝛇 increases, the oscillation is dampened

0 < 𝛇 < 1: oscillation exists; much more when 𝛇 is small

𝛇 = 0: oscillation never stops
acts very like drag or friction, by dampening the velocities
describes how the system’s position
settles at its target input
𝜁
Multiplying different constants by vel_position
, acc_position
, and vel_input
results in different characteristics of movement
spring forces, friction, and other types of forces can directly modify our velocity variables
And for some types of mechanical motion, we will want to directly modify the velocity of our position and our inputs

So we want to modify --or scale-- acc_position
How much velocity changes over time is called acceleration.
we scale acceleration and velocity by multiplying them by constants. Which we call scalars.
That is, we want to change the velocity of position. (AKA vel_position
)
scalar_vi * vel_input
input
scalar_ap * acc_position
scalar_vp * vel_position
position
We want to alter the character of the movement of our position

k3
k2
k1
OK! So...
We have input
and position
values
We are not mapping position
directly to input
anymore
But instead we want to set up some math so that position
moves toward input
over time
r
negative r = initial response moves the opposite direction first
Like Ease Out Back
r > 1 is like the movement overshoots

r > 1: overshoots past input
see how the point of the response curve is sharp here and curved above? That.

0 < r < 1: immediate response to vel_input
because(?) one thing r controls is, how much does the relative velocity of our input affect our movement?
when r is 0, the system has more inertia, and is slower to respond

r = 0; system takes time to accelerate from rest
speed and direction of initial movement, and amount of overshoot past the input
How do we learn to use these scalars effectively?
Now there are three new numbers we can play around with, and changing them will alter the dynamic movement of our system.
frequency of vibration in Hz

“the first task is mapping input signals to motion. The expressive potential is in the relationships.”
“With the right relationships between input and response, controlling something in a game can achieve a kind of lyric beauty.”
How do we do that?
Don’t worry about trying to implement this yet, let’s just understand the pieces. the position of our mover moves according to its velocity, which changes according to its acceleration and that sum total of its position and movement is equal to the position and velocity of our controlling input.
This gives us a smooth trajectory which moves position
toward input, just as we wanted
But wait! Wasn’t this about moving with some kind of intentional control of the character of the movement?
The movement shown here demonstrates a kind of “personality” to the animation
𝒇


r < 0: negative initial response; anticipates motion by winding up

bwoing-oing-oing...

boing!

ringy
these step response graphs show how the same springy movement changes scale, but not shape, when f is changed.
doesn’t change the shape of the movement curve.
speed of reaction
r is the initial response
𝛇 (zeta) is the damping coefficient
f is frequency


being predictable gives us creative agency over how the animation feels
And they behave predictably in ways that we can understand and compare
These parameters are what gives our movement the character we are looking for.
you could easily use map()
to take a potentiometer’s input, and feed it into any of these coefficients
think of them as control knobs - we could easily connect them to sliders and play with dfifferent values
Three values to tune movement

This gives us three different numeric constants, which have predictable effects on the movement animation.

initial tablet notes while watching video...

so we can use those to generate values for the scalars.

This is the “Step Response”, a standard way of visualizing the dynamics of a system
Let’s visualize how the system responds to a single, sudden change in the input
scalar_vp scalar_ap
and scalar_vi
are noted in video as k1, k2, and k3
vel_position
etc. are noted in the video as y-dot, y-dotdot, and x-dot
Naming Things - come up with better and more understandable names for k1-3, and the velocity, acceleration, input acceleration terms
if we are using delay()
then the value in that function is our deltaTime
deltaTime
is the amount of time we wait between updates
It helps to know how fast our inputs are changing so we can react differently to sudden, large changes
how much input has changed by per deltaTime
step
the velocity of input
how much we will be changing the velocity (vel_position
) per deltaTime
step
how much position
changes per deltaTime
step
the value we get from some kind of external input
the acceleration of position
the velocity of position
vel_input
input
the position of our mover
acc_position
vel_position
position

Just as the position of the ball in the animation accelerates toward the position of the mouse, position
must accelerate toward input
in this model.
Nature of Code examples of this type of movement are worth checking out, especially if this feels unfamiliar.
And if input
stays the same for a long time, our position
will eventually settle at the same value as input
.
That is our goal here.
The way position
moves toward input
is what we are hoping to learn to control.
position
is changing over time, and settling at the value of input
Note that the position
value is following the changes to the input
parameter
So if you see x
or y
that is why; they are the input and position respectively
The only reason for this aside is because there will be screengrabs and gifs from the video
Q diff between this and PID
We will be using input
and position
instead.
In the video, he calls the input x
and the position y
, which is very confusing.
example gif of character animation based on input parameters
TODO: go over non blocking delay substitutes
add context and animation for three different values
All the graphs are screenshots from the video linked above. Credit to t3ssel8r

So we can plot the input (green) and a position (blue) which moves toward the input value over time
change over time
position value

The potentiometer parameter directly changes the servo angle of rotation
input value
Both systems have the same key components
deltaTime
value since last loop (using delay
or (preferably) non-blocking timing function)
Time
The mover will follow the changes over time
anticipation
bouncy
stretchy
overlapping action / inertia
perky

For this example, our input is a potentiometer (knob), and our mover is a servo
Angle of rotation for servo motor
lethargic
Sets of Movement Values
Servo Position (Angle)
Input values will change over time
Analog value read from potentiometer pin (0 to 2048)
Sensor
comments with the useful ranges

have sets of f, z, r which work well for this type of movement
deltaTime
value since last frame
Our Robotics Example System
position follows changes over time
input will change over time
Time
Angle of rotation for enemy mob turret
Distance vector magnitude from player to enemy mob
Position Vector
Input Parameter
Game Animation System
to do so, let’s look at the model of a game animation, and compare it to the model of a simple, single-servo Arduino sketch
I would like to try and translate the techniques outlined in this video to animatronics, robotics, and other physical animation and motion
Note how the tilt of the turret reacts to the direction of its movement, as though it has mass and inertia

The position
variable changes, and this turret mob follows in a smooth and natural way
rather than using interpolation curves between keyframes, a type of motion is mapped to a controlling parameter It is very similar to how we often control animatronics or robots, by modifying a control parameter for various actuators or types of physical motion
this video is about procedural animation in games