From The DarkMod Wiki
Jump to navigationJump to search

Originally written by SneaksieDave & Ishtvan on

Physics fans rejoice! If you want an object (whether a model or multi-brush/patch) to be moveable (pick up and carry, push, float, shoot, etc.), even though it wasn't designed to be used that way, there is a way to do it anyway, and all within the editor.


You should read the article about Models first to get some understanding of the topic.

In summary you need to create the model, make it moveable, and make sure a collision model exists for it.

Create a Moveable

  1. Create a brush, convert it to a moveable_base entity, and assign it the model you want to use.
  2. You only need one collision model file no matter how many instances of this moveable you make in your map so check if it has already been created (a .cm file of the same name as the model and in the same folder.) If not:

Create a Collision Model (CM)

In DarkRadiant:

  1. Important: Make sure the model is not rotated in any way.
  2. Drag a new temporary brush over the model, roughly covering it.
  3. Clip the shape if necessary, or convert it eg, to pyramid or whatever to best fit the model.
  4. Any texture will do on any surface.
  5. Convert to func_static (any entity will do)
  6. Check the origin of the brush entity is in the same place as the model's origin because that is where its origin will be in-game. If they do not coincide then either move the brush so it coincides and resize the brush or key V and drag the origin into position.
  7. Use the File -> Save selection as collision model menu entry:
  8. The model selector dialog appears, Select the correct model. Click Click the OK button.
  9. A .cm should have now been saved in the same folder as the model and with the same name as the model. (I've done these before but recently in 1.08 it failed so I used the script menu to export as .ase and that worked! Note - in this case you must give it the common - collision texture.)
  10. You can now delete the temporary collision model brush entity.

Important: The shape must be very simple, not having more than say 16 faces! (I now think this is a max of 12. - Fidcal)

In DoomEd:

  1. Drag a new temporary brush over the model, roughly covering it. This will be the collision hull, so get it as close as you can.
  2. Clip the shape if necessary, or convert it eg, to pyramid or whatever to best fit the model.
  3. Convert that brush to func_clipmodel.
  4. Check the origin of the brush entity is in the same place as the model's origin because that is where its origin will be in-game.
  5. Texture it with common/collision.
  6. With that brush still selected, do Selected->Export->To CM. Locate the model for which it will stand as a clipmodel, and save with the same name. The path and name are vital. Don't worry, DoomEd will automatically name it .cm instead by of your model's extension, so it shouldn't overwrite anything.
  7. You can now delete the temporary collision model brush entity.

Brush/Patch Moveables

You can make virtually any brush/patch construction into a moveable. At its core must be a simple brush to form the collision shape. I've had a brush with 12 surfaces as a moveable OK. I don't know if there is a limit but it's my belief that it won't work if too complicated a shape. However, we can get round that and produce very complex moveables such as a stepladder with multiple steps and ladder surface. We do that by binding the construction to a single central collision shape brush which is the actual moveable entity.

Simple brush moveables

First let's take the simplest of brush moveables: a stone block. It is not uncommon in FMs to have a hole in a wall filled with stone blocks or rubble the player can move or push out of the way. So first make your brush stone block from the same texture as your wall so it will match perfectly (if desired.) If it is a broken block (rubble) then you can cut pieces off the basic rectangular block but I would get it all working first and save it then gradually cut piecess off and save the early versions. You might find if you have too many surfaces it might not work. (I am still unsure about this.) I have not tried with patches but it should work. In any event you can certainly bind a patch to an unrendered block to get what you want.

  • Make the brush an atdm:moveable_base entity. Later a proper entity inheriting from atdm:moveable_base might be made up with the following spawnargs to save time. (I couldn't get this to work with the custom entities which have to use a model.)
  • Give it mass (in kilos)
  • No need to give it density as this is now calculated from its volume and mass.
  • Give it friction (0 to 1) I usually aim low about 0.1 else it can be 'sticky'
  • Give it snd_bounce as the sound it will make on impact. Example: med_metal_impact. I suggest you look at what some already existing moveable of a similar size and material is using.
  • Give it an alert size and hardness. This determines how AI will react to its sound. If you don't then it will default to medium size and hard so if your object is about that then you need do nothing. Otherwise, give it these two spawnargs/values. These are the possibles:
    • spr_object_hardness - can be soft, medium, or hard
    • spr_object_size - can be small, medium, or large

By default, the above will highlight and can be pushed about, frobbed and picked up, carried, and manipulated by the player.

If you want it only to be pushed but not picked up then give it frobable 0.

If you want it to go in the inventory:

  • Give it inv_category. This can be eg, Special, Tools, Keys. (look at currentsimilar objects)
  • Give it inv_name with the value of whatever name you want it show in the inventory.
  • Give it inv_icon with the value guis/assets/hud/inventory_icons/default which will show blank (otherwise you get a black square.) If you can create your own icon then even better.
  • Give it snd_acquire with the value tool_pickup is a good default (the sound it makes when the player gets it.)

Remake the map cm file if console error

IMPORTANT! This caused me a lot of headaches over a couple of years until I realized so memorize this even if you forget everything else. When you first make a brush moveable it might work fine but later you get a console error: 'cannot load collision model'. You might get this if you rename the entity or import it as a prefab into another map. What you must do is DELETE the map cm file (in maps folder then DMAP again. Dmap doesn't know if you changed anything so you need to force it to recreate the map collision file.

More complex brush and patch moveables

To make complex brush moveables like a stepladder you first create a simple brush moveable as described above and texture it with textures/common/collision. Size and shape this brush to approximate the basic size and shape of the object you are making. Try to avoid over-complexity of this shape; it only needs to determine collisions. For example, for the stepladder I made an upright right-angled triangle shape. This is the core of the stepladder; the actual moveable entity as described in the above section. You then make your more complex shape(s) into func_static(s) and bind to the collision shape to get the best fit. The collision shape is what the player picks up but it is not visible of course.

Making frobable

The above is OK for pushing around but if you want to be able to pick up the object it needs to be frobable. At this point only the invisible collision moveable is frobable but its highlight is invisible! To make the visible object frobable do the following:

To the invisible moveable add the property/value:

frob_peer <name of visible object>.

To the visible object add the properties/vaues:

frobable 1

frob_distance 1 (do NOT use 0 or it defaults to the normal distance.)

What the above does is allow the visible object to highlight but not directly frobable. Instead when it highlights it means you are focused on the invisible moveable which is what you want - and it highlights the visible object through the frob_peer.

Model/Brush hybrid

In the earlier sections on making a moveable model is described how to make an external model cm file. In some situations you might instead bind a static model to a brush moveable as described above. In some cases you might make the brush moveable visible or some surfaces visible. An example makes it easier to understand: I took a model chest body. Made a rectangular brush moveable to completely fill it. I textured it with textures/common/collision but the top surface I gave it the texture that the chest used. When aligned carefully it complete sealed the top so it looks like a new luggable crate. Then bind the chest model to the brush moveable. To make it frobable see above #Making frobable

Complete List of Default Key/Values for Moveable entities

"Moveable object. Will drop to the floor and rest until activated."
"The visual model set with the 'model' key can also be used for"
"collision detection. However the model may not be too complex."
"max vertices = 32"
"max edges = 32"
"max polygons = 16"
""max edges per polygon = 16"
"The collision model must be an enclosed hull. Dangling polygons or"
"edges are not allowed. If the visual model is too complex or does"
"not meet these requirements it can be contained in a less complex"
"model for collision detection. Such a collision model is specified with the"
"'clipmodel' key."

"editor_var density"          "Volume of the object times the density is the mass."
"editor_var friction"         "Friction with contacting surfaces in the range [0-1] where 0 is no friction."
"editor_var bouncyness"       "How much the object bounces in the range [0-1] where 0 is no bounce."

"editor_var mass"             "Mass of the object (overrides density)."

"editor_model clipmodel"      "Model to be used for collision detection."
"editor_var clipshrink"       "Shrink the visual model with an epsilon and use it as a clip model."
"editor_var allowStep"        "Set to 0 to prevent monsters from ever walking over this object."
"editor_var nonsolid"         "Make the object non-solid."

"editor_bool nodrop"          "Do not drop to the floor."
"editor_bool noimpact"        "Do not activate by the impact of other objects."
"editor_bool notpushable"     "Do not allow to be pushed."

"editor_bool unbindondeath"   "Unbind entity when health drops down to or below zero."

"editor_var health"           "If set the visual model changes to 'broken' when the health drops down to or below zero."

"editor_model broken"         "Visual model to be used when the health drops down to or below zero."
"editor_bool explode"         "If set to 1 the moveable explodes and is removed when the health drops down to or below zero."

"editor_var init_velocity"    "Initial linear velocity set when activated."
"editor_var init_avelocity"   "Initial angular velocity set when activated."

"editor_var init_velocityDelay"   "Delay in seconds before the initial linear velocity is set after being activated."
"editor_var init_avelocityDelay"  "Delay in seconds before the initial angular velocity is set after being activated."

"editor_var initialSplineTime"    "Number of milliseconds the moveable should follow the initial spline path."

"editor_var damage"               "Damage definition if it damages things it collides with"
"editor_var damageWhenActive"     "Only damage when active ( currently for the vagary and influence stuff )"

"editor_var fx_collide"           "FX system to start at impact position when object collides."

Default Settings

"density"           "0.5"
"friction"          "0.05"
"bouncyness"        "0.6"
"explode"           "0"
"unbindondeath"     "0"
"health"            "0"
"nodrop"            "0"
"noimpact"          "0"
"notPushable"       "0"
"clipshrink"        "0"
"allowStep"         "1"
"snd_bounce"        "smallpanel_impact "

See also