Tuesday, April 4, 2017

Hashtag VR Stealth

So, like anyone else who's ever strapped an HTC Vive to their head, I am absolutely enthralled by the room-scale VR experiences it makes possible. The first time I tried the Vive, I was transported into The Lab by Valve, and I came out of VR expecting the teleporting mechanics to work in real life. Almost immediately upon taking off the headset I turned to my friend Julius and said, "We need to develop something for this. Something cool."

Fast forward to when we were both out of school and actually had Vive headsets with the space to set them up (because for a while my apartment wasn't big enough to handle the minimum room-scale size in addition to all the stuff I have). My friend and I decided to do a Vive game jam one weekend, and I thought it would be cool to try attempting stealth mechanics in VR--a decision which was probably fueled by the many hours I had recently invested in playing Horizon Zero Dawn.

As it turns out, making an entire stealth game in one weekend was probably a bit of a pipe dream, but we did get a good baseline to revisit in the future should we decide to take it further (we're currently devoting our free time to making a mobile game which I'll post about at a later date). Developing for the Vive is unlike anything else for a number of reasons, and a bunch of wrenches were thrown in the development process when I realized how easy it is to wall hack in room-scale.

A bit of context for those of you who may not know what I mean by "wall hack": Let's say you're playing a VR game in the Vive. The main requirement for room-scale VR is that you've got a nice, clear play area, which means that you have an entire rectangle to walk around freely in, despite the fact that there may be barriers in the game you're playing. When I say players can "wall hack", what I mean is that they can clip right on through the in-game walls as if they were nothing, because they can physically walk through them with no problem.

There's even a cool particle effect!
The basic premise of the game is that you're trying to break into a laboratory to download some data off of a computer while trying to avoid the patrol robots that are guarding it. Most of the code I wrote that weekend and the few days following it was focused on the main movement mechanic of the game: being able to throw a ball and teleport to wherever it lands. The same ball can also be thrown at the power switch on the back of a patrolling robot to shut it off.

I'm pretty terrible at aiming.
Getting the arc that the ball should be thrown at and having it bounce off the objects in the room was mostly trivial. I employed the use of physics materials to get it to bounce the way we wanted, and tracked the motion of the player's hand to get the throw trajectory and power. Even getting the proper offset between the player and the camera rig to teleport the player directly above the ball was super simple. The biggest issues turned out to be usability issues (I might make the robot power switch a larger target, for example).

The ball turns green when it stops.
Okay, so maybe it's more of a teal.
For obvious reasons, we only want the player to be able to teleport to the ball when it's stopped. However, being able to tell when the ball stops moving is much harder when it's far away. The solution to this problem was really simple: have the ball change color when it stops. It worked like a charm, except for in certain cases.

It's like having x-ray vision!
What if the player throws the ball behind a wall? In a game about sneaking around corners and past various objects there are probably a lot of scenarios where the place you want to be is obscured by the thing you're currently hiding behind. How do you tell where the ball is if you can't see it? The answer came in the form of a custom shader. I applied a different material to the ball such that it would draw in a solid color if it was behind another object. It made it a hell of a lot easier to tell when you were able to teleport and where you'd actually end up.

I almost used yellow instead of red.
One of the things I thought about early on was that players shouldn't be able to teleport to just anywhere the ball stops. There needs to be enough vertical clearance that the player can stand up wherever the ball lands, as well as enough horizontal clearance that there isn't a wall directly in the player's face when they teleport. These restrictions were already implemented when I was doing usability testing, so, in a few cases, the ball would stop and turn green but I wouldn't be able to teleport to it, and I realized that I didn't have any sort of indicator for when the ball was stopped in an invalid location (so I added one and hey look at that it's red instead of green).

You can't tell, but I'm trying to throw it.
After getting these feedback mechanisms set up, I decided to see in what ways I could break the game. One of the things I noticed is that I could release the ball inside a solid object and get it to pop out of the side opposite where I was standing, which was obviously not something I wanted players to be able to do. To remedy this, I don't allow the ball to be thrown when it's inside a wall, or if it has been inside a wall at some point during the last few frames. The ball will turn red to indicate that it can't be thrown.

The extra restrictions worked well in most cases, but what if the player sticks their hand through the wall and drops the ball on the other side? One solution to this is to just make all the walls thick enough that the player can't do this, but you never know how big someone's room-scale space is going to be. The solution I came up with was to raycast from the player's shoulder towards their hand and see if that raycast hits anything, but even this isn't a perfect solution. What if the player's arm is bent around the corner of a wall and the game thinks the player's arm is going straight through the wall? What if the player just steps inside the wall so the raycast doesn't actually hit the outside of the wall at all?

Obviously the biggest problem is dealing with players being able to walk through walls in the first place. The current solution to this is to darken the screen and change the camera's culling mask so it doesn't draw any of the robots--this way you can't look through the wall to peek at the robots' locations. There are still a lot of problems with this, however; what if the player walks into the wall just to hide from the robots and stay out of reach? What if they walk through the wall to the other side and play from there? In the future, I'll probably change this so that certain functions of the game will stop until the player goes back to where they were before stepping into the wall. It might also be necessary to see robot locations through walls somehow so the player doesn't have to rely strictly on audio cues (I mean, hey, Horizon Zero Dawn lets you peek at enemies through walls and that can be pretty crucial for stealth sometimes).

The yellow lines represent the robot's view frustum.
Currently, the robots aren't actually worth being stealthy around--they only exist to patrol and be turned off by the player. The chasing/searching AI doesn't exist yet, but all the building blocks are there. I built a patrol route editor and a view frustum editor, both of which have custom scene view GUI and some inspector buttons. I'll probably write more about the actual tool itself later, because it's complex enough to warrant having an entire post to itself.

More updates on this project will come when we decide to do some more work on it, but for now I'm focusing my attention on a mobile game in my free time instead, so stay tuned for some info on how that's going. Until next time!

--JBird

Sunday, April 2, 2017

Hashtag Reboot

Hey everyone! JBird here, coming back from the dead to break the long silence! A lot of stuff happened in rapid succession for a while there, and writing blog posts took a back seat. That isn't to say I haven't been working on stuff, I just haven't been able to write about it. I'll get everyone caught up with what projects I've been working on in a little bit, but first I want to talk about what's been going on with me.

I've lived in five different places since I graduated about ten months ago. Working as a seasonal employee and getting your end date extended multiple times will do that to a person, I guess. The moves have been hectic, but the folks over at 1st Playable Productions in Troy made it worth it. 10/10 would work for them again.

I also built a new computer and got an HTC Vive! Virtual reality is friggin' sweet, and I've gotten a few chances to develop VR applications for various platforms, but the Vive takes the cake when it comes to VR headsets. It lets you walk around in VR. Once more for the people in the back: you can walk around in VR. So cool! Details of my exploits with Vive development will come at a later date.

So what can you expect to hear about in the next series of posts?

~ Making a modular ship-builder for an Asteroids-like game.
~ Adventures with VR stealth.
~ The trials and tribulations of making a camera for a 2D sidescroller.
~ And probably some other stuff, I'd imagine!

I've also started doing a podcast thing with some friends. We're still trying to find a permanent home for that, but you can bet I'll plug the crap out of that when we've established it a bit more.

Anyway, more posts coming your way soon! Stay tuned!

--JBird

(I just noticed that the only other posts I made to this blog were literally last April. Guess I just like doing dev blog stuff in April for some reason. Huh.)