064 - The Road to Artistic Confidence

April 26, 2020

I started the week outlining the things that I wanted to include in the first area of the world, Jaw Jaw Island.

I enjoyed that because after spending four years primarily working on the underlying tech and tooling for the game it's nice to finally be in a place where I'm designing the gameplay experience.

It's a different way of thinking and a different set of skills that I'll enjoy honing over time.

Art Confidence

I've abandoned the notion that I'm "bad at art".

After much overthinking and what I'd summarize as aimlessly floating through the ether hoping to find a magic silver bullet, I've realized that my path forwards is fairly simple.

Make art everyday.

It sounds obvious, but when I'm new to something it can take some time before I remember that it's all about the repititions.

I let myself get lost in the Googling when the real path forwards was to start doing and then Google the problems that I got stuck on.

Googling without a well defined, specific problem that you're trying to solve is good for a little bit while you're trying to get some breadth and familiarity, but quickly hits a point of diminishing returns.

My returns were long since diminished.

Make, make, make is the key here on out.

The pre-requisite for doing things everyday is inspiration.

Willpower can only carry you so far - you need to be instrinsically motivated in order to keep the streak alive on days that you aren't feeling at your peek.

So I marinated on that for a bit and realized that I wasn't artistically motivated by the original idea for the game, "a world with intelligent animals"".

Mainly because I don't care for animals all that much in genereal.

Instead - I'll be fascinated by something temporarily, and then move on.

For example, when I was in Lagos earlier in the year I saw a Tortoise at the conservation and was fascinated by how it ate grass. In that moment I was very inspired. Today though, I don't care too much for Tortoises.

Similarly - when I've traveled to other countries or even when I've traveled around Wikipedia I've found bursts of inspiration and interest that were intense, but short lived.

I'd like to use my strong short bursts of miscellaneous inspiration as a strength. As such, I've changed the thematic direction of the game.

The game will have different areas of the world home to different Tribes and communities. One city might have humans, another viscious ogres.

This gives me the room to dive deep into different concepts and explore different ideas without being bound to them forever for the entire game.

Landing on this has me, finally, feeling inspired by the game itself, not just the technology behind it.

From there I was able to find the motivation and inspiration to start working on art daily.

I'm on day 9 now and feeling more comformtable, confident and skilled everyday.

I just need to keep racking up the practice and watch my skills soar!

Here's some art that I worked on this week:

Beast cage Normals on the cylinders are messed up since I didn't UV unwrap them properly. But mistakes like that are how you learn.

Gorilla Getting started working on a gorilla model.

Displaying Damage Received

I added damage indicators that are shown for a short time after you receive damage.

Indicators for the amount of damage dealt

There are powered by a Trajectory struct under the hood.

/// When an entity receives damage we display the amount of damage as a number animating away
/// from the entity.
/// The data in the DamageAnimation powers this damage display.
/// The damage gets an initial launch angle, velocity and gravity and then we use that to determine
/// it's position at any time.
/// Trajectory equation: https://www.omnicalculator.com/physics/trajectory-projectile-motion
#[derive(Debug, Copy, Clone)]
pub struct Trajectory {
    launch_angle_above_x_axis: Angle,
    velocity_per_second: f32,
    y_gravity_per_second: f32,
    started_at: SystemTime,

Structuring my Workdays

I do a mastermind meeting every Monday with a friend where we give eachother feedback on how we're approaching our goals and businesses.

My action item from the last one was to add some structure to my day since I was feeling out of order now that I've started working on art alongside coding.

So to start I've split by day into three sections. Art, gameplay and tooling.

Every evening before bed I write down what I'll do for my art, gameplay and tooling sections of the next day.

Splitting my day into phases has made it easier to feel focused, since when I transition from one phase to another it feels like a clean reset and I always feel like I'm doing one thing.


I extended the TerrainChunk struct to have Vec<SceneryPlacement>, allowing me to easily add scenery into the game that gets loaded only when we load up the terrain for that area.

Before the Q1 refactor earlier this year scenery was always loaded regardless of where you were in the world, which would not have scaled.

Today we load up a chunk of terrain, and thus it's scenery, when you're within a certain distance of it.

/// TerrainChunks are batches of data that are relevant to some square section of the world.
/// Chunks have no knowledge of their final placement.
/// So a chunk located at tile (45,45) when it is finally placed would still consider its bottom
/// left corner to be (0, 0) internally when defining placements such as water.
/// It is up to the user of the chunk to translate all of these things appropriately.
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TerrainChunk {
    terrain_chunk_id: TerrainChunkId,
    pub heightmap_png: Vec<u8>,
    pub blendmap_png: Vec<u8>,
    pub blendmap_components: BlendmapComponents,
    tile_info: TerrainChunkTileInfo,
    pub water_planes: Vec<TerrainWaterPlane>,
    pub scenery_placements: Vec<SceneryPlacement>,

And here's an example YAML terrain chunk definition file, wh_15_c_45_45.chunk.yml:

    color: sand-base-color
    normal: sand-normal-map
    roughness_metallic: sand-roughness-metallic
    color: grass-base-color
    normal: grass-normal-map
    roughness_metallic: grass-roughness-metallic
    color: cracked-dirt-base-color
    normal: cracked-dirt-normal-map
    roughness_metallic: cracked-dirt-roughness-metallic
    color: cracked-dirt-base-color
    normal: cracked-dirt-normal-map
    roughness_metallic: cracked-dirt-roughness-metallic
    [0, 0]:
      top: AllowAllMovement
      right: PreventAllMovement
    [0, 0]: true
    [0, 0]: Unlimited
  - tile_within_chunk: [0, 0]
    tiles_wide: 1
    tiles_high: 1
    renderable_id: BeastCageNotBent

Other Notes and Progress

  • Start putting the foundation for benchmarking the different renderers (just WebGL for now) in place

  • Started putting in the foundation for a renderer powered by Apple's Metal graphics API

  • Started lightly researching WebGPU and made a documentation PR to wgpu-rs

  • Made the system that interpolates the camera always run after the system that interpolates the player in order to remove that race condition jitter at lower frame rates

  • Started setting up GitHub Actions for CI by making little bits of progress throughout the week. Still more issues to address so we're still using CircleCI alongside GitHub Actions for now.

  • Addeed mipmapping to the terrain but that introduced some texture bleeding issues that I'll need to fix in the next week or two.

Next Week

I'm dubbing this next week as my artistic ascension.

I want to complete something where I'll know that if I can do this, I can do anything.

I found a great 2.5 hour tutorial on creating a human base mesh with around 3k vertices.

This week I'll go through that tutorial and use it as a starting point for Akigi's human mesh.

I'm not sure how much stamina I'll have and whether it will take one or a few days to get through the tutorial. We'll see, as long as it is done this week.

I'll get other gameplay and tooling stuff done this week as well, but my number one priority is finishing the human mesh.

If I'm feeling up for the task I might even finish it, delete it and then do it again.

But that's just aspirational - we'll see if I have the stamina for that.

Cya next time!