For this week's screenshot, an image showing some of the touch-ups to the "pit" area--specifically, the soil is a little more detailed, and there are now roots hanging in places from the ceiling.
The week just past continued to focus primarily on audio-work--not only in producing the sounds themselves, but also in implementing certain elements. However, a few other things were done, too (such as the roots shown above). Let me elaborate:
Monday, October 9. 2017
Easier than Easy
To start with, the audio work. During the week just past I continued to slowly advance through my list of sounds to be made. (A list which has grown as I've discovered more things that seemed to call for sounds, for that matter.) I even managed to come up with some paper-sounds that I'm reasonably happy with, I think! There are a few such changes that I want to mention individually:
First is the sound used for curtains, because it's entirely artificial. I had tried recording a number of sources for curtain-sounds, but none had seemed to quite work. However, the sound of a curtain is essentially a soft, modulated hiss of fabric on fabric, it seems to me--so I tried generating noise in Audacity, and then manipulating that. It took a few tries, but in the end I came up with something that I like!
Second is the sound played when a "thought" pops up on the screen--or rather, that doesn't. It seemed to me that a simple "prompt" sound might be a good idea here. However, when I tried it I became concerned that such a sound, played often, might become annoying. Not only is this a problem in and of itself, to my mind, I also fear that it might discourage players from "looking" at things (which, when successful, tends to produce a "thought"). Hence, I've decided to leave "thoughts" silent.
Third and final is the sound of pushable- or carriable- objects impacting solid surfaces--such as the former being pushed into a wall. I already had the sounds themselves, as I recall, but for a while the logic for playing them eluded me.
Under Panda3D's built-in physics engine, it's quite easy to be informed of collisions. However, I'm not using Panda's built-in engine, I'm using the engine's bindings for the Bullet physics engine. Under Bullet, detecting collisions is a little more complicated, it seems. If I have it correct, Bullet produces contacts, and may produce more than one per collision, and may further produce contacts on several successive physics-updates. In addition, there seems to be no easy way for me to get at this data for a given object: One can iterate over all contacts in the world, but this seems like overkill, and one can perform a contact test for a specific object, but, whether on Bullet's side or Panda's, much of the data from this test seems to come back as zero.
In the end, I decided to do it myself: On each update of such an object (as long as it's "active" in the physics engine), I examine its current and previous velocities. Using these, I can estimate the impulse applied in the previous frame--if that's high enough, I play an "impact" sound. Thus far it seems to work fairly well!
Moving away from audio, I've made a significant change--or rather, addition--in the combat mechanic. As I recall, I had been reading some of a discussion on Twitter regarding the skipping of content in games, and prompted by this, I gave further thought to the difficulty settings of my combat mechanic. After all, it's arguably somewhat unlike the rest of the game, and I could see some players liking that remainder, but being put off by the combat.
I considered having an "easy" mode that allowed the player to simply "kill" enemies by using the sword inventory item on them. The mechanics for this are pretty much all in place. However, it seemed a little anti-climactic, I think, and also incurred the question of how to stop the player from just walking around enemies.
But another idea came to me: to have an "easy" mode in which combat still happened, but was resolved automatically, with the extant combat AI taking on the role of the player. This (hopefully) allows for some of the impact of the combat mechanic to be retained (and indeed, as things stand it is possible for the player-AI to lose), while allowing players who dislike the mechanic to not engage in it. (And as it turns out, I actually find it kinda fun to watch!)
As I recall, I wasn't confident of how well it would work--I hadn't designed the combat mechanic with this in mind, I believe. However, it turned out to be fairly straightforward to implement! (In part, I daresay, because the enemies largely fight by the same rules as the player.)
Moving over to the visual-art side, as shown above, I've made some touch-ups to the "pit" area of the first level. The more detailed soil texture looks a little more interesting, to my eye, while the roots provide some variety in the ceiling.
As part of this, I made a minor technical change to the player-light shader. You see, the smaller roots shown there are simple flat quadrilaterals. Normally, these would be invisible from one side due to back-face culling--but we don't want that here, and so that feature is disabled for them. However, this complicates normal mapping, as when viewed from behind their normal is pointing away from the viewer.
To rectify this, I now flip the surface normal if called for: I take the dot-product of the surface normal with the light-direction (which comes from near the player in this case). I then multiply the surface normal by the sign of this dot product. Since that sign should be negative when the normal faces away from the viewer, it should flip the normal to face towards the viewer instead--and indeed, it seems to produce the intended result!
And finally, as per usual, there were other changes made that don't seem worth mentioning here!
That's all then for this week--stay well, and thank you for reading! ^_^
First is the sound used for curtains, because it's entirely artificial. I had tried recording a number of sources for curtain-sounds, but none had seemed to quite work. However, the sound of a curtain is essentially a soft, modulated hiss of fabric on fabric, it seems to me--so I tried generating noise in Audacity, and then manipulating that. It took a few tries, but in the end I came up with something that I like!
Second is the sound played when a "thought" pops up on the screen--or rather, that doesn't. It seemed to me that a simple "prompt" sound might be a good idea here. However, when I tried it I became concerned that such a sound, played often, might become annoying. Not only is this a problem in and of itself, to my mind, I also fear that it might discourage players from "looking" at things (which, when successful, tends to produce a "thought"). Hence, I've decided to leave "thoughts" silent.
Third and final is the sound of pushable- or carriable- objects impacting solid surfaces--such as the former being pushed into a wall. I already had the sounds themselves, as I recall, but for a while the logic for playing them eluded me.
Under Panda3D's built-in physics engine, it's quite easy to be informed of collisions. However, I'm not using Panda's built-in engine, I'm using the engine's bindings for the Bullet physics engine. Under Bullet, detecting collisions is a little more complicated, it seems. If I have it correct, Bullet produces contacts, and may produce more than one per collision, and may further produce contacts on several successive physics-updates. In addition, there seems to be no easy way for me to get at this data for a given object: One can iterate over all contacts in the world, but this seems like overkill, and one can perform a contact test for a specific object, but, whether on Bullet's side or Panda's, much of the data from this test seems to come back as zero.
In the end, I decided to do it myself: On each update of such an object (as long as it's "active" in the physics engine), I examine its current and previous velocities. Using these, I can estimate the impulse applied in the previous frame--if that's high enough, I play an "impact" sound. Thus far it seems to work fairly well!
Moving away from audio, I've made a significant change--or rather, addition--in the combat mechanic. As I recall, I had been reading some of a discussion on Twitter regarding the skipping of content in games, and prompted by this, I gave further thought to the difficulty settings of my combat mechanic. After all, it's arguably somewhat unlike the rest of the game, and I could see some players liking that remainder, but being put off by the combat.
I considered having an "easy" mode that allowed the player to simply "kill" enemies by using the sword inventory item on them. The mechanics for this are pretty much all in place. However, it seemed a little anti-climactic, I think, and also incurred the question of how to stop the player from just walking around enemies.
But another idea came to me: to have an "easy" mode in which combat still happened, but was resolved automatically, with the extant combat AI taking on the role of the player. This (hopefully) allows for some of the impact of the combat mechanic to be retained (and indeed, as things stand it is possible for the player-AI to lose), while allowing players who dislike the mechanic to not engage in it. (And as it turns out, I actually find it kinda fun to watch!)
As I recall, I wasn't confident of how well it would work--I hadn't designed the combat mechanic with this in mind, I believe. However, it turned out to be fairly straightforward to implement! (In part, I daresay, because the enemies largely fight by the same rules as the player.)
Moving over to the visual-art side, as shown above, I've made some touch-ups to the "pit" area of the first level. The more detailed soil texture looks a little more interesting, to my eye, while the roots provide some variety in the ceiling.
As part of this, I made a minor technical change to the player-light shader. You see, the smaller roots shown there are simple flat quadrilaterals. Normally, these would be invisible from one side due to back-face culling--but we don't want that here, and so that feature is disabled for them. However, this complicates normal mapping, as when viewed from behind their normal is pointing away from the viewer.
To rectify this, I now flip the surface normal if called for: I take the dot-product of the surface normal with the light-direction (which comes from near the player in this case). I then multiply the surface normal by the sign of this dot product. Since that sign should be negative when the normal faces away from the viewer, it should flip the normal to face towards the viewer instead--and indeed, it seems to produce the intended result!
And finally, as per usual, there were other changes made that don't seem worth mentioning here!
That's all then for this week--stay well, and thank you for reading! ^_^
Trackbacks
Trackback specific URI for this entry
No Trackbacks