012 - October 21, 2018

This past week I was supposed to work on client side interpolation as well as plan out the monthly subscription system so that people can pay for the game when it's released.

I spent Thursday - Sunday at the Rust Belt Rust conference and spent the few days before that working on Percy since I was speaking about it at the conference, so I actually didn't spend much time working on Akigi this week.

However - I was able to get the client side interpolation working on the plane ride back to the city.

Interpolate position Interpolate the client's position as it moves in between tiles. The vertical jerking is a bug in our terrain height calculation. I'll fix that..

I'm pretty tired from this weekend so I'll be short here.

Basically - our server tells us where an entity is in tile coordinates such as (0, 0) or (0, 1) for the bottom left corner tile and the tile right above it respectively.

On the client side we keep track of the 3d world coordinates that we're rendering the model at - such as (0.0, 0.0, 0.0).

If we see that the tile position of the entity is at a different location than our world coordinates, we'll interpolate towards it.

// Real code snippet
impl State {
    fn update_local_entities(&mut self, dt: f32) {
        for (entity_id, server_entity) in self.server_state.iter_entities() {
            let local_entity = self.local_state.entities_mut().get_mut(entity_id).unwrap();

            let tile_pos = server_entity.get_pos().unwrap();
            let tile_pos = (tile_pos.x as f32, -1.0 * tile_pos.y as f32);

            let mut world_pos = local_entity.pos_mut();

            // This entity is already in the proper position. Don't update its position.
            if tile_pos.0 == world_pos[0] && tile_pos.1 == world_pos[2] {
                continue;
            }

            let speed = (1.0 / GAME_TICK_DURATION as f32) * dt;

            // TODO: This code is very similar to the block below - normalize them
            if (world_pos[0].abs() - tile_pos.0.abs()).abs() < speed {
                world_pos[0] = tile_pos.0;
            } else if world_pos[0] < tile_pos.0 {
                // Increase local position
                world_pos[0] += speed;
            } else {
                // Decrease local position
                world_pos[0] -= speed;
            }

            if (world_pos[2].abs() - tile_pos.1.abs()).abs() < speed {
                world_pos[2] = tile_pos.1;
            } else if world_pos[2] < tile_pos.1 {
                // Increase local position
                world_pos[2] += speed;
            } else {
                // Decrease local position
                world_pos[2] -= speed;
            }
        }
    }
}

So if the tile position is (0, 1) we'll slowly interpolate the client position towards (0.0, Y, -1.0).

Note that Y is a variable that depends on the height of the terrain at a given point.

Also note that the z coordinate is negative. In OpenGL negative z is going into the page, but our tile coordinates only use positive numbers so we just flip the sign here.

Next Week

By next week I'll plan out the payment system (likely using Stripe) and build out the backend and frontend for the inventory system that will hold your items.


See ya next time!

- CFN