Planet Defence

WebVR experiment #2 with A-Frame

Arrow keys to move the turret, space to shoot. Save the planet (it’s behind you).

Debrief

This project turned out to be much harder than I anticipated!

The turret charging its laser…

One of the first issues I ran into was rotating the turret. Because of the shape of the model, the rotation point was totally off, and there’s not way that I can tell in A-Frame or three.js to fix this.

What I ended up doing was pretty neat, I created a box, and placed it at the rotation point that I wanted. Then I made the turret model a child of that box, and positioned it relative to it’s parent. That way I can apply rotation to the box and the turret rotates from this point too.

There were lots of animations happening here. The turret needs to rotate, the beam grows in scale and position, the light surrounding the beam grows in intensity, and finally, the beam shoots off into the distance. I found that using A-Frame’s <a-animation> was messy and unwieldy. In my last experiment, I found myself having to clean up the DOM once the animation had completed. Instead, I opted to use TWEEN, which is part of three.js, and hence part of A-Frame.

Another issue I ran into was positioning the beam. There are two states for the beam: loading and firing. When it’s loading, it really needs to be a child of the turret, so that it can be positioned and animated in exactly the right place, and continue to move with the turret, before it’s fired. However, after it’s fired, it should not be linked to or follow the turret rotation in any way.

To solve this, I use two different beams. The loading beam is positioned as a child of the turret. When it’s ready to fire, I need it’s position and rotation, so I can apply that to the second “firing” beam. The problem here is that the “loading” beam’s position is relative to it’s parent.

To solve this, I was able to grab it’s world position by creating a new THREE.Vector3, and use the setFromMatrixPosition method with the “loading” beam’s beam.object3D.matrixWorld property. I then apply the world position to the “firing” beam, as well as the rotation of the turret.

Once the firing beam was in place, I had a lot of difficulty with the released beam actually firing. TWEEN uses the variables as they were set when defining the tween, not as they are set when the tween starts. Even changing the value of a variable during a tween’s onStart method won’t have any effect on the value during onUpdate.

In the end I resolved this by calculating the position (end position and current position as a percentage between start and end) during the onUpdate method, which isn’t an optimal use of resources, but the best I could manage.

The next major challenge I faced was figuring out the end point that I wanted the beam to fire to. It’s no good just animating the beam’s position.z, because this doesn’t take into account rotation (z is always in the same place, no matter where the turret is pointing).

After looking into some complicated solutions (such as creating a new Matrix4 with the turret’s quaternion, and translating the z position of the matrix) I finally discovered three.js’s very handy translateZ method, which did all the heavy lifting!

To-do

  • Sounds
  • Add controller support for moving and firing the turret
  • Add enemy spacecraft, flying toward the planet for you to shoot at
  • Add collision between beam and enemies
  • Explosions

Drone Attack

WebVR experiment #1 with A-Frame

WASD to move around. Look at the drone to fire your laser at them.

Debrief

This was a fun first project! I ran into some interesting problems along the way, but mostly things went pretty smoothly.

Shooting at drones is much less violent than at humans.

A lot of the fun for me on this project has been playing with lights and sound. When the laser is activated, it moves a red spot light on the target.

The positioning of the sounds add a lot to the scene, and are super easy in A-Frame – I just made each sound a child of the element they were emitting from. You'll notice as you walk close to the drones they become louder, and the same is true for the sparking sound, while the laser sound emits from the camera so it's always the same volume.

I ran into lots of trouble with the particle component (the sparks) – it wasn't playing nicely with the environment component. It took my a while, but I eventually tracked it down to this bug, which I resolved (at least for now) by removing fog from the environment.

The position of the laser was another difficult aspect. It took my a while to realise that if I matched the start point with the camera position, I would be looking directly down the line, and thus unable to see it!

I'm not quite happy with the single pixel width line. Of course, I could use a cylinder, but shapes like that are generated with a width, height, depth, rotation, and position, as opposed to my ideal case: start, end, and diameter.

