Moriash Moreau: My Second Life
Friday, June 30, 2006
Just rolled out the alpha version a new type of monster: a long ranged attacker. The Kneebiter is a small, fast, relatively weak zombie-type monster. Just for fun, I dressed him up in a Cub Scout uniform (costume created by the Boy Scouts of Second Life). He alternates between moaning "BRAAAINS!" and demanding "CAAANDY!"
The main difference here is that he comes equipped with a slingshot. In addition to the normal close-range punch, he also stops every few seconds to fire a rock at the nearest player. Damage is the same as friendly fire from another player's monster gun. Not too overwhelming, taken singly. (Had to keep damage for the monster gun bullets small, or a stray 10-rounds-per-second burst from another player would be fatal.) But they can be pretty nasty in groups.
As you can see from the spatters of black ichor, the Kneebiters have no problem with shooting fellow monsters in the back. Works for me!
I've found that the monster's aim isn't too good against moving targets. This is mainly because I tied aiming into the existing movement system. A couple times per second, monsters scan for their targets, then turn to face them. Since the monster is already facing in the right direction, it's easy to fire a missile at the designated player. Just send the bullet straight forward. The problem comes when the player is running. Since the facing of the monster is only adjusted a few times a second, it's quite easy to move out of the path of the bullet.
I can see a couple of very easy ways to fix this (the simplest being to use a sensor to determine the exact direction to the target at time of fire, instead of using the coordinates found a fraction of a second ago), but I'm kind of warming to the idea of inaccurate shots. This has the effect of forcing the player to keep moving at all times, in order to keep the shooting monsters from effectively drawing a bead on him. Used this way, the bullets are more designed to encourage more active play than to do significant damage. I'll have to see if their aim is too pitiful to be useful for normal play (as opposed to the test swarms photographed above). I expect I could achieve the same effect by using more accurate fire methods, coupled with slower moving bullets. We'll see.
Oops. In the course of looking up a link to the definition for "knee-biter," I found out I was mis-using the term. Apparently, the term I want is "ankle-biter." Oh well, easy enough to fix. And I still think it's an appropriately gruesome term for a kid, in any case.
Went ahead and changed the fire routine to a sensor driven system. They're still a bit inaccurate when dealing with moving avatars, as a running avatar can still move just far enough out of the way to have the bullet land behind him. This could be mostly cured by increasing the velocity of the slingshot's ammunition. Right now, it moves at a paltry 15 m/s. With an avatar moving at a 6 m/s run, it's easy to see how it'd miss. I'll probably tinker a bit with increasing the speed of the shots for the Old Soldier (who will be using a rifle). I think I also see a way to make a rudimentary method of leading the target, by checking the target's velocity vector, and firing ahead of him. That will require some fairly tricky and time-sensitive calculations, though. I'll see if it's worth it.
Earlier this afternoon, I sent myself a reminder e-mail. Nothing too unusual about that. I often dash off a quick message to my personal address from work, as a reminder for when I arrive at home. I have my work e-mail rigged to check my personal mailbox, too, so I always receive two copies of the reminder: one at home, one at work. Kind of handy.
A few minutes ago, I received a copy of the e-mail I sent myself after a lunch hour programming session on the Garage of DOOM. Subject? "Change blood spray and ichor to follow source."
Y'know, I'm really kind of a weird dude sometimes.
Wednesday, June 28, 2006
Play Testing, Part 1
...Of 5,217, no doubt.
First, I want to send my thanks to Will Webb, both for helping me find all the bits that stopped working during the elevation changes over the weekend, and for putting up with my general ill temper and overall bitchiness during the process. (I meant to say this in Monday's update, but ended up getting sidetracked. Mea culpa.) Will has been indispensable as a beta tester and sounding board throughout this project.
Now, on with the update. Last night, I managed to squash a irritatingly unpredictable bug in the monster rezzing routines for the Garage of DOOM. Every once in a while, a monster would rez, and then just sit there staring straight ahead and doing nothing but block the rezzer. Vexing. Turned out to be a listen statement that was not triggering, in combination with the roll call system and the initial target information sent by the rezzer. Basically, I was a bit overzealous in closing off unused llListens. (Have to be lag conscious in the design of my scanning, chat-spewing, self-guiding physical monsters, don'cha know!) If the roll call information (the list of the keys of the current players) came through at exactly the wrong time (between the time the monster is rezzed and the key of the first target is sent to said monster), the llListen command waiting for initial marching orders would be killed prematurely (it is only supposed to listen for one command, then remove itself), and the monster would just sit there in standby.
I know, that's not terribly interesting, but it illustrates a point. I fully expect to run into all sorts of odd synergistic effects between the various systems. I suppose that's one of the hazards of this kind of build-as-you-go programming. I have all sorts of different subsystems doing any number of things at a given time, and it's often hard to tell what will interact with what. I really need to learn a little discipline in my programming, and plan these things in advance. But it's so much easier, not to mention more fun, to just wade in and start grappling with it right away.
Last night, I also did my first real play testing under realistic game conditions. This means playing the game straight, without Edit "God Mode" monster deletions and with a realistic number of power ups, until I die. Unfortunately, it appears that the game is far too easy as it stands now. Granted, I've got a bit of an edge, since I've been playing with it from the beginning. But even given that, it should not be possible for me to last 10 to 15 minutes without losing more than half my health.
As expected, this is going to be tough to balance. It would be easy to simply overwhelm the player by making rapid-fire swarms of unstoppable killing machines. And I'll definitely be nudging the game more in that direction. That was my intent all along, and it's only been my general timidity about LSL and simulator stability that's been holding me back. But the real challenge will be to make the game more difficult in an intelligent fashion. It's easy to cook the game to be unbeatable. It's harder to make it challenging, yet playable enough to encourage folks to come back.
I think one of the major issues is movement. As it stands now, many of the monsters move too slowly. I want that for some of them. Traditional zombies are slow, implacable horrors. But, as it stands now, most of my ghouls can be outrun at a walking pace, and none can keep up with a running player. Ideally, I'd like to tune the game such that a player is never given a chance to stand still and offload on one specific monster. Part of that is assured by the layout of the monster generators. There is no place a player can safely stand for extended periods in order to pick off targets from a distance. Ideally, fast monsters should move at a running pace (6 m/s), or perhaps a bit faster.
The other issue is damage. With the exception of the Jack o' Lantern (which explodes, damaging everything in a 7 meter radius), the monsters must be within a meter or so of the player to strike him. So it's easy for a player to use his superior agility to run circles around them. Ultimately, I'm going to have to introduce fiends with ranged strike abilities.
Enter the Old Soldier. He's a zombie type, slow moving and tough. But he's dressed in an old WW2 military uniform, and holding an M1 Garand rifle. He moves very slowly, and periodically stops to fire a few rounds of the same bullets fired by the player guns. This works neatly with the existing friendly fire system, and effectively removes the safety of range. (And if he manages to wing a few bad guys standing between him and his target, so much the better.) I'm thinking the Old Soldier will not use the conventional death effects of the other zombies. Instead, I think I will have him become dimmer and more transparent as he takes damage. Because, of course, Old Solders never die. They just fade away.
Ha! I slay me! More to come.
Monday, June 26, 2006
Yesterday, I completed a step I was somewhat dreading: moving the garage to 1500 meters elevation. And, as it turned out, I had every reason to dread it.
I'll spare you the play-by-play of mishaps. In general, they involved multiple iterations of testing, flying up 1500m, checking coordinates, correcting mistakes, editing notecards, flying down again, relaunching, and repeating. Over and over and over again. There was occasional swearing involved, as well as multiple open-palmed blows to the forehead. In short, not fun. I've had fun. I've come to recognize it. This? Not fun.
But I did learn a couple of interesting things. First, llTriggerSound and llTriggerSoundLimited do not work above 1024 meters. llPlaySound and llLoopSound appear to work properly, but for some reason triggered sounds just refuse to play. Very, very odd.
The problem with this is that the monster gun and most of the monsters use llTriggerSound for sound effects. The trick is the way the two commands operate. Triggered sounds can overlap, while sounds generated with llPlaySound can't. The latter would, for example, not work very well with a machine gun. Only the first report would be heard. So, long story short, I was forced to move the entire structure down 500 meters. And then recheck all my figures and correct. Ad nauseum.
Of course, this led to other problems. One of the main benefits to building at 1500 meters was that I didn't have to worry about appearance. I could have an enormous, unadorned concrete building floating in mid-air without cringing every time I looked up. But now, at least with the normal max-altitude builds, it's visible to many users. It sits right at that oh-so-annoying edge-of-view at the corners of your vision triangle. If you hadn't noticed, you can see further on the edge of your client window than at the center. (Check the vision cone on the mini-map, and you'll see.) Sometimes, this is handy. But usually, having a giant building creeping in and out of the corner of your eye is pretty dang irritating.
And since I'm kicking in land for a build that (someday, I hope, eventually, maybe) will be built at 742m, and directly under one corner of the Garage, this is going to be an issue. Nothing kills the end-of-the-world feeling of isolation of a high altitude build like a giant tan warehouse hovering in your peripheral vision. For now, at least, I've addressed the problem by killing off the entire structure 10 minutes after the last avatar leaves, then automatically rezzing it anew next time it's needed. Kind of a hassle. But until the sound bug is fixed, it'll have to do.
I've also run across some issues with llSay and llWhisper ranges at high altitudes. I haven't run any formal tests, but they both seem to have shorter ranges there. Someday, when I get bored, I'll do some more rigorous experiments to verify the behavior. Until then, I've had to brute force a few messages, by switching to the next "louder" channel (llWhisper to llSay, llSay to llShout). This is invisible, but it does generate a bit more script load, as irrelevant messages from across the arena must now be filtered. I guess we'll see if it makes a difference.
Friday, June 23, 2006
Quick Status Report
Well, I've sorted out the security cameras in the entry lounge/security room. They now swap between four different fixed camera views corresponding to four security cam domes in the garage. Not a terribly useful feature, but kind of neat, nonetheless. And it gives non-participants a way to view a game in progress without getting in the way.
Also took a few minutes to make some traffic direction arrows for the garage. Just to be evil, I rigged them to periodically change directions. Each arrow changes in a slow, random interval: long enough to escape immediate notice, but short enough that arrows will often have changed from one glance to the next. It took me a bit to come up with arrow combinations that are nominally plausible (no arrows directing drivers to steer into a wall or anything). Mind you, many of the random combinations would cause head-on collisions with oncoming cars, or left turns across an opposing lane of traffic, or other dangerous configurations. And no arrows will ever point back out of the garage again. (Symbolism!) This will have zero effect on the game itself, of course. It's just part of the garage's dubious charm.
Slowly but surely making progress here. More to come.
Thursday, June 22, 2006
Three Faces by Candlelight
A woman with a sword, an anthropomorphic wolf, and a little woman with a big purple hat gather around a candlelit table in a ballroom 500 meters in the air. Just another night in SL.
Sometimes, I really love this game.
Wednesday, June 21, 2006
Sound and Fury
I've spent the past couple of evenings working on the entry lounge for the Garage of DOOM! Basically, I'm going for a typical small office building security office. Well, actually, I'm going for as-few-prims-as-possible chic, but with a general security office theme. So far, I have a plain little 8x8x4 room with a desk and a few chairs inside.
The desk holds a couple of black-and-white security monitors that show scenes from the four corners of the garage (one via a four frame animated image, one with a static texture displaying all four tiled onto the screen). I plan to add basic camera controls to the desk, allowing people sitting at either of the two desk chairs to observe the action inside the garage. The chairs will include four fixed camera positions, one in each corner of the complex, selected with the direction keys. At least, that's the plan.
I've also completed the down-transport system. It's a simple wooden chair that carries the player back to the ground. Or, if he prefers, he can simply open the back door and fall the 1.5 kilometers to the ground. It doesn't really matter which. And freefall can be quite relaxing after a life-and-death struggle with the undead.
A largish bulletin board has been placed on one wall of the security room/player lounge. For now, it's blank. Eventually, it will contain information on the monsters, power-ups, and so on. I'm of two minds about how much data to include on that, though. I'd originally planned on posting data on offense strength (in general terms, like "Low" or "Massive"), defense strength (same), and special abilities (flight, insubstantial nature). But I don't necessarily want to give away everything right off the bat. And I doubly don't want to have yet another impediment (development time for new game documentation) for game improvements.
I'd planned on getting a little work done on all this during lunch today, but I forgot about the grid update. So, instead, I spent my lunch hour finding and processing moans and groans. I've decided that the monsters are entirely too quiet. This is kind of bland, and also makes things a bit too difficult. For the most part, these creatures aren't of a type that should be able to sneak up on you. Zombies aren't known for their ninja-like stealth.
Each of the zombie types (ultimately, there will be four) has a set of three different moans. Newbie Zombie has regular, masculine sounding groans. Coffee Zombie has kind of dopey, tired sounding moans. Mall Zombie has three different groans in a higher register, including one 7+ second long aria of uncertain warbling that cracks me up every time. And the Kneebiter has the same moans as Newbie Zombie, only sped up about halfway to chipmunk speed. Each of these sounds will occur at random intervals, coinciding with the already included randomized chat channel lines.
Skeleton zombie will now have a soft, looping sound of rattling bones. The Rippers have had whining saw blades from the beginning. I'm not altogether certain what kind of noise the Jack o' Lanterns should make while in flight. What sound does a flying pumpkin make? I'm leaning toward a crackling flame sound, to go with the half-meter long torch particle effect, but I don't know if that will be sufficient. In early playtesting, I've found that I lose a considerable amount of health to unnoticed pumpkins exploding behind my back. I'd not really intended the Jack o' Lanterns to be quite so lethal. But I suppose that's a matter for playtesting.
I've created a couple of rasping/hissing sounds for the Vampire, including one that was originally sourced from a recording of a gila monster. But I'm not certain if they're really appropriate. The Vampire may stay just silent. I know that the Wraith will do so. That's part of the whole theme. The only time it makes a noise is when it's attacking.
My concern is whether anything can be heard during normal play. It's quite tempting to just run about with the machine gun chugging away (one argument for ammo limits, I guess). I've found that it's often difficult to hear the monster dispensers cycle (they make kind of a roaring/screeching sound when a new monster is rezzed). This early warning system is fairly important for long-term survival, especially when a monster appears right behind you. I'm going to have to come up with incentives to lay off the trigger from time to time.
Monday, June 19, 2006
"But what do you call it?"
It's been something like seven or eight weeks now, but I'm still stuck for one of the most basic components of my "low-rent survival-horror FPS." (Best description I've heard so far.) I don't have a name for it.
The working title is "Monster Machine," but that hails from the early days when this project was built around a single, central device (presumably a product of malign science and/or occult perversion). I envisioned something with lots of copper and rivets, engraved with unnerving symbols and emitting glowing green fog. But now that I've moved the whole shebang into a modern parking garage, and my central server is a manhole cover (and not even a particularly evil looking one, at that), it doesn't really work anymore.
Right now, I'm leaning toward the generic, but descriptive, "Garage of DOOM!" It defines the narrow scope: you, the garage, and... DOOM! And it pays proper homage to the venerable old computer game that inspired many aspects of the project. But I'm not terribly enamored of the name.
If anyone out there can think of a better title, please drop me a line in the comments. If I like it, I'll be sure and give you credit in the game docs.
Game Status Report
First off, hello to everyone coming here from New World Notes. Thanks for sending folks my way, Hamlet!
Now, on with the status report. Sunday was a fairly productive day. I believe I have the HUD substantially complete. After nearly an hour of correcting stupid math errors and fiddling with floats vs. integers, I finally managed to get all three numeric readouts to update properly. I'm an engineer. I work with numbers every day. Math should not be this hard! Heavy sigh. Disheartening. Oh well, I'll be able to use the same tech for future projects, so I can't consider it time wasted.
Anyway, the numbers tick off quite nicely now. I also took the time to fix up the baked on shadows for the ceiling light fixtures. Nothing too sophisticated, especially by current SL standards, but I think it's sufficient. I was going for the washed out, grungy, monotonously-lit appearance of a modern underground parking structure. Mission accomplished, I guess.
My methods certainly weren't sophisticated, in any case. I just made a fuzzy rectangular blob in Photo-Paint, put it on a flat prim between an un-shaded ceiling segment and a prim fluorescent light fixture, and snapped a screenshot. The shading on the walls (the slight arc-shaped shading near the ceiling) and the columns (somewhat dimmer at bottom) was done the same general way. Sometimes the easiest methods are the best. Especially when your p-shopping skills are as rudimentary as mine.
I'm still trying to decide if I need further decoration to make the garage work. I probably should add some traffic arrows, assuming I can figure out how traffic flow would work in this messed up lot layout. I'm guessing the ghosts in the game are the enraged spirits of tenants killed in traffic accidents at the garage entry. There's a plotline for you: "The combined psychic onslaught of hundreds of angry, frustrated drivers a day tore a rip in the spacetime continuum, loosing the forces of evil upon an unsuspecting city..." Of course, if that kind of thing really happened, I can think of a couple dozen intersections, freeway interchanges, and mall parking complexes that'd be hip deep in zombies by now.
Come to think of it, most of the more successful shopping malls are already overrun with the shambling undead. Especially around Christmas. I should partner up with a butcher and open a special holiday BRAAAINS! concession stand at the Galleria this year. I'd make a mint! But I digress. Frequently.
There are technical and narrative arguments both for leaving it alone and for festooning it with graffiti. Technically, there's the matter of additional textures. And, given the load times for yet another max resolution texture (so they don't look fuzzy when stretched over a 10 meter wide prim), that's a real issue. But it would break the monotony of the uniformly painted, 60m long walls. I just don't know if I want the monotony broken. I can't decide if the sudden appearance of monsters is more jarring and disconcerting in a grim, rundown, graffiti-decorated building, or in a clean, well-maintained one. I suppose the look-and-feel details can wait until the mechanics are completed.
After some minor revisions to the monster damage tracking system, the Berserker Pack code is finished. Here's the visual effect. As you can see, a red filter has been added to the HUD. This filter is actually two counter-rotating, semi-transparent, mottled red prims. The net result is a slowly changing red film in front of the player's eyes (or covering his screen, anyway). Kind of like looking at a red lava lamp from three inches away.
But don't do that. You'll burn your nose.
A player goes Berserk for 30 seconds after picking up a Berserker Pack. The red filters expand (they're normally invisible and hidden behind the HUD) to cover the screen, and the life indicator icon turns red. (The icon will flash red and white for five seconds before the power up expires.) During this time, the player can't be hurt.
He also gains the ability to kill any monster he collides with, by delivering a mighty, adrenaline-fueled left cross. (Had to drop the one-two punch, because slashing at monsters with the barrel of the rifle in the av's right hand looked a bit odd.) As you may remember, I'd originally intended to make the punches roughly equivalent to 10 bullets (one point-blank blunderbuss salvo). This is very powerful, in the scope of the game, but would still require multiple collisions to kill tougher monsters.
In practice, I found that SL steering is too unwieldy to guide an avatar in for multiple collisions in a reasonable amount of time. Avatars are designed for ease of movement, not precision maneuvers. In this case, the player would spend all his time in eccentric orbits around your target, trying to calculate a return trajectory to finish him off. Quite frustrating. So, instead, we have a one punch, one kill system. It's much more satisfying to just run over the monsters and have them go down, anyway. And the required modifications to the monster health tracking systems open the way for future power ups, like enhanced weapons (rocket launchers?) and mines.
The Holy Hand Grenade effect has mutated a bit since its conception. Originally, it was going to be a conventional thrown grenade. In practice, though, it was too easy for the grenade go off at at the player's feet, or bounce off into a corner. I tinkered with various ideas, such as having the device explode on impact with ground and/or monster, or having it home in on the nearest baddie, but ultimately I settled on having the effect centered on the player. This makes aiming relatively easy, especially if he switches out of mouselook.
So, we're left with the effect above. I created a simple custom animation for the effect. When a Holy Hand Grenade is activated (either by typing "h" in the chat bar or clicking on the grenade icon), the player's avatar rises a meter or so into the air, head thrown back and arms outstretched. Heavenly organ music plays, and a ring-shaped blast of white light explodes outward, destroying every monster in its path. Perhaps a bit heavy on the anime melodrama, but it works.
The range on this attack has doubled since the last time I mentioned it. In particular, it changed from a 10m to a 20m radius. Basically, I switched from using llWhisper (with its ~10 meter audible range) to llSay (which is audible for ~20 meters, just like regular chat) to issue the "monster die" command. (This is the same command the central server uses to clean up the field when the last player dies, although it uses llShout's 100m range.) I found that it was too easy to underestimate distances with the 10m range. I'm going for overwhelming, but still requiring a minimum of advanced planning and strategy (at least of the "wait for it... wait for it... now!" type) to use. This seems like a reasonable enough balance between the two.
So, save for debugging, playtesting, debugging, balancing, and debugging, the game itself is complete. Next comes the entry area, information kiosk, documentation (ugh!), teleportation system, and high altitude construction scripts. More later.
Saturday, June 17, 2006
And the HUD
And now, weighing in at 39 prims of pure shiny... The Monster Machine HUD!
This thing turned out much better than I expected. The heart icon turns into a skull-and-crossed-bones when the player dies/is out of play. Eventually, when the scripts are complete, the clock readout will display elapsed time in minutes and seconds. If folks somehow manage to go over 99:59, well, they really need to find another passtime. Either that, or they're cheating their asses off. Eventually, I'll need to put in some more work on the high-level game to deal with excessively long playtimes. Maybe I need to either build in a victory condition, or go the old Atari 2600 route and have the game speed up until it's too fast for a human to play (unsatisfactory, but easy). I'll burn that bridge when I come to it.
Still have to complete the scripting for time, health, and grenade readouts; write the Berserker code; script the Holy Hand Grenade; create the entry lounge and game information kiosk; come up with a high-altitude rezzer that can rez a building this large at 1500m, and make a high score system. And work out a couple of maddening, recurring bugs. Long way to go.
Friday, June 16, 2006
And here are the power ups (at least for now). From left to right we have:
- Health Pack - Restores player health, to a maximum of 100%. Shiny, slowly rotating sphere.
- Berserker Pack - Makes the player "berserk" for a brief period. When berserk, a player is invulnerable, and delivers a mighty one-two punch to any monster he touches (doing as much damage as 10 bullets). Notably, the player cannot damage insubstantial creatures (such as Wraiths and Poltergeists) with a berserker punch. Could be a problem, as the player could be left with a concentration of fast, hard to kill monsters after he comes down from his berserker rage. Translucent black sphere with red-black particle effect.
- Grenade Pack - Gives the player a Holy Hand Grenade. When used (via chat command), it acts as a smart bomb that destroys all monsters within range (about 10 meters) without damaging players. Modeled after the Holy Hand Grenade of Antioch from Monty Python's Search for the Holy Grail by Will Webb (who is also acting as beta tester, brainstormer, and general sounding board for the project). Thanks, Will!
All told, the power up system came together surprisingly quickly. The chat damage system used by the monsters proved to be very easy to expand to include power ups. Currently, monsters deliver damage by saying the damage and the key of the intended recipient. If a player HUD hears the key of the player, it knows to apply the indicated damage to the life total.
Given that system, making health packs was a snap. The packs simply deliver negative damage, effectively increasing the life total of the target. The other two required a couple of extra if-thens. If the damage total is a specific amount (512 for the Berserker Pack, 513 for the Grenade Pack), the HUD knows to bypass the damage system and trigger a specialty power up routine instead. It should be easy enough to add other power ups as they occur to me.
A few different people have suggested that I make an invisibility pack. The way to do this would be to broadcast a false key to the central server when it calls for a roll call. The monsters will only seek players whose keys are listed on the active roll call list (which is broadcast every 6 seconds, currently). The power up could trigger a roll call immediately, then tell the HUD to broadcast a nonsense key. This would have the result of keeping all the monsters active (the server kills them off if there are no keys on the roll call list), but unable to find any players to hunt. For a single player game, that's fine. The player would just have a bunch of stationary targets to shoot at. But for a multiplayer game, the power up would effectively be a "screw your fellow players" button. All of the monsters currently seeking the invisible player would suddenly go after the nearest visible players, instead. Given that this is nominally a cooperative game (players vs. the monsters), this is a sub-optimal result. I'll keep it in mind, but I'm thinking invisibility won't be an option any time soon.
I forgot to detail how the power ups are dispensed. As mentioned before, they have a small, random chance of being released every time a monster is rezzed. As such, more power ups are dispensed when more players are in game. Seems fair, given that the monster rate is also increased.
The power ups are rezzed from the same dispensers as the monsters. They are initially invisible. Each dispenser is turned such that its positive-X direction points toward the center of the arena. The dispenser knows to rez monsters to match this direction. This gives the best chance of rezzing the monster facing (at least generally) towards the players. (Mostly because it looks a bit silly to have the monster appear with its back to you, only to laboriously turn around as it bumbles toward you.) Now, on rez, the invisible power up checks its current X direction, and moves a random distance (from 2 to 12 meters, in one meter increments) along that same vector.
Then it parks itself and waits for the next player roll call. Once a player list is received, it reveals itself (turning visible, turning on particles, etc.) and waits for an avatar collision. If 60 seconds pass, it disappears. But if an avatar whose key is on the active player list collides with it before that time, it fires off its code string, plays a little power up sound effect, and vanishes. And, voila, we have randomly appearing power ups.
My next task is to finalize the HUD itself. Right now, it has functionality to change player status: dead/out-of-play or alive/in-play. It can also track health, and arm/disarm the gun when entering or leaving play. Ultimately, my plan is to tie the HUD into the teleport system that brings players in and out of the garage. The HUD will automatically switch to "live" mode when the player enters. This will signal the HUD to arm the gun, start the play timer (there is no score, only an elapsed survival time), and begin to call for monsters. When the player dies, the HUD will deactivate and summon a teleporter device to leave the arena. (He can also use the exit door to teleport out without dying.) In either case, the play timer will be stopped, and the timer will broadcast the elapsed time to a scorecard device somewhere. Honestly, the high score system is my lowest priority right now.
I'm still tinkering with the design, but I know the HUD will need three different readouts: Health (percentage), Elapsed Time (in minutes and seconds), and Grenade Count. As easy as it would be to work in llSetText, I think I'm going to have to use a prim numbering system. I've found that llSetText in a HUD can be unpredictable and hard to format, since it changes sizes based on the screen resolution (or, rather, doesn't change size, but the HUD and client changes size around it). It might be possible to come up with a scheme that allows for differing sizes of floating text, but it would be difficult. At the moment, I'm leaning towards a retro-styled rolling number scheme, with lots of brass and copper toned fittings around it. I guess we'll see if my artistic skills are up to the task.
Wednesday, June 14, 2006
The Shape of Things to Come
Oceanfront Property in Arizona
This evening, while doing a little scripting work, I got quite a shock. It all started at 3:38pm game time, when I received the following instant message:
Second Life: Your object 'Big River Rocks' has been returned to your inventory lost and found folder by 'Eric Linden' from parcel 'The Garden of Mo' at Louise 255, 225.
This was followed immediately by another dozen or so random objects: rocks, trees, prims labeled "land," and so on. At first, I was gripped with a moment of panic. "Was there a problem with my billing? Are they repossessing my land? I've got to stop them before everything is demolished!" But, before I could react, the barrage of system IMs stopped, well before they reached anything irreplaceable.
(Yes, I know, Lost and Found folder. But many of my larger builds would arrive there as a disorganized clump of random parts, as good as lost if they were returned to inventory in a haphazard fashion.)
Eventually, I recognized the names of the returned objects as components of my oceanfront improvements at the east edge of the grid. But that still left the question of why they were returned in the first place. Thinking that, perhaps, I had run afoul of some new policy against extending objects off the edge of the grid, I flew to the east coast of Louise...
And got another surprise. What the hooping heck? I'm landlocked! My familiar ocean view had disappeared, to be replaced with low, rolling hills. Say what?
As I got closer, I noticed a figure hovering on the Louise border. It was Eric Linden himself. Unfortunately, as I noticed after the first tentative chat attempt, he was in Busy mode. Guess I can't blame him. Looks like he was, indeed, quite busy. The entire coastline for several sims in either direction had to be terraformed to match the new landscape.
Eric left a few moments later, and I flew up and down the coast to survey the change. To my relief, it appeared that the land was initially terraformed by the Lindens to match the adjacent geographic features. Your opinions may differ, but many of the mainland sims terraformed solely by the buyers are... Well, not terribly aesthetically pleasing, to put it kindly. (Or baboon-butt ugly, to put it not-so-kindly.) Take a look at some of the peninsulas on the northeast and southeast corners of the mainland, and you'll see what I mean. It's often very clear that the sims were designed to be chopped up and sold as fast as possible. There were some reasonably nice ones created during the bulk land auction experiments. But most, not so much.
After 20 minutes or so, I returned to Louise and contacted Live Help to see if they had any news. Helper Eric Boyer went to great lengths to contact a Linden in the know, but ultimately was stymied by my inability to enter the new sims and find out their names. (The new sims were all locked, preventing outside entry by non-Lindens such as myself.) And, since they didn't yet appear on the map, I had no way of finding their names. The best advice they could give was to wait and see what happened.
As I was thanking Boyer for his attempts, I happened to look back at my eastern coastline, and found the new sims had disappeared as mysteriously as they had come. All that was left was the knife-edge of a newly terraformed coastline and a familiar expanse of endless, inaccessible ocean.
I feel quite certain that the sims will return, and fairly quickly. And, in the interim, I'm looking for upsides to the inevitable change in the local geography. I had several months with the end-of-world real estate, and it would be silly to expect that the straight line of sims on the east coast wouldn't be expanded upon eventually.
The loss of my coastline forced me reclaim a hundred-some-odd prims from my coastal beautification project. This will let me add that much more detail to the monster garage project. My land value has been lowered somewhat, since it's suddenly no longer end-of-world waterfront. (I feel sorry for the folks to my north who are using that as a selling point for their vast tracts of otherwise unremarkable land.) But that doesn't really matter to me, since I don't intend to sell it. I've been in Louise for 18 months, and I don't see leaving any time soon. So who cares what my property values are? It's not like I'm paying taxes on it!
It'll be interesting to see how the local landscape and economy changes now that we're effectively further inland. Should increase the fly-by traffic, in any case. This is both good and bad. I enjoy having visitors from time to time, but our relative isolation has always kept Louise quiet and residential (give or take my humble shop and the occasional short-lived club). Guess I'd better brace myself for the change.
Still, all told, it makes me wish I'd spent more time with reflective water enabled. I'm going to miss my little slice of the virtual briny deep. More to come as things develop.
Well, the new land arrived last night. Vexingly, the nice, gentle downward slope has changed into a rather obtrusive hillock blocking my view even further. Which may be a blessing in disguise. As Will speculated last night, it is quite likely that a good portion of the new sims will be designated first land. So maybe I'll be saved the epilepsy inducing texture flicker of newbie builds as far as the eye (or the clip plane) can see. I know, we all have to get that out of our system before we develop the pride, experience, and competence necessary to pay attention to overlapping prims, but nobody should be forced to watch those traits develop.
Unfortunately, my haste to terraform my plot to fit the new neighbors had unanticipated consequences. Apparently, the terraforming done on the edge of my sim (and I assume the adjacent sims as well) required exceeding the 4 meter limits. When I tried to smooth out the 2m wide strip next to the border, it suddenly dropped a few meters (presumably to the maximum terraformable height for mere players on this sim). So, now I have an unrepairable meter-wide, multi-meter deep triangular ditch running the width of my east border. I guess all I can do is wait until the new sims are opened (their borders are still closed, as of yesterday evening) and see what falls out. My guess is that the median land height at the borders will eventually be changed to be more consistent with the neighboring sim. Failing that, I should at least be able to file a land repair request on the forums.
Woot! I don't know if someone saw this blog post, or if it was just noticed during the course of normal work, but the giant triangular ditch is gone! Big thanks to the Linden staffer who took time out of his or her day to correct my screw ups for me. I promise I'll leave it alone until the new sim goes live.
And the new sims are gone again. What the heck? I guess they were hung up in auction. We'll see.
Tuesday, June 13, 2006
Monster Machine, Update
As I mentioned before, I am tinkering with a first person shooter inside SL. I'm making slow progress toward a working game. I know enough about game design not to give a release date, but I think I can commit to "soonish."
I finally got around to finishing several walking monsters. As mentioned before, I decided to go ahead and make/obtain in-game avatars for these. This makes it easier to create art for front and back views (simply turn the model 180 degrees and snap another pic), an makes it easier to make matching action poses using built-in animations. These turned out pretty well, for what they are (floating static cut-outs). Attacks are simple one-frame affairs. Each monster texture (remember, there's one for front and back) is actually composed of two frames: the basic standing/walking pose, and an attack pose. When a monster attacks, it switches to the attack pose briefly. Usually this is a picture of the avatar in mid-punch, although the Skeleton has both punch and kick. This is mostly because these were the first images I created. In testing, I found that it wasn't worth making a kick pose when the image could not be seen, such as in Mouselook, where the avatar would only be able to see the monster from the torso up. So, ultimatelty, each monster required four different images, and a little photoshop work to glom them together properly.
From left to right, we have:
- Wraith - Faster than other walkers, and intangible (which means it can bypass impediments like other monsters, but can still be hit by bullets). Becomes less visible as damage increases. Has black, smoky particle effects that change to red fog briefly when the monster is hit. I made the avatar (such that it is) myself, with the aid of photoshop to fuzz the edges. Homes in on one specific player.
- Skeleton - Basic cannon fodder with no special abilities. Makes bone rattling noises when attacking or when damaged. Awesome avatar purchased from YadNi Monde. Goes after whichever player is nearest.
- Newbie Zombie - More cannon fodder. Punches are accompanied by meaty thuds, and damage by sprays of black ichor. Alternates cries (in chat) of "BRAAAINS!" with stereotypical clueless n00b lines like "WHERE U GET MONEY?" and "U WANT CYBER?" (Don't get me wrong, I don't have anything against most newbies. But you've almost certainly met the type I'm lampooning here.) Laura Ingersoll's custom created zombie av strikes the right balance between gruesomeness and gormlessness. Goes after the nearest player.
- Coffee Zombie - Just like the Newbie Zombie, but cries out for "COFFEE!" Also slightly faster due to the caffeine infusion. Goes after the nearest player.
- Vampire - Same combat effects as the Newbie Zombie, but somewhat faster. Goes after a specific player. Avatar by yours truly. Regenerates damage over time.
I may have a few more, eventually, including female zombies (dressed in the latest fashions and accessories- haven't decided between "Mall Zombie" or the more obscure roleplaying joke, "Spawn of Fa'Shun") and child zombies ("Kneebiter" always sounded like a particularly ghoulish term for a kid). Maybe a couple more, if ideas strike.
Fortunately, I took the time over the weekend to make it easier to add to and modify the monsters. The monster dispensing system is divided into three general parts: player HUDs, a central server, and a system of remote monster generators. (The first two serve other purposes, as well.) Basically, the HUD sends out a call for a monster to be dispensed. The server hears the call, notes the owner of the HUD that called it, and signals a random monster generator to spawn a monster. The generator does so, and tells the monster who its initial target is (if it is a player specific type).
Initially, I had the monsters loaded into each of the monster generators. So, in order to change or add a monster, I had to edit each and every generator. Quite cumbersome for testing and tweaking purposes. Finally, after the Nth time, I wised up and moved the monster dispensing system to the central server. Now, the server sends a random monster to the monster dispenser, which has the sole task of rezzing it. This made things a little bit more complex, but will pay off hugely in efficiency down the line. Now, I only have to edit one object (the server), no matter how many generators are ultimately used. Currently, I'm using eight of them, spaced evenly in a rough circle around the arena (see below).
And it also lets me easily tweak monster distribution and create special events. For example, right now I have two general types of monsters: walkers and flyers. The server has a 50/50 chance for picking one of each. But I can easily change this balance by changing a single variable. And, down the line, I can add boss monsters, power-ups, special events (such as swarms of a certain monster type- the Rippers are a lot of fun in swarms) and so on, simply by modifying a single script. Quite handy.
Here is another shot from the inside of the arena. My plan is to ultimately build it at 1500m or so, both to keep the massive 60m x 60m x 7m structure out of the way and to take advantage of the superior frame rates at high altitude. I typically get something around 12-15 FPS at ground level, compared to 30-35 FPS at the SkyLounge. (Boy, I've gotten a lot of mileage out of what I learned from that little project. I guess you never know what's going to turn out to be a vital bit of educational experience.) It helps when the client doesn't have to render another prim for a couple thousand meters. The scripting to rez this huge structure by remote control will be interesting, but it's well worth the trouble.
In order to make this all work, I needed a large, open, enclosed area to contain the monsters and players. It had to have a roof, to prevent players from easily flying out of range of ground-bound threats. This is aided by building well above the unaided flight limit. Flying players simply skim along the floor. This can be a handy strategy for fast, if clumsy, dashes. And if someone wants to use a flight assist to bump along the ceiling, well, that's up to them. I feel no need to complicate things to deal with the issue.
I suppose if it becomes a real problem, I can always skew monster distribution towards flying types if the player insists on hovering. Given that these seem to be the most lethal varieties (Rippers are fast, Poltergeists fly in an unpredictable spiral, Jack o' Lanterns do massive damage- and all are a small targets), I'm guessing that this would break the habit fairly quickly.
As you can see, I settled on a large, indoor parking garage. For narrative purposes (and so I don't need to waste prims making windows or fences), I'm calling it an underground structure. Thanks to Laura Ingersoll for the idea. (I agree: giant, enclosed parking structures are inherently spooky at night, even when well lit.) I'm still working out some of the ins-and-outs for the baked-on lighting and shadow (especially for the ceilings, around the fluorescent fixtures), but I'm fairly happy with the way it's coming out so far. Now I just need to come up with a name. Unfortunately, "Monster Garage" is already taken.
At the suggestion of Will Webb, semi-official beta tester, I've added some columns to the garage since this picture was taken. Unfortunately, as much as we'd both like to see them, I don't see a way to add cars. They're just too much of an obstruction. After some initial testing, we found that the monsters can successfully navigate around columns and even cars, but they look especially silly doing the latter. We bandied around various ideas, but I think I'm going to back burner the car issue, for now. I don't really see folks parking their prized BMWs overnight in a garage populated with zombies, anyway!
I finally got around to making a better model for the game gun. It's kind of an oddball combination of magic and steampunk-esque technology. (Nods and thanks to Ordinal Malaprop and her Clockwork Blunderbuss for inspiration. I hope it's sufficiently different from her superior device to avoid being a complete ripoff. And, while we're at it, this project also owes quite a bit to an hours-long session shooting Steel Pigeons that sparked some of my earliest ideas for the game.) As discussed in the previous report, the gun has two fire modes: machine gun and shotgun. Or, to fit the more retro feel, Automatic Rifle (top) and Blunderbuss (bottom). The gun swaps types with a voice command. The green gem inset in the stock glows and slowly rolls an animated jade texture (which does nothing but look perty), and the large drum on the bottom adequately hints at/explains the unlimited ammunition. I suppose it wouldn't have been too difficult to add limited ammunition to the game, but it didn't seem necessary. And unlimited bullets add to the therapeutic effect. Given that I'm building this primarily to blow off steam after a hard day's work, I want as few impediments between me and shootin' baddies as possible.
Next, I plan on adding a duplicate health readout to the gun. Currently, it displays a "GUN DISARMED" notice when not in play, but it should be an easy enough matter to expand the display to include player health. This duplicate readout allows other players to judge your current status at a glance.
I also have plans to add various power-ups to the game. I think I can add that to the improved server system with a few modifications. Some small percentage of the time, a power up will be rezzed along with a monster. Said powerup will be a short-lived object that applies its effect and disappears upon collision with a player.
Stimpacks/first aid kits are easy enough to implement. The entire damage system is based around chat commands carrying the damage amount and the key of the recipient. Healing is simply a matter of applying negative damage. A booby trap (perhaps an old style bomb with burning fuse) would be just as easy.
The DOOM and Quake style Berserker Pack seems like it should be fun. Mechanically, it's not that complicated. (Actually, nothing in this project is all that complex viewed singly. It's the combinations that keep tripping me up.) For a brief time, the player stops taking damage, and does damage upon collision with monsters. (Perhaps he throws a one-two punch, too.) Just for the look of it, a portion of the HUD will expand to cover the player's screen with a semi-transparent red pane. Should be kind of neat.
And as I write this, the to-do list gets longer and longer. More later!