Monday, April 28, 2014

Coffin / Ludum Dare #29 Post-Mortem

So recently I posted that I was participating in Ludum Dare, a solo, 48-Hour Game Jam competition.  After the rather hectic, 48-hour period, I did complete a game!  Entitled Coffin, this game can be found on the Ludum Dare page here.

We were encouraged to write journal entries throughout the course of the jam; I wrote 9 total:

A lot of people write post-mortems or retrospectives of their game, so I decided to do the same.

Interpreting the Theme

So before entering Ludum Dare, I had several ideas in mind.  This, in my experience, is usually a no-no for themed game jams as the final theme can turn that idea on its head or make it completely unusable -- unless you bullshit a wild correlation.  During this Ludum Dare, participants were asked to vote on a theme, which I think contributed to my scheming in advance, voting up themes I liked and those that I wouldn't have an idea for.  I liked the voting, but I think no voting would have forced me to go into this without 0 (or fewer) ideas.
Anyway, after the theme, Beneath the Surface, was announced, I thought for about 20 minutes -- waiting for the pizza I ordered to arrive -- but succumbed to one of the ideas I had earlier.
My recent Oculus Rift research had a heavy influence on my idea, particularly with how it can make you feel like you're in an experience.  Of course, there are a lot of rules, such as too much movement in the character that contradicts the player's movement can cause motion sickness, especially when locking the view.
I also wanted it to be creepy and scary as I feel the Oculus is a great outlet for creating these types of experiences.  My current inspiration for maximum creepiness is a this rather and quite frankly disturbing music video directed by Eric Wareheim:

Pretty creepy right?  I won't post the video as it's kind of NSFW, but you can search for it yourself

Anyway, I interpreted the theme to a rather terrifying experience -- being buried alive.  I didn't want to do just do being buried alive though; this was a game jam, not an experience jam.  So instead, I wanted some other idea in it.  I wanted to add some elements to the game that would make the player understand why they were being buried.  I eventually came up with the idea that you were some sort of immortal wizard or witch that is being buried alive to keep everyone safe from your magic.
Unfortunately, this was all I really had.  I had the idea that you are in the coffin, that there is a glass window and you can see rocks falling in from above, covering the glass.
After fighting with physics for a couple of hours -- which I always end up doing even though I say that I despise wasting time with it -- I was able to achieve the effect I want:


Also, a quick physics note, mostly for myself, but if you want to use Unity3D's physics and move an object from point A to B and use Physics, making it "jump", here's a quick code snippet for doing so:

Vector3 startPosition, goalPosition; 
float speedFactor; 
rigidbody.position = startPosition; 
rigidbody.velocity = speedFactor * (goalPosition - startPosition) - (Physics.gravity * 0.5f) / speedFactor;

In the above, if you want an object to be moved from a starting position to a goal position with velocity, I found this to work.  The speed factor is just a little touch for making the object move more quickly or more slowly.  It's probably game physics 101, but I always forget how to do this when encountered with moving an object from its current position to a goal position with a little jump.  In my game, I didn't use the speed factor, hence why the initial sequence is so long; also filling that window with rocks was a pain. 

Making Something I'm Not

At the beginning of day two, I was trying to figure out the actual gameplay of my entry.  I somehow had the idea that you are buried underground because you have some sort of artifact or puzzle box.  You're buried with it, but now it is the only thing that can save you.  With this, I feverishly began modeling and conceptualizing ideas for a puzzle box similar to that in the iOS game, The Room.  I skinned, rigged, and textured my mysterious sphere and was ready to solve my first (juvenile) puzzle!

The puzzle sphere broken apart

