Game Dev Diary

Day 2: Let’s Transform everything at once what could go wrong? #

So we continue the learning journey from yesterday. We wanna move it with arrow keys now!

If you remember our example is based on the clear_color example and that example already demonstrates how to do something when a key is just pressed. So I explain briefly the idea of how systems query components, and that in this case the component we are interested in querying is the Transform component. We also need the same resource as the change_clear_color from the example.

My friend A stops me there and asked me, “but how do we pick the circle?” I reply with naive foolishness, “we will learn that later but for now our example only has the circle anyway!”

So we write this out:

fn transform(input: Res<Input<KeyCode>>, mut query: Query<&mut Transform>) {
    for mut transform in query.iter_mut() {
        if input.pressed(KeyCode::Up) {
            transform.translation.y += 1.0
        }
    }
}

And after my friend goes through the cycle of talking to Ferris and convincing them the code is correct, the application finally compiles without warnings and launches. She clicks the Up arrow and… nothing? ”Huh?” I think to myself, I was just telling her how much Rust makes coding simpler by moving all errors to the point where you are compiling your code and so once it compiles it just works. Not a great look let me tell you.

I suggest maybe the 1.0 is too small so we push it up a notch. Nothing changes, although both of us feel like the circle might be phantom moving? Or it might be our imagination…

I start having some doubts, I know we added the system to the app, so it can’t be that. Maybe there is some weird shadowing magic going on with the system name transform? My friend picked this name because she is still learning. Okay I change the name to move_system and run it again. It’s still broken.

But how?

Okay nothing a bunch of dbg! can’t solve. I add a bunch of dbg! after struggling a bit with its positioning, you can’t just wrap the transform declaration in a dbg! apparently!

Here’s where we end up:

fn move_system(input: Res<Input<KeyCode>>, mut query: Query<&mut Transform>) {
    for mut transform in query.iter_mut() {
        dbg!(&transform);
        if input.pressed(KeyCode::Up) {
            transform.translation.y += 1.0
        }
    }
}

And I look at the debug output in the terminal and within 2 seconds, I am facepalming and sighing and freaking.

In case you’re curious the debug out shows that things are indeed increasing in their Y transform. But somehow it’s not one thing that’s increasing, there are multiple things all increasing… but we only spawn the camera and the circle… wait a minute. Of course I had to forget the camera has a transform like anything else and that this is working. It really is. It’s just everything moves up by the same amount of pixels every time the up arrow is clicked. Everything including the camera that points at everything in the world.

I explain what went wrong and my friend bursts into hysterical laughter for a minute and I worry she might die from laughing but she stops after a bit and she is gladly fine.

“Welp. Remember how you asked me earlier how do we pick the circle, time to learn that!”

I explain the idea of marker components and we create one and attach it to the circle:

#[derive(Component)]
struct Balloon;

// snip...

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    commands.spawn(Camera2dBundle::default());
    commands
        .spawn(MaterialMesh2dBundle {
            mesh: meshes.add(shape::Circle::new(50.).into()).into(),
            material: materials.add(ColorMaterial::from(Color::PINK)),
            transform: Transform {
                translation: Vec3::new(-100., 50., 0.),
                ..default()
            },
            ..default()
        })
        .insert(Balloon);
}

And then I explain how to tell Bevy to pick components that have this marker component:

fn move_system(input: Res<Input<KeyCode>>, mut query: Query<&mut Transform, With<Balloon>>) {

And we run it and it works!

Goodness. I am such a terrible teacher. I really gotta sit down and prepare these materials ahead of time, don’t I?


Phantom movements #

I need to remember to reproduce that example at some point with the same version of Bevy, I am curious if the phantom movement was just us imagining or hoping it’s moving or if the camera and circle moved at a precision loss and caused that perceived slight jittery movement