Another problem is that the start and end positions can change while the laser line is visible (if the camera or drone moves). I could lock the laser to the camera by making it a child of the camera, but there would be now way of locking it at on the drone end (plus I would have to deal with converting the world position of the of the drone to the relative position of the line in the camera).

So, rather than do that, I opted for the more resource intensive method of reapplying the start and end position of the laser line on every tick. In hindsight, this is far from ideal, and the likely cause of memory crashes (especially on mobile).

I did experiment with a Curve component, which allowed my to create a curve at a start and end position, and draw a shape along that curve (I used a repeating cylinder). Unfortunately, working with this component in every single tick was far too slow.

What I'd like to try next is drawing the laser as a child of the target (so that it moves with the target), and if the camera moves, just turn the laser off until a new click event occurs.

To-do

  • Resolve memory leak
  • Drones explode after x seconds of being hit by laser
  • Scores
  • Timer
  • Start / Restart

Quantum Leap

Small changes to our product can lead to large changes in user behaviour.

The colloquial phrase Quantum Leap or Quantum Shift means to make a very large improvement or change. Ironically, this is the exact opposite of  Quantum’s scientific definition, which refers specifically to the smallest possible change.

When operating at scale, we find that small changes to our product can create large changes to user behaviour. A good question to ask ourselves is: What’s the smallest possible change I can make to my product which will result in the largest possible returns?

The answer will give us a hypothesis: I believe that moving the advertisement into the sidebar will increase my email subscription rate by 10%.

Now, test, measure, and iterate. Aim to achieve a huge quantum leap by implementing a tiny quantum change.

 

Momentum

How do you transform an idea into a product? Open your calendar.

I had a conversation with a close friend today. While we talked, a product idea surfaced. The more we explored the possibilities around this idea, the more excited we became.

This experience happens to everyone, frequently. But most of the time, that’s where the idea stops. Nobody is sure of the next steps, and even if you were, nobody thinks they have enough time, anyway.

So, what’s the next step for transforming an idea into a product?

Traditional Product Management might tell you to Validate your idea. That’s terrible advice. Validation this early only serves as a means of letting negativity and pessimism end your product before it started.

No! Trust your instinct. Back yourself. Worry about validation later.

A better first step is to open your calendar. Find just one day in which you can cancel all your other meetings, take the day off work, and create a prototype or MVP.

When that day is done, you’ll have a number of things: something visual, something usable, something to demo, something to validate. But more importantly, you’ll have momentum.

Minimum Viable Marketing

Most marketing campaigns, aim to reach as many eyes as possible. Here’s another approach: Minimum Viable Marketing.

We’ve all heard about lean product development principles: Create a Minimum Viable Product (MVP), measure its performance, and iterate.

We could apply this same principle to many Product disciplines. Take marketing, for example. Often, a Product team will hire a marketing manager or consultant and launch a campaign, aiming to reach as many eyes as possible.

Here’s another approach: A Minimum Viable Marketing (MVM) campaign.

Define a small campaign targeted only at the early adopters amongst your market segment, using words like Innovative, Pioneer, Breakthrough, Private, Limited, and Now. Choose just one channel to reach them on.

No need to build out every asset for every medium. No need to get the alignment just so. No need for pixel perfection. No need to wordsmith.

Since you’re starting small, take the time to get to know your audience. Talk with them, without any hint of self-promotion. Show them your marketing materials and gauge their thoughts and reactions.

Then iterate.

Hypothesis Driven Development

Once you have a hypothesis, you have something to test and validate. Gather data, then conduct an experiment.

An important tool for every Ideas Person. Hypothesis Driven Development is the difference between wandering and way-finding.

Light bulb moments. They happen all the time. You stumble into a pain point or discover a problem and think “Somebody should solve that…”. Then you realise that you should solve it.

Continue reading “Hypothesis Driven Development”