Archive

Status

I put together this halftone shader effect in Blender earlier today:

The key realization for me was that Blender's shader nodes allow you to use Diffuse BSDF or other shaders as inputs to your setup. This means we can take the lightness of our mesh and use that as an input to a color ramp with a step function in it. In more detail, here's the shader setup:

I'd wager a more skilled artist could replace the dot-pattern generator with something that gives more consistent result and doesn't have that semi-circular banding issue. Give it a try and let me know if it works out for you.

Cameras are hard. If you've ever found yourself fighting against a camera that would really like to pivot in a direction you don't want it to, you've been on the receiving side of this technical difficulty. The reason behind your struggle is simple: spiteful developers.

Not really. Or at least probably not. The fact of the matter is that making a camera which balances the atmosphere of a game, moves quickly enough to keep up with the player, moves slowly enough to not move around with the player's jitters, and accounts for the corner cases like a player getting teleported -- it's not a simple thing.

I'd like to talk about the different methods I've been experimenting with in Clearing Skies. This is as much a journal entry for me to see what I've tried and why it works or doesn't work as anything else. I hope that someone may find some insight in it.

Approach 0: Strap the camera to the player.

This is the simplest and most straightforward approach to moving the camera. Wherever the player moves, the camera follows.

  • Simple! Easy to implement and understand.
  • Basically no corner cases where movement will be odd.

There are some drawbacks, and they're not too hard to see. When the player shakes or moves about drastically (like if she shakes after a shock or hit), the camera is liable to jitter along with her. Shaking the camera is a good way to induce nausea or eye strain in the player. Additionally, you lose the sense of level depth. The entire space is continuous. This is fine, generally, but for the first dungeon in particular, this felt to me like it shrank the space considerably.

  • Can cause eyestrain for sudden movements.
  • No way to add 'cinematic' elements on transitions between rooms.

Maybe there's an easy solution to the rapid movement problem? Indeed, we can try...

Approach 1: Smoothed Camera Movement.

The camera smoothly transitions between where it is and where the player is located. This solves a lot of the issues with the player shaking rapidly. It's like attaching a spring to a camera gimbal.

  • Still easy to implement.
  • Reduces eye strain from rapid motion.

The downsides are visible in the gif above. The biggest issue we run in to is the rapid movement of the player between rooms. The camera has to spend a few frames catching up to the player location on transport to a distant location. This can be solved by snapping the camera (disabling smooth on transition), on setting a max threshold before the camera teleports, or a few other tricks. No matter what, it's a bit more involved than simply assigning a location, and it still doesn't give us the cinematic room sweeping we want.

  • Camera has to catch up on long moves.
  • No cinematic controls.

Approach 2: Camera Zones

When the player character enters an area, the camera's bounds are set to match the region. This means the camera moves smoothly inside the zone, sliding to follow the player and 'transitioning' when the player moves between regions. I like the way this looks -- it divides the map in such a way that it makes things appear larger than they are.

  • Looks good. Cinematic.
  • High degree of control over where the camera moves. Can cut off areas outside of the map to avoid wasting screen real estate.

It's not perfect, though. Transitions are very abrupt and might cause issues with visual tracking of the player. It's also very cumbersome to implement, as the zones need to be defined manually:

Furthermore, troubles come in the way of overlapping rectangles. Not the region on the bottom where it may be necessary for two zones to overlap. Plus, when we finally leave the map, the bounds for the camera will need to change. Lastly, when we change the camera bounds, we lose the ability to smoothly transition between states.

  • Possibility of weird edge cases when moving between zones.
  • Time consuming to put together regions.
  • Not clear how to restore full camera zone when leaving dungeon.
  • No smooth transitions.
  • Visual tracking is hard on screen switches.

In a more perfect world, I'd love to be able to define small pins which act as boundary keepers for the camera, then, if a distance is exceeded, have the camera quickly tween to the player location and return to tracking. I don't have a solution for that worked out yet, however. Time will tell if I get it solved.

Bucky Isotope recently made mention of building the US-Mexico border wall entirely out of LEGO, following it with an inquiry on how much such a wall would cost.  Twitter, even with the newly increased comment size, still did not provide ample room for the calculation with sources.  This short piece will serve that purpose.

