SP Tutorial Module System How to add New Skeletons/Mountain Giant to your module.

Users who are viewing this thread


Greetings again, lads,  it's cdvader with a new tutorial. I'm pretty excited to write tutorial this, as I can't imagine what kind of dwarves, trolls, hobbits, orcs, you name it, start coming out of it. Today, we will make a new custom skeleton with WORKING animations by duplicating the old human skeleton. The process will be very easy and I hope nothing goes wrong.

Before I start, I must say a very, very big thanks to mtarini. Thank you!

What do we need?
The game.
Mount & Blade - Version 1.011.
Mount & Blade - Module System for Version 1.011.

Some kind of a animation editing program. Here's two of the (probably) most known:
Autodesk 3ds Max

And the import/export SMD scripts for them.
3ds Max SMD Import/Export
Blender SMD Import
Working Blender Export Script.

And the two most important things of all.
Open BRF
Iron Launcher

PART 1 - Getting ready.
Okay. First of all, make sure you have your Mount&Blade up-to-date and that it's working correctly and also you need the ModuleSystem all set up. Before you start this tutorial, you must have SOME understanding of the ModuleSystem. Once again, I highly recommend The Official ModuleSystem Documentation, but also Jik's ModuleSystem Documentation (very great!).

Now, let's continue. Install OpenBRF. Just download & extract it somewhere, like your desktop (That's a good place, I have it there). OpenBRF is a very good alternative to BRFEdit, because it can edit Animations and Skeletons, which BRFEdit cannot. However, since OpenBRF is still in it's very early development stages (Alpha stage), it doesn't have all the necessary features like Material, Collision or Shader tabs. Thus, currently you should only use OpenBRF for Skeleton and Animation related stuff, and BRFEdit for all the other. But I'm quite sure that soon enough, OpenBRF will be better and more complete.

The next step is to get a Animation and Skeleton editing program. Blender is a bit complicated, but good. And it's also free, which is a really good thing. The other solution - 3ds Max is better in all ways, especially the price part. That's the only downside of Max - It costs around 3500$. I personally use 3ds Max. To get it, either download the 30-day Tutorial or, if you're lucky, you may get a Commercial edition (Or something like that) from school.

After you've got a animation & skeleton editing program ready, you need to set up Iron Launcher with your module. That's easy - Download Iron Launcher, extract it somewhere, and paste all the content of the IronLauncher folder to your Module's folder. I made a shortcut of "IronLauncher.exe" to my desktop for easy access to my mod. Iron Launcher is completely necessary to get the new skeleton working.

I believe we're all set up now! Let's continue.

PART 2 - Adding a new skeleton.
Alright. In this part we will add a new skeleton. A Mountain Giant to be precise. We will not make new heads, hands and legs (Which, unfortunately, are necessary). In fact, the only down-side of adding a new skeleton is that you must re-scale all the bodies, heads, hands and legs if you want it to work with the Giant. But enough babbling - Let's start! :wink:

First, open OpenBRF. Now open 'body_meshes.brf'. Click on 'man_body' and Export as Rigged Mesh. Save it as 'giant_body.smd'. You can close OpenBRF now. Import 'giant_body.smd' into your favourite animation & skeleton editing program (I use 3ds Max in this tutorial!). Note before we start: You have only 1 try, if you fail and re-import the model afterwards the "skeleton" is stretched out and unusable.

Now make a box or a plane right beneath the 'man_body' model in your program. This is critical, we will use the box later to adjust the skeleton to the right place. Now select everything expect the box, and scale your new model a lot. I scaled it to be about 14 times bigger than normal. Now move your new scaled model so the feet touch the box slightly. Delete the box, export the model as 'giant_body.smd' (Reference SMD). Now, still in the same scene, delete the mesh. Only the mesh! Leave the bones. And then export it again, this time as 'skel_giant' (Sequence SMD). Now you can close your program.