My idea was simple.  You'd rotate and push various parts of the model to complete a pattern that would ultimately glow and take you to the next scene.  If you failed to complete it in a given period of time, you'd get a scare!
As I worked though, I realized that programming this to feel good would take a long time, especially with all of the extra work I wanted to put into the game as a whole.  I contemplated quitting, but I don't like to give up, so I rethought my idea.  I thought about what kind of game would I want to play.  I wanted to keep the puzzle, but the more I worked with it, going from the sphere to a flat plane, I realized the puzzle solving wasn't going to happen.  Instead, I decided to go an entirely different route:  rail-shooting.
I enjoy rail-shooters like Resident Evil:  The Umbrella Chronicles.  Of course, this wouldn't be on rails since you are confined to such a confined, claustrophobic space.  I did have the idea that some imp would drag you out of the coffin and then you'd have to shoot rocks and bats, but this never came to fruition.  I had a lot of ideas that never came to fruition such as a dialogue between two guys who were burying you.  Why did I think I'd get time to record myself doing two unique voices despite having almost 0 voice acting experience?  Well, it's fun to dream, which I find happens during a lot of game jams.
Anyway, after realizing I wanted a shooter and determining that solving a puzzle while shooting wasn't going to work, I built a system in which three "buttons "would be on the sides and top of the coffin which would activate different magic!  I finally had my game figured out!  It did, sadly, feel a little late as if I would have used the time to make the puzzle sphere and jump immediately to this idea, I probably could have done a lot more with the game such as texturing.
In fact, the entire last day felt like a mad rush just to get what I wanted.  I didn't get to texture anything, which quite frankly isn't really needed here and the audio was also rushed.  I did get the main components:  projectiles, creepy hands, a bound main character that seemed like you were actually playing them, and a super creepy boss with animations that I really wish was less suggestive.

So How Do I Think I Did?

When competed solo, Ludum Dare is a competition, but honestly I don't care about winning or losing.  I was more or less doing this against myself to see what I could do working alone in a short period of time, especially after such a long period of creative stagnation from writing the GML book.  I feel I made something interesting for only two days.  I could only imagine how this could be with two weeks or two months -- two years would be crazy as my attention span isn't long enough.  Honestly, however, I probably won't continue this game.
In fact, making this game, made me wonder:  Why even do game jams (or at least a solo one)?  The deadline is a good motivator, but I know I'm disciplined enough to get things done quickly, so that isn't really the challenge.  The bigger challenge for me is working with a unique theme.  I have themes in my head and ideas I want to prototype, so the theme sometimes feels like it gets in the way.
What I should probably do is keep a backlog of game ideas I want to prototype and when participating in game jams like this, or heck, just picking a free weekend to punch something out, and work on making a prototype for that idea, even if it uses assets that I'll end up throwing away.
Overall, I think I succeeded.  I completed a working game.  I experimented with things in Unity I don't touch often:  Physics, post-processing effects, dynamic lighting.  I also experimented a bit with Substance Painter, which I think is a neat texturing tool but doesn't quite do what I want it to do when it comes to texturing.  Though I'm not sure what I really want in such a tool anyway; I'm still looking for a program to texture 3D models.  In addition, I realized, I normally neglect the elements of a game I am terrible at during a game jam -- in this case, texture and audio.
In summary, I should have either picked a game idea I wanted to prototype more strongly than this, one that I'll want to continue with, or at least know the actual gameplay of my game instead of the initial cinematic experience.  I shouldn't focus on elements of polish without completing major elements either.  Regardless, I still think I was successful and though I'm not sure whether or not I will do the next Ludum Dare, I will definitely consider it.  Anyway, here is a video of my game, Coffin:


Thursday, April 24, 2014

Ludum Dare #29

Now that the GameMaker book I have been working on for the past 9 months has wrapped up, I have decided to participate in the Ludum Dare game jam. Ludum Dare provides an outlet for posting about one's progress, so here is a link to a post I recently made talking about why I have decided to participate in a solo, 48-hour, game jam: http://www.ludumdare.com/compo/2014/04/24/why-am-i-doing-this/ My next couple of post here will most likely be links to what I write for Ludum Dare. I'm excited and nervous, but mostly just glad the book is done!

Saturday, April 5, 2014

Daz3D -> 3DS Max Biped for Skin Wrapping

Instead of whining about my feelings for a change, I wanted to write about something I'm excited about that actually has to do with game development!  In this case, the process of taking a skinned model from Daz 3D, transferring the bone weight information properly to 3DS Max's biped, and using this new configuration to skin characters!

The Problem