We will assume that the wall will be comprised of 2x4 LEGO brand building blocks for the sake of simplicity.  It is possible that a more cost effective wall be made if a different piece is chosen as the basis, but it will suffice for our purposes.  

9.6 1.8 1.0 31.8 32.0 4.9 2×0.1 8.0 8.0 8.0 8.0 31.8 15.8 4.9 2.6 6.41 0.8 0.6 0.3 Credit: Cailliau.org


A 2x4 LEGO brand building block has dimensions 16mm by 32mm by 9.6mm. 

If we simplify the surrounding border (heh) and remove the cap insets, shifting the volume instead to the perimeter by increasing the thickness to 1mm from 0.8mm, we can sum the four walls and 'ceiling' thusly:

Left: 15.8mm * 9.6mm * 1mm = 151.68mm^3
Right: Matches left.
Front: (31.8mm - 2mm) * 9.6mm * 1mm = 286.08mm^3 // We subtract 2mm for the thickness of the left and right walls.
Back: Matches front.
Top: (31.8mm - 2mm) * (15.8mm - 2mm) * 1mm. = 411.24mm^3 // Subtracting for the front, back, and side walls.

Total volume: 849mm^3 = 0.849cm^3.

At the time of writing, LEGO blocks are manufactured from acrylonitrile butadiene styrene (ABS), having a density of 1.05g/cc.  A 2x4 LEGO brand building block then weighs approximately 0.89145g, giving us 1121 blocks per kg.

We can convert an average eBay cost of approximately $50/lb to $110.23/kg, or approximately $0.0893 per block.

The US-Mexico border is 3,145km long from the Gulf of Mexico to the Pacific ocean.  Assuming blocks were stacked using the long side, it would take approximately 98,900,000 blocks for a grand total of $8,831,770.

The wall would stretch an impressive 9.6mm into the air and would weigh 88.16 metric tons.

If a taller or wider wall is required for some reason, one can calculate this by multiplying for every additional ~10mm of height desired and again for every 16mm of width desired.  For example, doubling our wall from 9.6mm to 19.2mm would double the cost to $17,663,540.  Doubling the width to 31.6mm would double the cost again to $35,327,080.

The average adult male from Mexico is 172 cm.  To construct a wall with this height at a thickness of 15.8mm would cost approximately $1,582,358,791.  It would require a human to be moving at least several centimeters per hour to breach.  

Last week's progress is listed here https://www.josephcatrambone.com/?p=1110.

There are three things I really want to get done tonight.  (1) Characters, when they die, should go flying backwards after the last strike.  (2) I need to recursively swap out the crash-dummy yellow body parts with something that's more in line with the game's theme.  (3) I need to actually write something that ends the level.  I did make a phone booth.  (Whee!)

Let's review those P1's from the start:

  • Main menu with start/settings/quit.

Bam.  Done.  Sorta.  Quit and start work.  Definitely need to add the settings page and maybe put something other than "Title" in for the title.

  • The 'fighter body' should broadcast the "damage taken" event to child nodes so they can record whether or not they're dead.  Dead enemies should be despawned.

Also done!  Enemies indeed die and take damage.  That's handled by the controller.  I need to figure out what approach I want to use for the "die but then fly backwards on hit if enough damage is done."

  • End-of-level triggers need to fire.

The triggers fire when the player enters, but that's it.

I even had time for a little AI:

Last week's progress is listed here https://www.josephcatrambone.com/?p=1109.

I spent a while running through the game in its current state and think that it's fitting to add at least a few of the following features.

Priority One:

  • Main menu with start/settings/quit.
  • The 'fighter body' should broadcast the "damage taken" event to child nodes so they can record whether or not they're dead.  Dead enemies should be despawned.
  • End-of-level triggers need to fire.

Good to haves:

  • Motion feels very limited right now.  Jumping would go a good ways to helping that, as would having different attacked based on whether or not one was jumping or moving.
  • Perfect-time parrying.  Right now a user can cancel into a block at certain times, but there's no reward for having anything above 'okay' timing.
  • Rebindable keys would be very nice.

I know I should work on having a level completion and a main menu before adding any of the extras, and I expect I'll do as much, but I want to keep track of these items to I can refer back here and see how much I set out to accomplish and how much I actually accomplished.