Open OpenBRF and import your 'skel_giant' as "Skeleton". Don't be surprised if the bones seem to be way too far of each other (I barely see the bones, I made the skeleton so big). Now save your .brf as "skel_giant.brf" and put it to your Module's Resource folder. Now go to File > New and Import your 'giant_body.smd' as Rigged Mesh. Save the .brf as "giant_body.brf". You can close OpenBRF now.

Now, open your Module's module.ini. Paste these two lines at the very bottom.

load_mod_resoure  = skel_giant
load_mod_resource = giant_body

You can close module.ini now. Before you move on to the next step, make sure you have Iron Launcher installed. It is crucial! Okay, copy the Data folder from Program Files/Mount&Blade to your Module's folder. In the Data folder, open "skeleton_bodies.xml" and paste this after the last </Skeleton> (Note: NOT </Skeletons>. I have not edited anything else expect the name, btw. I haven't researched into this for now. But as mtarini said, it is for hitbox data and such. You don't need to edit this information, at all. The hitboxes and such will scale along very fine with the bones.

  <Skeleton name="skel_giant">
      <Bone name="hb_abdomen" bone_mass="10" bone_twist_limit="20" bone_cone_max="30"> <Bodies> <body type="capsule" radius="0.15" pos_x="-0.0327" pos2_x="0.0327" pos_y="-0.045900" pos2_y="-0.045900" pos_z="0.040400" pos2_z="0.040400"/> </Bodies> </Bone>
      <Bone name="hb_thigh_l" bone_mass="10" bone_twist_limit="30" bone_cone_max="70"><Bodies> <body type="capsule" radius="0.09" pos_x="0.0045" pos2_x="0.0045" pos_y="0.089725" pos2_y="0.434114" pos_z="0.027649" pos2_z="0.043844"/></Bodies> </Bone>
      <Bone name="hb_calf_l" bone_mass="6" rotate_side="45" bone_twist_limit="45"  bone_cone_min = "-5" bone_cone_max="5" socket_dir_y="0.0" socket_dir_x="0.9"><Bodies> <body type="capsule" radius="0.06" pos_x="0.0076" pos2_x="0.0076" pos_y="0.071147" pos2_y="0.447461" pos_z="0.058433" pos2_z="0.005583"/></Bodies></Bone>
      <Bone name="hb_foot_l"></Bone>
      <Bone name="hb_thigh_r" bone_mass="10" bone_twist_limit="30"  bone_cone_max="70"><Bodies> <body type="capsule" radius="0.09" pos_x="-0.0045" pos2_x="-0.0045" pos_y="0.089725" pos2_y="0.434114" pos_z="0.027649" pos2_z="0.043844"/></Bodies> </Bone>
      <Bone name="hb_calf_r" bone_mass="6" rotate_side="45" bone_twist_limit="45"  bone_cone_min = "-5" bone_cone_max="5" socket_dir_y="0.0" socket_dir_x="0.9"><Bodies> <body type="capsule" radius="0.06" pos_x="-0.0076" pos2_x="-0.0076" pos_y="0.071147" pos2_y="0.447461" pos_z="0.058433" pos2_z="0.005583"/></Bodies></Bone>
      <Bone name="hb_foot_r"></Bone>
      <Bone name="hb_spine" bone_mass="10" bone_twist_limit="20" bone_cone_max="30"> <Bodies> <body type="capsule" radius="0.14" pos_x="0.028570" pos2_x="-0.026203" pos_y="0.131210" pos2_y="0.131584" pos_z="0.008536" pos2_z="0.010200"/> </Bodies> </Bone>
      <Bone name="hb_thorax" bone_mass="10" bone_twist_limit="20" bone_cone_max="30"> <Bodies> <body type="capsule" radius="0.145" pos_x="-0.046671" pos2_x="0.046902" pos_y="0.111923" pos2_y="0.111877" pos_z="0.003622" pos2_z="0.001374"/> </Bodies></Bone>
      <Bone name="hb_head" bone_mass="3" bone_twist_limit="60"  bone_cone_max="70"> <Bodies> <body type="capsule" radius="0.09" pos_x="-0.002853" pos2_x="-0.004396" pos_y="0.004160" pos2_y="0.102851" pos_z="0.000345" pos2_z="-0.009731"/> </Bodies></Bone>
      <Bone name="hb_shoulder_l" bone_mass="3" bone_twist_limit="50" bone_cone_max="10"><Bodies> <body type="capsule" radius="0.065" pos_x="-0.003582" pos2_x="-0.003063" pos_y="0.129283" pos2_y="0.162886" pos_z="-0.003477" pos2_z="-0.000981"/></Bodies> </Bone>
      <Bone name="hb_upperarm_l" bone_mass="4" rotate_side="-60" bone_twist_limit="20" bone_cone_max="40"> <Bodies> <body type="capsule" radius="0.06" pos_x="-0.004050" pos2_x="-0.003737" pos_y="0.068400" pos2_y="0.218365" pos_z="-0.012791" pos2_z="-0.009558"/></Bodies></Bone>
      <Bone name="hb_forearm_l" bone_mass="2" rotate_up="-45" bone_twist_limit="45" bone_cone_max="5" socket_dir_z="1"> <Bodies> <body type="capsule" radius="0.052" pos_x="0.007783" pos2_x="0.006982" pos_y="0.013050" pos2_y="0.238987" pos_z="-0.014167" pos2_z="-0.020907"/></Bodies></Bone>
      <Bone name="hb_hand_l"> </Bone>
      <Bone name="hb_item_l"> </Bone>
      <Bone name="hb_shoulder_r" bone_mass="3" bone_twist_limit="50" bone_cone_max="10"> <Bodies> <body type="capsule" radius="0.065" pos_x="0.003582" pos2_x="0.003063" pos_y="0.129283" pos2_y="0.162886" pos_z="-0.003477" pos2_z="-0.000981"/></Bodies> </Bone>
      <Bone name="hb_upperarm_r" bone_mass="4" rotate_side="-60" bone_twist_limit="20" bone_cone_max="40"><Bodies> <body type="capsule" radius="0.06" pos_x="0.004050" pos2_x="0.003737" pos_y="0.068400" pos2_y="0.218365" pos_z="-0.012791" pos2_z="-0.009558"/></Bodies></Bone>
      <Bone name="hb_forearm_r" bone_mass="2" rotate_up="45" bone_twist_limit="45" bone_cone_max="5" socket_dir_z="-1"> <Bodies> <body type="capsule" radius="0.052" pos_x="-0.007783" pos2_x="-0.006982" pos_y="0.013050" pos2_y="0.238987" pos_z="-0.014167" pos2_z="-0.020907"/></Bodies></Bone>
      <Bone name="hb_hand_r"> </Bone>
      <Bone name="hb_item_r"> </Bone>

