Argh. Day started off well enough. Ran some errands first thing in the morning, settled in to work a bit before lunch time. Fixed the previous night’s glitches pretty easily with a fresh head and a night of sleep to think on it, then started working on the next task I’d mentioned in my last blog, transfering routes that were still being entered. Had an idea, threw the code together, then flailed for a bit at a few glitches. I’d worked through lunch, just threw together a sammich and ate it at the computer, so I took a break then, watched an episode of Farscape, came back and found the problem easily. Started on the next task, exiting vehicles. This one was gonna use a lot of code from the vehicles, and I was expecting it to be straightforward. And it was – up to a point.
As an aside, if I’ve learned one thing so far in this project, it’s the importance of planning out the code more before diving in. Of course, I’ve learned this lesson the hard way before, but once again, I convinced myself that it would all be easy enough that more rigorous planning were unnecessary; the lack of same has been a contributing factor in most of the glitches that keep coming up. Anyway, back to the point…
There was one major difference I’d glossed over in my limited planning between getting into a vehicle and getting out. When getting in, the raw input path leads into the vehicle. Since actually hitting the vehicle would cause the path to abort, I implemented a system that tracked and stored collision data as the path was input. Then, if the last node was determined to be entering the vehicle, I could walk step back through the path dropping nodes until I arrived at the one just before the collision would’ve happened. Worked like a charm.
Doesn’t work at all for getting out of the vehicle. I was thinking I would just step forward the same way, until it stopped colliding with the car, on exiting from the vehicle. The problem being… the vehicle was not there at the time the path was drawn. So it’s not in path data.
Three main solutions I can see: one, crawl forward performing the collision checks all at once to find the first node that is outside the vehicle, and go there; two, initially disable rendering and have the character exiting the vehicle follow it’s path in a ghost state where it ignores collisions; only when it stops colliding, turn off ghost mode and appear, following the rest of the path normally; or three, insert a “ghost” collider for the car at the position it will be in when the LeaveCar action is executed, which does not block objects moving through it, but will register in the path collision checks, allowing my original idea of stepping through until the collision ends to work.
The last seems like the best, but there’s another hitch that I’ve been not thinking about – there might be other objects in the way. Do I cancel the route if there is another collision along the path? By this point I would already have ejected the passenger and replaced the car to a parked version again, so I’ll have to pick a place they can be put around the car that is not occupied. That’s not too terrible – I was going to be implementing that anyway, for the case where you give the exit car command when the car is already stationary, without any future path data to worry about. But if there is more path to follow, and the available space I put the passenger in is on the opposite side of the car from that path, they’ll promptly try to walk through the car, hit it, and cancel their route. Do I implement a full conventional pathfinding system to let the character find their way around the car and to the beginning of the input path they’re trying to follow? That seems unacceptable, given that manual pathing is one of the key gameplay elements.
I guess I’m going, for now, to go with the cancel in that case; #3 for the first problem – ghost car for colliding post-exit paths – using the open-space solver with a bias towards the side of the car where the first valid pathnode sits. If it’s forced to put them on the other side of the car, the route will just be cancelled by the collision and the player will have to redraw that route. In principle this will just become an aspect of the game that players will have to consider – long, elaborate routes are not going to be required anyway, but an advanced technique – but it might prove to be an element of frustration for the players that requries a better resolution later.
Oh well, enough winging about the problem. Onward!