Making Completely New Ships

Modelling new ships (from scratch)

I'm going to assume that the folks reading this are proficient in 3d meshing, modelling, animating and UV-Mapping, as those are skills you will need to do this - they are not related to ThreadSpace: Hyperbol, but general 3d modelling skills.

If you want to just see how its done, scroll down. There are videos.

The Pipeline

Custom models are more advanced than prefabs, and ships moreso.

The way it works, is that we use a completely free 3d Modelling tool called Blender 3d. Its available at http://www.blender.org and runs on every platform.

If you have hyperbol installed, you will find a subfolder inside the main tshb folder (eg in your steam folder under steam/steamapps/common/tshb) called hbmetoolkit. In the hbmetoolkit folder there are many tools, but the ones we are interested in for ship making are the python scripts (everything .py), makemodel_release.exe and genmeta.exe

The pipeline is as follows:

  1. Create the mesh in blender. (Including materials, uv-maps, etc). This includes using the material toolkit (python script) to choose shaders for the various polygons. Engines should be 'glowing' or fullbright. See the "Making Custom Prefabs" topic here on the wiki for some insight on how to make your ship models compliant. Basically if it can be exported as a prefab, it can be exported as a ship model (But you don't need to make collision lines).

  2. Break the mesh up into subpieces so that they can be individually colored. There should be a chassis, and then three other pieces (for Part A, Part B, Part C in game).

  3. Normalize the mesh (apply all scaling transformations) in blender this is CTRL+A

  4. Rig the mesh: All the subpieces should be children of the chassis so that when the chassis moves, they do.

  5. Add 'empty' (aka dummy objects) for the various attachment points such as retro or engine particle emitters, and make sure these are correctly attached to the parent so that when you move the various parts, they move as expected. Also add an empty object called pivot and make sure that the object rotates correctly around this object.

  6. Create a set of empty folders for your exported files - one for each chunk. For example, the vindicator has 4 folders: chassis, engines, fins, wings.

  7. Use the HBModelTool (in object mode in blender, its under object->scripts) python script. Use it to set the crease angle, export folder (Browse to the folder you made).

  8. Using the HBModelTool, add three animations. Name one "reference" and make it from frame 1 to frame 1. Name the other one "idle" and set its animation however many frames you want for the idle animation. Set the other one to "idle" and set that animation however you want it. You can use as many frames as you need, but the fewer the better. TSHB interpolates.

  9. Change the reference frame's from type "animation" to type "reference"

  10. Select all objects in the scene and choose "not to be exported"

  11. Now we export the various pieces of the ship each to its respective folder by doing the following

    1. select the piece and all its children (ie, if it has attachment points attached to it, select them also. For example, I might select the engines, and all the engine emit points.

    2. click 'To Be Exported' in the HBModelTool to mark those as to be exported.

    3. in the HBModelTool click on the path (starts off as reference.mds) to browse to the folder that this part should go into. For example with the engines, I'd choose the 'engines' subfolder.

    4. click export model. b. click 'Not To Be exported' to prevent the parts you just exported from showing up in the next export.

    5. repeat the steps a - d for each subpiece. IF you're at all unsure about the state, select everything, click 'not to be exported' and try again.

  12. Now that everythings exported, you'd save your rigged model (probably under a different name) and we're done with blender.

  13. Make a VA2 file that describes each part, and put it in the parts folder

  14. Run the makemodel_release.exe program on the va2 files. Each one produces a vm2 which is a compiled model.

  15. Drag and drop the vm2 onto the genmeta.exe file. This generates a mex file (model extra) for the model which tells it where to get its textures and what shaders to use. Edit this file.

  16. Export the textures to whatever format (TGA is okay, but make sure the mex file mentions them), DDS is better. DDS-DXT1 for base layers, DDS-DXT5 for overlays.

At this point the engine could actually run with your ship. To get it to view your ship you're going to have to overwrite a ship slot (ie, the dreadnaught) with it. This involves adding a csv file listing the pieces into your modfiles folder. You could also make a custom map.

Details - Exporting From Blender

Instead of trying to describe this, I've simply put it in a wink video.

Exporting Ships Video 1024x768 - click here to watch in the browser, or right click here and choose "save as"

List of all recognized attachment names and what they do

The thrusters - each one consists of a position that particles jet out from, and a direction they travel towards from there. There must always be exactly six of these. They can be anywhere, in any direction, and the game will intellegently fire them as appropriate to maneuver the ship.

thruster1
thruster1dir
thruster2
thruster2dir
thruster3
thruster3dir
thruster4
thruster4dir
thruster5
thruster5dir
thruster6
thruster6dir

Gun points - each gunstart point will emit particles and beams to converge at the single "gunend" point. A big glow will appear at gunlimit. Most of the time, gunend and gunlimit are the same point. It is recommended that both gunend and gunlimit are directly in front of the ship, on the 'ring', on the floor plane.

gunstart1
gunstart2
gunstart3
gunend
gunlimit

Up to three engines - engine glow particles will start at the engineemitX points, and travel towards the engineemitXend point. A glowy engine ring will be created at engineemit1, and will 'face' engineemitXnormal.

engineemit1
engineemit1normal
engineemit1end
engineemit2
engineemit2normal
engineemit2end
engineemit3
engineemit3normal
engineemit3end

List of animation frames that he game recognises for ships

idle - played when not firing, looping.
fire - played when firing.  Then it loops back to idle.

Of course, all parts must have a reference frame too - but that contains the mesh data, no animation.

Details - Building the compiled ship using VM2 and MEX files

Instead of trying to describe this, I've simply put this in another wink video.

Compiling Ships - click here to watch in your browser, or right click here and choose "save as"

Example VM2 File - Vindicator Chassis

[HBVAN]
COMMENTExportScale: 0.8
COMMENTExportOffset: 0.0 0.0 2.0
[HEADER]
ModelName: vindicator_chassis
CollisionSphere: 0.0 0.0 0.0 64.0
AttachmentPoint: gunstart1     gunstart1     0.0 0.0 0.0
AttachmentPoint: gunend     gunend         0.0 0.0 0.0
AttachmentPoint: gunlimit     gunlimit     0.0 0.0 0.0
AttachmentPoint: thruster1     thruster1     0.0 0.0 0.0
AttachmentPoint: thruster1dir     thruster1dir     0.0 0.0 0.0
AttachmentPoint: thruster4     thruster4     0.0 0.0 0.0
AttachmentPoint: thruster4dir     thruster4dir     0.0 0.0 0.0
AttachmentPoint: engineemit3     engineemit3     0.0 0.0 0.0
AttachmentPoint: engineemit3normal     engineemit3normal     0.0 0.0 0.0
AttachmentPoint: engineemit3end     engineemit3end     0.0 0.0 0.0
[MODEL]
LODScale:         0.0
ReferenceFrameFile: "reference.mds"
Animation:        "fire.mds" "idle" 0.01
Animation:        "idle.mds" "fire" 0.5

VM2 Format

(mandatory) [HBVAN]
(optional)  ExportScale: <global scale of model>
(optional)  ExportOffset: <X Y Z> // offset to move the model when exporting
(mandatory) [HEADER]
(mandatory) ModelName: <export name, no spaces or special characters>
(optional)  CollisionSphere: <x y z radius>
(optional)  CollisionSphere: ... repeated as many as you want (up to about 10 but 1 is best!)
(optional)  AttachmentPoint: <name> <name> <x y z offsets>
(optional)  AttachmentPoint: ... repeated as many as you want (only as many as needed please)
(mandatory) [MODEL]
(mandatory) LODScale: <scale 1.0 to 0.0>
(mandatory) ReferenceFrameFile: <filename in quotes>
(mandatory) Animation: <filename in quotes> <animation name for game to see in quotes> <frames per game frame>
(optional)  Animation: ... repeated however many animations you want
(optional)  [MODEL] // another LOD model
(optional)  ... another model block as above - however many LOD models you have.

Example MEX file - Vindicator Chassis (actual, with fixed issues)

[model extra file]
[submodel_0]
[texturechunk_0]
originalname and texture: vindicatorchassis_mainskinpsd_mainmatc - mainskin.psd@mainmat_c_
shader: Chrome_Tint_Overlay
texture_slot_0: "data/models/vindicator_chassis/mainskin.dds"
texture_slot_1: "data/models/vindicator_chassis/mainskin_OVER.dds"
texture_slot_2: null
texture_slot_3: null
[texturechunk_1]
originalname and texture: vindicatorchassis_mainskinpsd_mainmatd - mainskin.psd@mainmat_d_
shader: Diffuse_Overlay
texture_slot_0: "data/models/vindicator_chassis/mainskin.dds"
texture_slot_1: "data/models/vindicator_chassis/mainskin_OVER.dds"
texture_slot_2: null
texture_slot_3: null

MEX FILE FORMAT

(mandatory) [model extra file]
(mandatory) [submodel_n] // (submodel_0 ... submodel_9) one of these for every LOD model in the file
(mandatory) [texturechunk_n] // (texturechunk_0 to texturechunk_99) howver many different materials the mesh has.)
(ignored)   originalname and texture: whatever it was in blender - totaly ignored by the exporter/game its just for you to see
(mandatory) shader: <Standard shader name>
(mandatory) texture_slot_0: <full relative path to the base layer, or null for no texture>
(mandatory) texture_slot_1: <full relative path to the overlay... or null if not an overlay type shader>
(mandatory) texture_slot_2: null
(mandatory) texture_slot_3: null
// at this point you'd repeat the texturechunk_n and then the submodel_n.

Shader Names

Ships can use the following shader names. Shaders without an overlayshould have texture_slot_1 set to null. Shaders with an overlay should have texture_slot_1 set to an appropriate alpha blended overlay layer that has lights/lines/scrollwork/decoration for the player to customize the color of.

RECOMMENDED SHADERS:
Diffuse_Overlay - has colorizable overlay for slot 1 - and a colorizable base color. Recommended diffuse shader to use.
Specular_Overlay - has colorizable overlay for slot 1 - Recommended specular shader to use.
Glowing - No overlay - always rendered at full brightness.  Glows in the dark.  Not colorizable.  Use for engine innards.
Chrome_Tint_Overlay - Overlayed, colorizable shiny reflective glossy shader.  Fancy.
OTHER SHADERS:
TheCrystal - The glowing pulsing shader you see used on map signals, recycle indicators, etc - not really meant for ships.
Diffuse - no overlay - very plain texture shader.  Has shading and thats about it.  Cannot customize colors.
Diffuse_Tint - no overlay.  Just a plain shaded shader, with player color customization
Specular_Tint - no overlay.  Has specular highlights, and can be color tweaked.
Glowing_Tint - No overlay - always rendered at full brightness, glows in the dark - but can be colorized by players
Glowing_Tint_Primary - No overlay - always at full brightness, but controlled by the parts primary color instead of secondary
Glowing_Tint_Overlay - If for some reason you need a glowing part with a glowing overlay as well.
Pulsing - No overlay. Pulses between black and fullbright - not colorizable
Pulsing_Tint - No overlay. Pulses but can be colorized (uses secondary color)
Pulsing_Tint_Primary - No overlay. Pulses but uses primary color
Flashing - No overlay. Rapid flashing.  Not colorizable
Flashing_Tint - No overlay.  colorizable version
Flashing_Tint_Primary - No overlay. colorizable version
Chrome - No overlay - Shiny reflective chrome, but without overlay or color choice
Chrome_Tint - No overlay - same as chrome but color tinted by secondary color.
Chrome_PulseOverlay - No customization - but its overlay pulses betwen black and white
Chrome_Tint_Overlay_NoAdd - Special version of Chrome_Tint_Overlay for when parts of it wash out due to them being white.

How Color Customizations Work

The way it works is that you use a shader such as Diffuse Overlay, and you supply a base texture in slot 0 and an overlay in slot 1. The base texture is just the regular texture of the ship, generally an all-greyscale texture, perhaps with a few colorful details set to be part of the GLOWING shader. The overlay texture should be a texture that has an alpha channel (ie, transparency). It will be transparent, but with parts of full white color. Those parts will be tinted to the "primary color" that the player chooses, and then overlaid over the ship. It has the same UV map. Parts that are transparent will have the base layer (with secondary color) shining through.

Getting The compiled model into the Game

Of course, the purpose of all of this is to put the model in the game. So lets do so. There are many ways to do it, but probably the best is to simply override an existing model, such as the dreadnaught. The dreadnaught is model # 1. So we'll make a data_user.csv file (in the modfiles subfolder). data_user.csv is loaded after all other files are loaded and all other data is consumed, so that it may do final overriding of any values.

Note that trying to run a modified server with changes to user_data will cause the server to become unofficial and scores to be discarded. You can, however, play on servers with a modified data_user.csv file. At worst, it will simply desynch you if you use it to change game values. Model editing should be pretty harmless.

If you override the dreadnaught (for example), then your model will be used wherever the dreadnought would be used - in LAN games, in the market, in starport, etc. Note that of course, all such overrides are local to you - other people wont see your ship, since they don't have the model files, or the overrides in place. Its like a model pack in other games.

Example: The original dreadnaught file

[KP],BOOL,SHIP_MODEL_1,PRELOAD,TRUE,end,
[KP],STRING,SHIP_MODEL_1,CHASSIS_MODEL,data/models/dreadnaught_chassis/dreadnaught_chassis.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_0,data/models/dreadnaught_generator_0/dreadnaught_generator_0.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_1,data/models/dreadnaught_generator_1/dreadnaught_generator_1.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_2,data/models/dreadnaught_generator_2/dreadnaught_generator_2.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_3,data/models/dreadnaught_generator_3/dreadnaught_generator_3.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_4,data/models/dreadnaught_generator_4/dreadnaught_generator_4.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_0,data/models/dreadnaught_clamps_0/dreadnaught_clamps_0.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_1,data/models/dreadnaught_clamps_1/dreadnaught_clamps_1.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_2,data/models/dreadnaught_clamps_2/dreadnaught_clamps_2.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_3,data/models/dreadnaught_clamps_3/dreadnaught_clamps_3.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_4,data/models/dreadnaught_clamps_4/dreadnaught_clamps_4.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_0,data/models/dreadnaught_engines_0/dreadnaught_engines_0.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_1,data/models/dreadnaught_engines_1/dreadnaught_engines_1.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_2,data/models/dreadnaught_engines_2/dreadnaught_engines_2.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_3,data/models/dreadnaught_engines_3/dreadnaught_engines_3.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_4,data/models/dreadnaught_engines_4/dreadnaught_engines_4.vm2,end,
[KP],FLOAT3,SHIP_MODEL_1,CHASSIS_DEFAULTCOLOR1,0.0 0.4 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,CHASSIS_DEFAULTCOLOR2,0.77 0.77 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_0_DEFAULTCOLOR1,0.0 0.4 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_0_DEFAULTCOLOR2,0.745 0.745 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_1_DEFAULTCOLOR1,0.0 0.4 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_1_DEFAULTCOLOR2,0.745 0.752 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_2_DEFAULTCOLOR1,0.0 0.4 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_2_DEFAULTCOLOR2,0.729 0.737 1.0,end,
[KP],INT,SHIP_MODEL_1,PART_0_DEFAULTSUBST0,0,end,
[KP],INT,SHIP_MODEL_1,PART_1_DEFAULTSUBST1,0,end,
[KP],INT,SHIP_MODEL_1,PART_2_DEFAULTSUBST2,0,end,

Example: data/modfiles/data_user.csv

Suppose I made a ship and I called it 'myship'

  • Assuming myship is comprised of myship_wings, myship_chassis, myship_widget, and myship_doodad

  • assuming you exported it into the models folder

(Notice how we set all subparts to be the same part, since there are no alternative parts).

  • We create a modfiles folder in tshb/data if it doesnt exist

  • we create a csv file (its just text) in tshb/data/modfiles, and call it data_user.csv

  • You can put as many key/name pairs in this file as you want so you could override multiple ships.

  • each line in this file starts with [KP] and ends wth ,end, or else its considered a comment.

[KP],BOOL,SHIP_MODEL_1,PRELOAD,TRUE,end,
[KP],STRING,SHIP_MODEL_1,CHASSIS_MODEL,data/models/myship_chassis/myship_chassis.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_0,data/models/myship_wings/myship_wings.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_1,data/models/myship_wings/myship_wings.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_2,data/models/myship_wings/myship_wings.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_3,data/models/myship_wings/myship_wings.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_0_SUBST_4,data/models/myship_wings/myship_wings.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_0,data/models/myship_widget/myship_widget.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_1,data/models/myship_widget/myship_widget.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_2,data/models/myship_widget/myship_widget.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_3,data/models/myship_widget/myship_widget.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_1_SUBST_4,data/models/myship_widget/myship_widget.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_0,data/models/myship_doodad/myship_doodad.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_1,data/models/myship_doodad/myship_doodad.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_2,data/models/myship_doodad/myship_doodad.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_3,data/models/myship_doodad/myship_doodad.vm2,end,
[KP],STRING,SHIP_MODEL_1,PART_2_SUBST_4,data/models/myship_doodad/myship_doodad.vm2,end,
[KP],FLOAT3,SHIP_MODEL_1,CHASSIS_DEFAULTCOLOR1,0.0 0.4 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,CHASSIS_DEFAULTCOLOR2,0.77 0.77 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_0_DEFAULTCOLOR1,0.0 0.4 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_0_DEFAULTCOLOR2,0.745 0.745 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_1_DEFAULTCOLOR1,0.0 0.4 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_1_DEFAULTCOLOR2,0.745 0.752 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_2_DEFAULTCOLOR1,0.0 0.4 1.0,end,
[KP],FLOAT3,SHIP_MODEL_1,PART_2_DEFAULTCOLOR2,0.729 0.737 1.0,end,
[KP],INT,SHIP_MODEL_1,PART_0_DEFAULTSUBST0,0,end,
[KP],INT,SHIP_MODEL_1,PART_1_DEFAULTSUBST1,0,end,
[KP],INT,SHIP_MODEL_1,PART_2_DEFAULTSUBST2,0,end,

You dont actually have to override the default colors or subst's you can actually leave those lines out, if you want...

Another Way to get it into the game

A "non overriding way" is to include the special ship with your own map, in the maps folder. The map packer will automatically include vm2s, tgas, and DDs files into the map pack if they are in the map folder. It will also include a mapentdata.csv file, which behaves the same way as the data_user.csv except only for that map. So you could include the models in the map and override it for that map only - a self contained package.

Ship Model Numbers

SHIP_MODEL_1 - Dreadnaught
SHIP_MODEL_2 - Poseidon
SHIP_MODEL_3 - Shrike
SHIP_MODEL_4 - Centurion
SHIP_MODEL_5 - Spectre
SHIP_MODEL_6 - Phoenix
SHIP_MODEL_7 to SHIP_MODEL_16 - various special ships (vindicator is 10 to 16)

Addendum: using blender to finish a model

Finishing Touches Video 1024x768 - click here to watch in the browser, or right click here and choose "save as"


Comments