Save and you can close "skeleton_bodies.xml" now. Go to your ModuleSystem, and open 'header_troops.py'. Paste this after "tf_female".

tf_giant          = 2

Save and you can close 'header_troops.py' now. Let's move on. Open "module_skins.py" now and paste this.

    "giant", 0,
    "giant_body", "man_calf_l", "m_handL",
    "male_head", man_face_keys,
    ["man_hair_s","man_hair_m","man_hair_n","man_hair_o", "man_hair_y10", "man_hair_y12","man_hair_p","man_hair_r","man_hair_q","man_hair_v","man_hair_t","man_hair_y6","man_hair_y3","man_hair_y7","man_hair_y9","man_hair_y11","man_hair_u","man_hair_y","man_hair_y2","man_hair_y4"], #man_hair_meshes ,"man_hair_y5","man_hair_y8",
    ["beard_e","beard_d","beard_k","beard_l","beard_i","beard_j","beard_z","beard_m","beard_n","beard_y","beard_p","beard_o",   "beard_v", "beard_f", "beard_b", "beard_c","beard_t","beard_u","beard_r","beard_s","beard_a","beard_h","beard_g",], #beard meshes ,"beard_q"
    ["hair_blonde", "hair_red", "hair_brunette", "hair_black", "hair_white"], #hair textures
    ["beard_blonde","beard_red","beard_brunette","beard_black","beard_white"], #beard_materials
    [("manface_young_2",0xffcbe0e0,["hair_blonde"],[0xffffffff, 0xffb04717, 0xff502a19]),
     ("manface_midage",0xffdfefe1,["hair_blonde"],[0xffffffff, 0xffb04717, 0xff632e18, 0xff502a19, 0xff19100c]),
     ("manface_young",0xffd0e0e0,["hair_blonde"],[0xff83301a, 0xff502a19, 0xff19100c, 0xff0c0d19]),     
#     ("manface_old",0xffd0d0d0,["hair_white","hair_brunette","hair_red","hair_blonde"],[0xffffcded, 0xffbbcded, 0xff99eebb]),
     ("manface_young_3",0xffdceded,["hair_blonde"],[0xff2f180e, 0xff171313, 0xff007080c]),
     ("manface_7",0xffc0c8c8,["hair_blonde"],[0xff171313, 0xff007080c]),
     ("manface_midage_2",0xfde4c8d8,["hair_blonde"],[0xff502a19, 0xff19100c, 0xff0c0d19]),
     ("manface_rugged",0xffb0aab5,["hair_blonde"],[0xff171313, 0xff007080c]),
#     ("manface_young_4",0xffe0e8e8,["hair_blonde"],[0xff2f180e, 0xff171313, 0xff007080c]),
     ("manface_african",0xff807c8a,["hair_blonde"],[0xff120808, 0xff007080c]),     
#     ("manface_old_2",0xffd5d5c5,["hair_white"],[0xffffcded, 0xffbbcded, 0xff99eebb]),
     ], #man_face_textures,
    [(voice_die,"snd_man_die"),(voice_hit,"snd_man_hit"),(voice_grunt,"snd_man_grunt"),(voice_grunt_long,"snd_man_grunt_long"),(voice_yell,"snd_man_yell"),(voice_victory,"snd_man_victory")], #voice sounds
    "skel_giant", 1.0,
    [[1.7, comp_greater_than, (1.0,face_width), (1.0,temple_width)], #constraints: ex: 1.7 > (face_width + temple_width)
     [0.3, comp_less_than, (1.0,face_width), (1.0,temple_width)],
     [1.7, comp_greater_than, (1.0,face_width), (1.0,face_depth)],
     [0.3, comp_less_than, (1.0,eyebrow_height), (1.0,eyebrow_position)],
     [1.7, comp_greater_than, (1.0,eyebrow_height), (1.0,eyebrow_position)],
     [-0.7, comp_less_than, (1.0,nose_size), (-1.0,nose_shape)],
     [0.7, comp_greater_than, (1.0,nose_size), (-1.0,nose_shape)],
     [2.7, comp_greater_than, (1.0,chin_size), (1.0,mouth_nose_distance), (1.0,nose_height), (-1.0,face_width)],

Right before the last ']'. Save, and close. Open 'module_game_menus.py' and paste this after the Female option.

	  ("start_giant", [], "Mountain Giant.",
	   [(troop_set_type, "trp_player", 4),
	    (assign, "$character_gender", tf_giant),
		(jump_to_menu, "mnu_start_character_2"),

You can save and close. Now Compile. If you get any errors, just re-compile and they should go away. If they don't, make sure you've got everything as it is currently. Now go in-game and check out your new Mountain Giant guy!!

PS: Make sure you launch your game through Iron Launcher every time after doing this.

Critical Update (17/08/09) - Slawomir posted a great explanation!
[quote author= Slawomir of Aarrghh]
Copy skeletons.brf from CommonRes to your mod Resources, name it whatever you want, add your new skeletons in that file, change "load_resource=skeletons" to "load_mod_resource=name_of_your_copied_skeletons_file_here" in module.ini... It works for other brfs, so it should also work for skeletons. Though you'll still need the "skeleton_bodies.xml" in Data folder.







If you want to see any of the custom skeletons actually in action, go and see Berserker Pride's Revenge of the Berserk mod, that is the first mod ever to include any custom skeletons (and a lot of them).







A big thanks to mtarini for Open-BRF,
A big thanks to Swyter for Iron Launcher,
And, of course, a big thanks to Armagan for Mount & Blade.
I think you wanted to say "This is so cool." :grin: Because it works. I'm uploading a screenie as we speak.

Yeah, I will. Also, one note. Third person view with this new custom skeleton sucks. First person, however, is completely fine.

cdvader: Although Blender can edit animations and skeletons the SMD export scripts in your link can't export animations.

Here are two scripts for Blender that can export animations:
http://dl.dvondrake.com/smd_export.py - You can export, but openBRF can't read them - useless until someone savvy enough can modify the code so that openBRF would accept its output.

http://mitglied.lycos.de/dirk_schulz/blendertobrf/brf_export.py - Exports as a BRF readable by openBRF (Major credits to eierkopf), but since it's still pretty new it has some teething problems though eierkopf is currently working on fixing those issues. However, completely new skeletons and animations for the new skeletons can be imported into openBRF without any problems so far if you want to give it a test ride.

If you want to update the links, don't forget to do them for your other tutorial as well. But for now I think it's best you wait until either someone modifies the SMD exporter script I linked or until eierkopf releases a newer version of his BRFexporter that fixes some problems.

edit: eierkopf has released a new version with which is bugfixed. Download link is still the same. It works alright with my Blender (2.4:cool:. Now to get cranking!
I'll add them to the tutorials, thanks. Anyway, screenshots added to main thread! The main problems with mountain giants are ...

a) You see only his feet in a conversation scene.
b) It is VERY hard to hit anything.
c) And to hit anything at all, you need a really, really big sword.

However, mountain giants are excellent for ...

a) Give him a extremely large crossbow and apply 50000 damage to it. :grin:
b) Give him a extremely large club and use Berserker Pride's script so he deals damage to everyone infront of him. :razz:
c) Killing. I bet killing somehting like that would be awesome ... if possible. :grin:

Dain, if you look closely, you see a looter throwing a stone at him. :razz:
Yes, but I was asking about arrows because I'm interested about hitboxes. Have you tried making a giant NPC and attacking it with arrows?
I'll try it today... Anyway, if the hitboxes are out of place, you can still adjust them in skeleton_bodies.xml to be perfect.

If I get this right, it means both trolls and dwarves with human animations are possible?
Yarr, though differently proportioned dwarves may be trickier than just a simple scaling down. I'm not sure.. have you tried changing proportions at all cdvader?
[quote author= Merlkir]If I get this right, it means both trolls and dwarves with human animations are possible?[/quote]
Yeah... You name it. Trolls, dwarves, hobbits, mountain giants (look at mine...) are possible and they use human animations. My mountain giant looks really odd because I didn't scale the head, hands or feet. And I made him too big.

Really, only downside is the items. You somehow must restrict the human items only to humans, hobbit items only to hobbits or whatever. Because hobbit skeleton + human armor = bad.

[quote author= Dain Ironfoot]I'm not sure.. have you tried changing proportions at all cdvader? [/quote]
No. But I'm sure mtarini knows how to change them, and correctly. (He's the one who said that you can use skeleton_bodies.xml for hitboxes, anyway (through Capsule or something)).
I think I just peed my pants. Well, I think Brutus will be glad his work on dwarven gear wasn't for nothing. :wink:
*Important news*. :razz: Well, I've got good news. Apparently, the hit box seems to "dynamically" change along with the skeleton. It's kinda hard to explain, just watch this video (In the end, I show you the collision system.).

Top Bottom