Since I'm a fan of Unity3D, I want to actually create 3D assets for a game.  With the release of their 2D tools, I know I could just make a sprite-based game, which technically I am with Battle High 2 despite not using this new tool set, but I don't want to do this.  I want to eventually make a 3D game with animated characters.
Since I technically was trained to be an artist, I feel this muscle is constantly atrophying, and I the only way to build it back up is to create more art.  Also, I always enjoyed 3D character modeling and animating, and though I know my work will never be the level of quality created by AAA studios -- for one, I don't touch ZBrush -- I'd rather create something than nothing.
Since I'm employed and don't have tons of times to dedicate modeling the perfect nose or every strand of hair on someone's head, I look for shortcuts, especially when it comes to tedious task.  Utilizing these shortcuts has caused some issues though, but there is a crossroad that I reach.  I can either take the time to learn something new, something that'll probably be replaced by a better technique, program, or method, or just use what I know and make something.  Also, as a kinesthetic learner -- I think anyway -- I learn and improve best by actually doing.  This being said, one of my major problems is 3D Studio Max is my modeling suite of choice.  There are many problems associated with this:
  • It's expensive.  A single license cost about $4,000.  Up until recently, they've introduced a subscription model, but personally, because of game development's unpredictable nature, I try to avoid subscriptions, finding that eventually buying the static license would have been cheaper.  Maya LT and Blender are cheaper -- Blender being free -- but again, despite this, I really don't want to take the time to learn these other modeling suites when I have one I am capable of doing the same things in.
  • It's skinning capabilities are dreadful.  Skinning refers to binding a mesh's vertices to bones; you'll be hearing a lot more of that later in this post.  Both Maya and Blender utilize heatmapping, a technique I believe was created or at least inspired by the M.I.T. Pinocchio, auto-rigging project.  What's even more irritating is that a script has been written to utilize this, but the user doesn't have it uploaded anywhere.  You can see it in this video:  
  • It has tons of tools I will never use.  This correlates to the high expense.  It would be like buying a 90 piece knife set but only using 3 knives all the time.
Anyway, in my search of shortcuts, one process I definitely find tedious, as mentioned earlier, is skinning, so I set out to find a better solution.  I reached a lot of deadends and decided to eventually form my own.

The Solution in Genesis

3DS Max does have one tool that I really like to make skinning a bit easier.  This tool is known as Skin Wrap.  I believe I talked about it in an earlier post.  This video explains more about it:

Skin wrap comes with two giant caveats though.  You need a model that is already skinned for one.  This isn't impossible to find, but can be irritating.  The second issue is that with skin wrap, the rig of what is being used becomes your new model's rig.
To solve solution one, I found a 3D modeling program, Daz 3D, that comes with an already, rather well skinned character known as Genesis.
Those weird gray shapes are the dummies / bones.

This model can be exported from Daz3D with its skinning information intact as an FBX.  This is great, but I don't want to use the rig it comes with.  Nothing is linked up properly, and all of the rotations are at identity quaternions.  This can be extremely problematic when animating.
This also causes an issue with another shortcut I use, this being the use of 3DS Max's Biped.  The biped is a built-in rig.  It is a little dated, but it still is useful for animation, especially due to its ability to save and load animations and poses.
Oh Biped, you so crazy looking!

I could just size the biped in figure mode and make it close to the Daz Rig, but I don't like this approach.  Also, the Genesis rig has extra bones that I simply don't need such as a big toe bone and two carpal bones -- which were the most troublesome.  Here are the two rigs side-by side:
The different poses aren't the issue, but the different orientation of bones.
Here is a more detailed list of differences:
  • Biped assumes the legs are at the same height as its pelvis
  • Genesis has two carpal bones in each hand, a big toe bone, and pectoral bones
  • Genesis has a lot of extra bones in the head that using morphing for facial expressions could replace
  • Genesis doesn't have forearm twist, which can be added to the Biped.
So, in my process of transferring the Daz model to the biped rig, I had to resolve these.

Removing Unnecessary Bones

Normally, more bones can create a nicer, more realistic rig, but it can also become more difficult for the game engine to process and more time-consuming to animate.  This being said, I had to delete these unneeded bones, but unfortunately, when removing bones from the skin modifier, 3DS Max doesn't do a great job reconfiguring skin weights.
I could delete the carpals, but there is no guarantee these weights would be distributed to the hand properly.

I could have tried deleting this and fixing it by hand or use the weight table to transfer these values to the hand bones, but this would have taken a very long time.  Instead, I decided to write a maxscript!  Unfortunately, I don't know much about manipulating skin values with maxscript, so my solution is rather slow and tedious.  It also uses two functions which actually aren't documented, which made this process rather irritating:
-- Swaps selected indices between bones.

