User:SirYodaJedi/Porting IdTech 3 maps to Source/Entities
Common KVs
Some KVs that are common across several entities. If I mention a KV, but it isn't listed here or in the per-entity lists below, assume it works the same as in Source and can be kept as-is.
- Yaw angle (angle) <angle>
- Yaw rotation. For example, a misc_model angle of "180" is equivalent to a prop_static's angles of "0 180 0".
- Target (target) <targetname>
- send an input to the specified entity (whatever that entity's "do" input is)
- Script block name (scriptname) <string> (only in RtCW, WolfET)
- name of block in script file that the entity is associated with
- TargetShaderName (targetShaderName) <material>
- TargetShaderNewName (targetShaderNewName) <material>
- When this entity is triggered, the specified material is replaced with a new specified material. Note that targetShaderName will always be the original material name, even if the material being displayed has been changed at runtime. This will require some complicated material proxy stuff env_texturetoggle or material_modify_control on brushes, but on prop_dynamic, you can just send the skin input.
- Model2 (model2) <model path>
- The first frame of a dynamically-lit model is displayed at runtime wherever this brush entity's origin is (which will move if the entity moves). Put a prop_dynamic where the origin is, and parent it to this entity.
- Model2 Pitch Yaw Roll (Y Z X) (modelAngles) <angles> (only in Jedi Academy)
- Rotational offset of Model2 compared to the rotation of the bmodel. This should be added to the brush entity's angles KV when put in the prop_dynamic.
- Uniform model scale (modelscale) <float>
- Uniform scale of the model (or for brush ents, model2) in all directions. Depending upon the engine branch and entity, you might be able to do this in the entity's properties, but otherwise you can use $scale.
- Model scale vectors (modelscale_vec) <vector3>
- Per-axis scale of the model (or for brush ents, model2). This can't be done with entity KVs or $scale, so it will need to be done in Blender.
- Skin (skin) <file path>
- A .skin file to use for the models skin. See #Skin files.
- Cast Shadows (_castShadows, _cs) <boolean>
- Whether entity casts lightmap shadows. See vrad_brush_cast_shadows for brush entities, or disableshadows for prop_static.
- Lightmap sample size (_lightmapsamplesize, _samplesize, _ss) <integer>
- Explicit luxel scale.
- Lightmap scale (_lightmapscale, lightmapscale, _ls) <float>
- Adjusts luxel scale relative to the material's q3map_lightmapSampleSize, or, if not present, the -samplesize Q3Map2 parameter). If neither are present, assume a default luxel scale of 16. Do note that brush/disp lightmaps in Source are much lower resolution than lightmaps in Quake 3 (32px vs 128px+), so to avoid excessive subdivision on really low luxel scales, consider using static prop lightmaps if possible.
- Smoothing angle (_shadeangle, _smoothnormals, _sn, _sa, _smooth) <angle>
- any angles equal to or more obtuse than this value are phonged together. Use smoothing groups as deemed suitable. If this is on worldspawn, use the -smooth n VRAD parameter, wherein
n = 180 - q
, with q being the q3map2 shade angle. - Constant light color (color) <color1>
- rendercolor.
World brushes
worldspawn
func_group
N/A
Func_group brushes should be untied from entities and returned to worldspawn, as VBSP lacks func_group support. If the brush had the detail flag, tie to func_detail instead.
I added func_group support to my VBSP fork, YBSP.
Q3Map2 entities
misc_model
Usually prop_static, unless there is a target KV, in which case it should be a prop_dynamic parented to the specified entity.
Most small or medium-sized misc_models are lit about the same as prop_static (with Q3Map2 doing bounced lighting on them like CSGO), but misc_models with forcemeta can be lightmapped the same way as brushes, unlike Source; see notes below for spawnflag 4.
Collisions are usually done via clip brushes; use Propper++ if you want to convert them to $collisionmodel. Oftentimes it may be preferable to create a new collision mesh for the prop instead.
- Keyvalues
- Tie to bmodel (target, _target) <targetname>
- Ties the model to the named brush entity instead of being part of worldspawn. Instead of using prop_static, use prop_dynamic and parent to the specified entity.
- Remap material (_remap*) <string>
- Format
"original_material;new_material"
.
The first material is replaced with the second material in the compiled map (usually used for misc_model). Use skins.
- Spawnflags
Auto-clip model : [2, 8, 16, 128, 256, 512, 1024, 2048, 4096]
- If any combination of these are enabled, they have collision automatically generated collision, so make sure the ported prop has a $collisionmodel. You can decompile the map to get the autoclipped geometry, but you probably only want to do that for large terrain meshes.
Force meta : [4]
- Decompose to "metasurfaces", allowing it to be lightmapped.
- (in any branch) - Subdivide each convex face of the mesh, being careful not to change the overall topology (don't add verts to "curved" edges). Lighting is done per-vertex, so increasing the number of vertices results in more accurate lighting, and a dense enough mesh can be more accurate when vertex lit than when lightmapped.
- If $lod is available for the engine branch, consider having two versions of the subdivided mesh: one with heavy subdivision for the default close-up mesh, and one with much less subdivision for further away. For example, a simple rectangular prism (ex: fence post) could be subdivided on the long sides with 12x3 faces for the close up mesh, and 7x2 faces for the
$lod 50
mesh (potentially using loop cuts, so that the short sides are subdivided evenly).
- If $lod is available for the engine branch, consider having two versions of the subdivided mesh: one with heavy subdivision for the default close-up mesh, and one with much less subdivision for further away. For example, a simple rectangular prism (ex: fence post) could be subdivided on the long sides with 12x3 faces for the close up mesh, and 7x2 faces for the
- (in and ) - Make all of the model's UVs fit onto one material with no overlap or tiling, then use a static prop lightmap.
- (in any branch) - Do the same UV edits as above, but pre-bake the lighting in Blender (possibly onto a detail texture with $detailblendmode 8 or Modulate mesh). Use UnlitGeneric instead of VertexLitGeneric to prevent VRAD lighting from conflicting with the Blender lighting. Note that this will cause the model to be unaffected by most dynamic lights except for flashlights and CSM.
- (in any branch) - Use OBJ2MAP or similar to convert the model to brushwork (only if the model is simple enough!). This can work around the lack of bounced static prop lighting on pre- versions of VRAD.
Color to Alpha : [32]
- The RGB vertex colors in the source model represent vertex alpha instead of vertex color. If you can, remake the geometry as displacements; otherwise, bake the blending into a megatexture.
_decal
info_projecteddecal… sort of.
_decal is a brush entity (patch mesh entity, rather), but it works similarly.
- Keyvalues
- target (target) <targetname>
- Entity to project towards the origin of. Use some math to determine the angles and Distance KVs.
_skybox
- Keyvalues
- Scale (_scale) <float>
- scale of sky_camera.
light
If no target: light If target: light_spot
- Keyvalues
- Color (_color) <color1>
- Light color; convert from Color1 to Color255 and make part of _light.
- Brightness (light) <integer>
- Light intensity; make part of _light.
- Spawnflags
Linear attenuation : [1]
- Uses linear attenuation instead of inverse square… except if compiled in -wolf mode, in which case it uses inverse square instead of linear.
lightJunior
N/A
Only affects dynamically lit models, and does not use an edict. Source 1 and its BSP format technically supports this, but the compilers lack a way to set it, so you'd have to manually edit/replace the WORLDLIGHTS and WORLDLIGHTS_HDR lumps.
Quake 3 entities
These can be found in most games
info_null
This is usually the same thing. The exception is in WolfET, where the entity is kept around for a tick longer than usual. This is done to allow game entities to target the point; to mimic this behavior, use an info_target, and killtarget the it with a logic_auto 0.1 seconds after map spawn.
info_notnull
Works the same way; Valve decided to rename the entity in GoldSrc.
target_kill
point_hurt via Hurt input, with DamageTarget set to !activator (if no target OR if spawnflag 1 enabled)
Kill input of target entity (if has target and spawnflag 1 disabled)
If no target, deals 100000 hit points to the activator.
- Keyvalues
- Target to kill (target) <targetname> (only in RtCW, WolfET)
- killtarget the specified entity instead of hurting the player.
- Spawnflags
Kill user too : [1] (only in RtCW, WolfET)
- Still damage player even if a target is present.
target_position
Same as info_notnull
target_relay
- Spawnflags
Red only : [1]
- Use a filter to prevent the blue team from using this relay.
Blue only : [2]
- Use a filter to prevent the red team from using this relay.
Random target : [4]
- Only triggers one of the targets (they'll all have the same name).
Change the targets to all have different names, and have this relay send a PickRandom input to a logic_case which then uses the OnCase## outputs to trigger the appropriate target.
Since target_relay supports up to 32 targets compared to logic_case's 16, you may need to use three logic_cases, with the first one deciding which of the other two to use.
target_delay
The delay can have a random variance to it, in which case some complicated logic_timer shenanigans may be necessary, probably in conjunction with a logic_case.
target_speaker
target_location
trigger_always
IdTech version is poorly named. It is only fired on map spawn, but does not fire if a map is entered from a level change without starting a new unit. As such, it might be necessary to put a trigger_once around the player spawn if using in singleplayer.
func_static
func_brush, func_wall, or func_wall_toggle
- Keyvalues
- Name (targetname) <string>
- (in RtCW and WolfET) If this entity is triggered, it toggles visibility and collision. Send the Toggle input to this entity to replicate this.
- Flags
Starts Invisible : [1] (only in RtCW and WolfET)
- Starts in the off state. This is the same as func_wall_toggle's spawnflag 1; for func_brush, enable StartDisabled.
func_rotating
- Keyvalues
- Rotation speed (speed) <integer>
- Change to maxspeed.
func_timer
Despite the func_ prefix, this is a point entity.
misc_portal_surface
func_monitor (if has target)
func_reflective_glass (if no target)
linked_portal_door (if navigable)
Point entity which affects the nearest portal surface, which will need to be turned in to the appropriate brush entity.
misc_portal_camera
Target for the misc_portal_surface.
info_player_intermission
info_intermission
point_viewcontrol
Controls camera in between rounds.
team_CTF_redplayer, team_CTF_redspawn
info_player_combine
info_player_axis
info_player_terrorist
info_player_scientist
info_player_teamspawn (RED)
In Quake III (and maybe RtCW?), the team_CTF_*player are initial spawn points, whereas team_CTF_*spawn are respawn points. WolfET always uses the latter; toggling them based upon conditionals.
In RtCW and WolfET, red is Axis (German), and blue is Allied (American).
team_CTF_blueplayer,team_CTF_bluespawn
info_player_combine
info_player_allies
info_player_counterterrorist
info_player_marine
info_player_teamspawn (BLU)
See above
Wolfenstein entities
corona
In RtCW and WolfET. Scale is loosely relative to r_flaresize, which defaults to 40. Multiplying scale by 40 should yield VerticalGlowSize/HorizontalGlowSize.
dlight
light_dynamic (if possible) light (otherwise)
Flickering light. Unlike light_dynamic, custom lightstyles are supported, so it may be necessary to use a real light instead.
Also, there are some additional preset lightstyles (19 instead of 13), so yeah.
- Keyvalues
- Preset lightstyle (style) <integer choices>
- Various preset lightstyles. Some of them are in Source, but not all.
Wolf | Style string | Source | notes |
---|---|---|---|
1 | mmnmmommommnonmmonqnmmo |
1 | |
2 | abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba |
2 | |
3 | mmmmmaaaaammmmmaaaaaabcdefgabcdefg |
3 | |
4 | ma |
4 | Source version is longer, but repeats itself, so result is identical |
5 | jklmnopqrstuvwxyzyxwvutsrqponmlkj |
5 | |
6 | nmonqnmomnmomomono |
6 | |
7 | mmmaaaabcdefgmmmmaaaammmaamm |
7 | |
8 | aaaaaaaazzzzzzzz |
9 | |
9 | mmamammmmammamamaaamammma |
10 | |
10 | abcdefghijklmnopqrrqponmlkjihgfedcba |
11 | |
11 | mmnommomhkmmomnonmmonqnmmo |
N/A | |
12 | kmamaamakmmmaakmamakmakmmmma |
N/A | |
13 | kmmmakakmmaaamammamkmamakmmmma |
N/A | |
14 | mmnnoonnmmmmmmmmmnmmmmnonmmmmmmm |
N/A | |
15 | mmmmnonmmmmnmmmmmnonmmmmmnmmmmmmm |
N/A | |
16 | zzzzzzzzaaaaaaaa |
N/A | close enough to style 9, if you want to use that |
17 | zzzzzzzzaaaaaaaaaaaaaaaa |
N/A | |
18 | aaaaaaaazzzzzzzzaaaaaaaa |
N/A | |
19 | aaaaaaaaaaaaaaaazzzzzzzz |
N/A |
- Custom lightstyle (stylestring) <string>
- A custom lightstyle (like light's pattern)
- String offset (offset) <integer>
- Offset the starting point of the lightstyle. Move one minus this number to the end of the string.
- Attenuation (atten) <integer>
- Add or subtract this value from each character in the string. stylestring of "ddeeffzz" with an atten of -1 would result in "ccddeeyy".
func_explosive
- Flags
Use shader : [4]
- Uses the materials found on the original brush entity's geometry for debris instead of basing on the type of debris. You'll need to make custom gib models. Since func_breakable doesn't support custom gibs, you can use env_shooter, but it might be easier to make an invisible prop_dynamic that gets destroyed when the func_breakable does.
misc_gamemodel
If animated and/or has targetname/scriptname: prop_dynamic If single-frame and lacks targetname/scriptname: prop_static, with per-vertex lighting disabled
In RtCW and WolfET. Source 2013 doesn't completely support arbitrary vertex animation, so animated MD3s or MDCs will need to be re-animated with a skeleton. If unnamed and not animated, it is only an edict for as long as info_null entities are, becoming effectively the same as misc_model_static, described below.
script_model_med
monster_generic or generic_actor
In RtCW and WolfET. A model which has its animations and movement defined in an external script file.
team_WOLF_checkpoint
In WolfET. A checkpoint, flag, command post, or control point; whatever you want to call it.
- Displays models/multiplayer/flagpole/flagpole.md3 if no model is defined, and plays sound/movers/doors/door6_open.wav during capture animation.
- Any spawnpoints that are targeted (target KV) by this entity are only active while the point is in the respective team's control.
- Unlike the DoD:S equivalent, this model is solid, so cover the pole with a small rectangular func_detail using a nodraw material with a metal $surfaceprop.
props_chair
prop_physics with ported version of models/furniture/chair/chair_office3.mdc, including gibs via $collisiontext
- Keyvalues
- Health (health) <integer>
- Default 10
props_chair_hiback
prop_physics with ported version of models/furniture/chair/hiback5.mdc, including gibs via $collisiontext
- Keyvalues
- Health (health) <integer>
- Default 10
props_chair_hiback
prop_physics with ported version of models/furniture/chair/sidechair3.mdc, including gibs via $collisiontext
- Keyvalues
- Health (health) <integer>
- Default 10
props_skyportal
Raven Software entities
misc_model_static
prop_static, with per-vertex lighting disabled.
In Jedi Academy. Like misc_model, but the model is rendered as a runtime entity, instead of baked into the map geometry. If you want to be accurate to how this affects lighting, you could disable per-vertex lighting.
misc_model_ghoul
In Jedi Outcast and Jedi Academy. Arbitrary animated GLM model; destroyable.
misc_model_*
In Raven Software games. Specific MD3 model to display at runtime, sometimes animated; see DEF or ENT entity description file for model path and usage specifics.