Design in Practice
I originally wrote this entry as a design diary for DDO, but since I’m no longer with Turbine and the writing will never see the light of day, I figured I’d dig through some of that stuff, remove any company specific information, and post anything that might be of interest. I particularly liked this one, simply because when I came up with the solution it talked about I felt particularly cleaver ;)
The walls of Design
For me, the interesting part of design is the walls you work within. Be those the technical constraints, or the constraints you’ve placed on yourself for a higher level goal within your design. Many designers resent these walls as boundaries or limitations, but it’s within these walls that your creativity and ability to view something from multiple angles is truly tested. This is where design really happens; not in the ethereal space of a word document or ideas in your mind, but in the constraints of your medium.
The process of game development is a slow creation of these walls; each decision has consequences on what you can and cannot do in the future; or perhaps it’s better phrased as how you can, and cannot do things in the future. Often, by looking at the problem from a different angle, you can find a solution within your walls. While on vacation in Italy, I woke up with the solution, or rather the angle on a solution, for one such problem. They say the brain works on problems while you sleep; going over them in your head looking for solutions, and mine definitely seems to work this way. It’s funny, because I hadn’t given this issue serious thought in quite some time, so why it jumped to the forefront of my sleeping thoughts is beyond me.
The issue had to do with how lighting interacts with stealth. When we had designed our lighting model for the game, having the server know about the lighting of the scene was not a priority. None of our previous games had ever made use, or planned to make use of such information; and in this version of the engine, we wanted the lighting and shadow to be computed entirely at run-time. Except for a few mentions, the issue never really came up as a serious one.
But as we developed the game, I added a hearing and sight model to the AIs, and various stealth features to allow the user to avoid detection. These would essentially modify the range of hearing and sight detection based on the skills of the user’s character, and the abilities of the monster to see and hear. I added noise events to certain actions, such as an arrow hitting a wall, to allow users to distract the monsters. I added lights which could be shot with water arrows; cool, but useless if they don’t actually do anything. So we talked a bit about ways to move lighting information onto the server.
The first model would be to store lighting information across the world geometry or 3d space, but this would impose technical restrictions onto our lighting model, and require a ton of work which we didn’t have time for. It also required a ton of additional data that the server would have to manage, because the server had no concept of lighting. The second model would require that each light have an area of influence defined and monitor things which came into that area of influence; but this required that every light become a rather expensive type of object on the server (a few lights would be as expensive as another AI). So for a while, we just assumed lighting and shadows wouldn’t be able to play a role in stealth.
My thought upon waking was that perhaps the way we were defining the problem was wrong, and that the solution could be derived in the different fashion. Really, what we’re trying to do is tell the user “Don’t go into the light!”, and we don’t need to know the lighting of the world to do that. In fact, all we really need to know is where the lights in the world are relative to the player. And while lights don’t exist on the server, the objects which are placed with them, such as a torch, do.
By attaching some information to these associated objects, I can get a rough location of each light in the scene. Now, rather than having each light propagate a lighting value to various places in the world and somehow storing that data, I can use a combination of distance information and line of sight tests from the player to the light to determine if, and by how much, the user is being affected by the light. This model can not only takes into account the radius and falloff of the light, but shadows as well; because if the light isn’t visible by the player, the player is in the shadow of that light. Best of all, it’s fully dynamic, supporting moving lights and objects, and doesn’t require custom information on the server. The two previous models we had discussed and discarded were both inferior, and this model required little extra work; so little extra work that I wondered out onto the porch with my laptop that morning, and wrote the code for it in less time than it took to write this diary. Maybe sleeping on the job would be a good habit to get into ;)