rollout skinTransferRollout "Skin Transfer"
(
    edittext boneIndexA "Bone Index A" readonly:true
    edittext boneIndexB "Bone Index B" readonly:true
  
    checkbox canCheck "Add Bone Weight"
  
    button setBoneA "Set Bone A"
    button setBoneB "Set Bone B"
  
    on setBoneA pressed do
    (
        _mySkin = $.modifiers[#Skin]
        boneIndexA.text = (skinOps.GetSelectedBone _mySkin) as string;
    )
  
    on setBoneB pressed do
    (
        _mySkin = $.modifiers[#Skin]
        boneIndexB.text = (skinOps.GetSelectedBone _mySkin) as string;
    )
  
    button doit "Process Scene" -- button to start processing
    progressbar doit_prog color:red -- a red progress bar
    on doit pressed do -- when the button is pressed...
    (
        bA = boneIndexA.text as integer;
        bB = boneIndexB.text as integer;
      
        _mySkin = $.modifiers[#Skin]

        -- Gets the number of vertices
        vertCount = skinOps.GetNumberVertices _mySkin

        print vertCount;

        selectedBone  = skinOps.GetSelectedBone _mySkin
        print selectedBone

        selectedVertexArray = #()

        for i = 1 to vertCount do
        (
            if (skinOps.IsVertexSelected _mySkin  i) == 1 then
            (
                append selectedVertexArray i
            )
        )

        finVertCount = selectedVertexArray.count;
      
        for i = 1 to finVertCount do
        (
            doit_prog.value = 100.0*i / finVertCount
          
            v = selectedVertexArray[i];
  
            skinOps.selectVertices _mySkin v
  
            weightCount = skinOps.GetVertexWeightCount _mySkin v;
  
            weight = -1.0
            for b = 1 to weightCount do
            (
                boneIndex = skinOps.GetVertexWeightBoneID _mySkin v b;
      
                if boneIndex == bA then
                (
                    weight = skinOps.GetVertexWeight _mySkin v b;
                )
            )
  
            if weight >= 0 then
            (
                if canCheck.checked == false then
                (
                    skinOps.SelectBone _mySkin bA
                    skinOps.setWeight _mySkin 0
      
                    skinOps.SelectBone _mySkin bB
                    skinOps.setWeight _mySkin weight
                )
                else
                (
                    skinOps.SelectBone _mySkin bA
                    skinOps.setWeight _mySkin 0
      
                    skinOps.SelectBone _mySkin bB
                    skinOps.addWeight _mySkin weight
                )
            )
        )
        doit_prog.value = 0
    )
)
createDialog skinTransferRollout-- create a dialog to test 



This script was written rather quickly and could probably be (a lot) better.  Essentially, the user defines two bones -- the first is the bone whose vertex weights will be transferred, the other is the bone they will be transferred to.  Then, the user specifies if the weights will be added or set.  I had to make this differentiation because the hand was taking information from two bones and simply setting using setWeight would cause the bones to the values to overwrite.  Also, I have to do the extensive looping of each vertex because setWeight and addWeight only work upon the selected vertices.
This was great for transferring these bones.  I was able to take the carpal weights and add them to the hands.  I also did this to the big toe bone.  I didn't do this to the pectoral because the pectoral weighting covered a large region.  I could probably figure out a way to do this, but I decided to leave them as they would just serve as additions to the biped skeleton and not interruptions the rig like the carpals did.

Align those hips!

So now that I can transfer bone weights, the next issue had to be solved.  The Genesis rig's hips and legs are not aligned while the bipeds are.  Honestly, the Gensis rig is probably more realistic or better, but to transfer the rig over, beause the biped's legs cannot be detached from the pelvis, I had to realign the genesis rig.

Fortunately, the skin modifier can be temporarily turned off to make these changes.  The Genesis's rigs hip, pelvis and leg bones were moved to align with the bipeds more properly.

 While "Always Deform" is off, the bones can be adjusted.  I had to make sure that the legs would end up being in their original positions as moving the pelvis and hips causes them to moved as well.

Aligning the Biped

The next phase in this journey is aligning the biped to the original daz rig.  Now, I could do by carefully eyeballing, but that is risky and can cause things to be misaligned, which would cause strange deformation later.  I, instead, decided to write a script to at least make sure the bone sizes were correct.

rollout bipedAligner "Biped Aligner"
(   
    local bone_selection = undefined;
    local dummy_selection = undefined;
   
    group "Biped Group"
    (
        pickbutton SelectBipedBone "Select Biped Limb"  across:2 align:#left
        edittext BipedText "" text:"undefined" align:#right readonly:true
    )
   
    group "Dummy Group"
    (
        pickbutton SelectDummy "Select Dummy" across:2 align:#left
        edittext DummyText "" text:"undefined" align:#right readonly:true
    )
   
    button ScaleX "Scale X"

    button ScaleZ "Scale Z"
   
    on SelectBipedBone picked obj do
    (
        if (obj != undefined) then
        (
            bipedAligner.bone_selection = obj;
            BipedText.text = obj.name;
        )
        else
        (
            BipedText.text = "undefined";
        )
    )
   
    on SelectDummy picked obj do
    (
        if (obj != undefined) then
        (
            bipedAligner.dummy_selection = obj
            DummyText.text = obj.name
        )
        else
        (
            DummyText.text = "undefined"
        )
    )
   
    on ScaleX pressed do
    (
        bone_dist = distance bipedAligner.bone_selection.transform.pos bipedAligner.bone_selection.children[1].transform.pos
        dummy_dist = distance bipedAligner.dummy_selection.pos bipedAligner.dummy_selection.children[1].pos;
       
        scale bipedAligner.bone_selection [dummy_dist /bone_dist , 1, 1]

    )
   
   
    on ScaleZ pressed do
    (
        bone_dist = distance bipedAligner.bone_selection.transform.pos bipedAligner.bone_selection.children[2].transform.pos
        dummy_dist = distance bipedAligner.dummy_selection.pos bipedAligner.dummy_selection.children[2].pos;
       
        scale bipedAligner.bone_selection [1, 1, dummy_dist /bone_dist]
    )
)
createdialog bipedAligner 900 200

Again, not the most elegant or clean or efficient code, but it did what I wanted.  Essentially, I pick one of the biped bones and one of the Genesis rig dummies.  I then  run a script that figures out the distance between the selected dummy and one of its children in the genesis rig and then the same in the biped rig and scales the biped bone on either the x or z axis.  Almost every bone used x except for the hips which had to use z.  Also, I use the child at index 2 for the z since the first child in the hips is actually the spine and not the legs.  By making the distances match, I'm guaranteed that the bones are the proper sizes.  Unfortunately, I still had to eyeball rotation.  I know there is a way to use the distance and get a vector and convert that to a rotation somehow -- and if you have a clear way to do so, I'd love to hear it -- but at 1:30 AM, which is when I was working on this, eyeballing was faster.

Genesis Transfer

After finally getting the rigs aligned and adding my own forearm twist bones, I could transfer the weights.  Skin Envelopes and vertex weights can be saved out to a file, which I did.  I also renamed all the biped bones so they would match the Genesis rig.  The loading process for envelopes requires the names to match; otherwise, a list of current bones has to be adjusted in a rather slow process:
This process is outrageously slow if the names don't match.
After this, the Daz model was now rigged to the biped!  Now for the wrapping to begin!

Wrap It Up!

As mentioned earlier, Skin Wrap is a nice method for transferring skin weights from one mesh to another.  One problem was I had to resize the biped for now meshes.  You can change the height of a biped in figure mode, but it looks rather silly and can probably cause inaccuracies when skin wrapping.
I was going to try and just use this, but fortunately after a quick Google search, I found biped resizer script.  Essentially it allowed me to resize a biped and keep anything skinned to it properly resized.  Anyway, after all of this madness, I made a video of me aligning the biped to a character.


(A little upset how the video isn't the recorded resolution, but hopefully it gets the point across.)

In the video, I transfer the Daz skin, after resizing it to an old character.  I don't take the time to position the biped perfectly since this is for demonstration purposes, but with my quick job, the character is skinned relatively well to the new bone structure.
This was a lengthy process, but I'm happy I got it working and it took much less time than learning a new modeling suite.  Hopefully I can use my new skin wrapping pipeline to create 3D humanoid characters for my next 3D game after Battle High 2, which I still am working on.  If you have suggestions on how to better my process, I'd love to hear it as I know these are all very quick approaches that could probably be better.