set light's custom pattern if needed, and whether it will be initially dark
set an entity to trigger the pair. they will be triggered together because of the shared name.
the effect being that the light emitted by the texlight has the same light style as the paired light entity instead of being static, and thus can be toggled with it.
But now that VHLT has light_surface, just use that instead.
Commented 7 months ago2024-06-22 01:03:25 UTC
in wiki page: VERC: Custom DecalsComment #106208
Curious about how the engine differentiates between monochrome and alphatest decals. I've seen (and used) decals that has full colour with the last index being the transparent colour, just like regular { textures. My working theory is that it checks that palette indices 0-254 are monochromatic (black→white or the reverse). If it's neither then it assumes alphatest mode. I think I've also seen decals.wad in the wild that have the palette indices 0-254 all zeroed out (i.e. black all the way), but I haven't loaded them in game and see how the engine interprets that decal.
Glad to have you here, Philip!
Anyway, as I was originally typing...
X and Y scaling should be proportional to the aspect of the base texture. If the base texture is a skinny 16x196 texture then having both X and Y scales be 10 means each tile of the detail texture would be 1.6 by 19.6 pixels relative to the base. If you can't tell, this is horribly, horribly stretched.
Sadly there exists no tool today afaik that can easily plug in the aspect ratio values to you.
Commented 9 months ago2024-05-16 17:25:22 UTC
in vault item: sewagex3Comment #106179
Really stinkin beautiful with the brushwork detail! It might hinder playability but ya can't deny it's a very cool place to gawk at things. Especially that gantry crane, gyatt damn!
This comment was made on an article that has been deleted.
Commented 9 months ago2024-05-01 05:21:10 UTC
in wiki page: func_conveyorComment #106169
The scroll speed of scroll* textures for the entities are encoded in a hacky way by hijacking FX Color (rendercolor) and you can control the speed of scroll* textures in any brush entity, and even change them with env_render (I tested, it works! 😁)
An algorithm you can use is:
R - 0 if positive, 1 if negative
G - abs(speed) // 16 (floor division)
B - floor( abs(speed) * 16 ) % 256 (modulo or remainder)
DO NOT USE trigger_auto on the second map. trigger_auto fires only once. DO USE instead "change target" in trigger_changelevel of the first map to fire eleend_mm on the second level. This makes it repeatable and reliable.
If the elevator is to be used both ways, the reverse setup is also needed.
If you want to study how Valve does it, use newbspguy and open any Half-Life map with elevator changelevels.
^ Crowbar is only a frontend for whichever studiomdl you choose. The problem you're facing seem to be errors with the .qc file referencing smd files that doesn't exist.
I feel like 2 of the toolbars need to be explained as well, as they've been a lot of cases of people accidentally having IG/TL/SL/UVL on, and getting confused... Ideally they should've RTFM but it wouldn't hurt drawing attention on the important ones.
Commented 10 months ago2024-03-28 09:56:50 UTC
in wiki page: momentary_rot_buttonComment #106092
Findings:
Door hack flag makes the entity un-use-able but solid (default is useable but not solid)
Not useable flag has no effect [not implemented?]
[bug] the entity only works well with positive distance (clockwise opening). Negative distance makes the internal value "start open". The linked momentary_door will always be opening when the momentary_rot_button moves clockwise and vice versa.
solution: have all linked momentary_rot_buttons have positive distance, and rotate the entity's yaw 180 degrees to make it spin counterclockwise (and now lighting needs to be taken to consideration)
[bug] [Related with negative distance also,] if there are 2 or more linked momentary_rot_buttons and the other has different signed distance then the other button will keep spinning past the end (and the internal ratio value would go past the 0 ≥ x ≥ 1 range)
solution: same as above
If 2 or more linked momentary_rot_buttons have different distance/speed the one being USEd will dictate the speed and distance of the others. Then when it reaches the full distance all the others will snap to their fully opened/closed positions.
As per RUST: Creating Proximity Doors triggering the momentary_rot_button every 0.1s does move it at the prescribed speed, but if "auto return" is not set it'd just continually ping-pong between opening and closing.
[2024-06-05]
This is common knowledge amongst pro mappers but the momentary_* setup is used on Uplink and Blue Shift for the dialing-in sequences through an off-the-playable-area setup where the momentary_doors push a func_pushable through several trigger_multiples that have "pushables" flag set. One of them is the "correct, dialed in" position, the others unset it.
One very basic application for this that I can think of is replicating HL2 Route Kanal sliding gate setup locking at its open position by having a trigger_once at the very end of the momentary_door, and when the func_pushable touches it, kills the momentary_* entities and replaces them with func_wall_toggles of the setup frozen at their final positions.
Commented 10 months ago2024-03-26 01:06:50 UTC
in wiki page: activatorComment #106087
In vanilla SDK, there is no way for any entity to specify the activator in the target field. However in Spirit of Half-Life, Sven Coop, and Featureful, you can use these special names:
Commented 11 months ago2024-03-11 06:35:21 UTC
in vault item: BoredComment #106059
I found a server that has cardboard maps, just not this exact map. High probability it's using textures from this map. Very cool concept overall. I just wish more servers host cool maps.
To trigger the same target multiple times, subsequent keys should be suffixed with #N where N is a number. This is simply because key names need to be unique to be exported to .map properly. The game code drops the suffixes when reading the entity keyvalues.
Commented 11 months ago2024-02-29 00:09:02 UTC
in wiki page: path_cornerComment #106019
Fun fact: the logic of picking movement waypoints of a func_train is entirely within func_train itself. It is therefore possible to make a valid path with other entities mixed in. I've successfully mixed path_corner's with momentary_doors like this:
path_corner (`p1`)
target = m1
wait = 0
spawnflags = Teleport (2)
momentary_door (`m1`)
target = p2
wait = 0
path_corner (`p2`)
target = m2
wait = 0
spawnflags = Teleport (2)
momentary_door (`m2`)
target = p1
wait = 0
I can then use momentary_rot_button to move the momentary_door's around and vary the distance the func_train has to travel.
It is a setup for an experiment where I can vary the time a func_train spends on one part of the map vs the other because it's being used to occlude LOS between me and a monster to test its AI schedule but that's off topic.
But you can likewise use it to have dynamically timed sequence with the mom_doors and func_train's off the playable areas.
My theory is that func_train's check the keyvalues of the entities it uses as paths (usually path_corner's) without checking that their classname is actually path_corner. You can therefore use any entity as long as it has keyvalues that concur with that of path_corner's: a target, optionally a wait, message (fire on pass) or speed, and spawnflags that don't conflict with that of a path_corner (therefore flag 1 will stop the func_train, flag 2 will teleport, etc.)
[2024-09-22] Most monsters use "target" to patrol `path_corner`s. Should denote all attributes on whether they apply to [Apaches/Ospreys/Monsters/Trains].
[2024-09-23]
List of monsters that patrols path_corners in their target kvs:
A way to place/reuse the model multiple places in the map. Maybe a point entity that targets the main func_ entity, inheriting the func_'s convert_to.
Technically you can do this with MESS that runs after map2prop, but why use 2 tools when 1 tool do job.
Using brush entities that inherit others is actually mighty useful actually, to get the right sizing and positioning in the map. Maybe something like zhlt_usemodel approach is more ideal. Maybe do both.
More bones 🦴, a way to assign different parts of meshes to different bones, and a way to set bone hierarchy (easy enough using target keyvalue)
A way to create separate meshes (i.e. separate bodygroup parts) that is later combined into a single model. Probably separate entities that has a shared keyvalue (like MESS). Probably needs a way to set the main entity from the group too (also like MESS).
Commented 11 months ago2024-02-23 10:56:45 UTC
in wiki page: game_textComment #106006
There should be more information about character sets: what the game supports, how to get the best results on displaying most languages in whatever charset env is necessary (like VNs requiring shift-jis system charset).
Decided to test for myself.
Vanilla Half-Life's text engine seem to be broken for anything that's not ASCII. It consumes single-byte character sets (presumably ANSI/Windows-1252/system locale) but the text rendering is consuming UTF-8. This results in the broken text consistent with the table in this page: https://www.i18nqa.com/debug/utf8-debug.html
Haven't looked at the other SDKs or engines (candidates include Updated/Unified/Featureful/Xash-fwgs/Pathos) on how they handle text. Hopefully better than the unrecoverable mess vanilla is in right now.
ALSO, JACK will purposefully mangle non-ASCII texts. You'd need to edit the .map directly and feed it to the compilers yourself.
2024-06-29
apparently HLCSG also needs -notextconvert argument. sauce: singularmurderer
Back from AFK, got HL and JACK back and working again.
I tested light_surface and it works exactly as I expected, proving the description is indeed incorrect. I will pass my test map to you for you to incorporate into this page. (tip: gl_wireframe 1 would be useful when taking screenshots for this map)
Edit 2024-03-17
No correction on the above has been made yet. As of now the information on light_surface page is updated and correct, yet this page is still repeating the outdated and incorrect information.
Can you test the difference between light_surface's Filter max range [_frange] and Filter max dist to plane [_fdist]? I know what the words mean, but the description seem to contradict my understanding of the meaning of planes and how they work.
I have a few test case ideas:
A wall of tiling 16x16 brushes textured with a texlight.
_frange should make only a disk of those brushes around the light_surface emit light.
_fdist, if my interpretation of plane is correct, should light up all of them since the normal distance of all the faces to the plane is identical even if they're infinitely far away. That's the nature of planes.
Similar setup to the above but the next row above recedes 16u behind the previous row, producing a staircase. Place light_surface in the middle of this flight of stairs.
_frange should produce a sphere of lit up faces.
_fdist, if my interpretation of plane is correct, should have all faces on the same row light up until a certain distance away from the entity because again, all of them should have same normal distance to the plane.
Unfortunately I can't do these tests myself right now as my drive did a resonance cascade and I'll be afk for a couple of days.
You could probably fit all 1100 colours if you use just the hex values for names e.g. COLOR<RRGGBB>. Has the unintended side effect of the alphabetical sort being quite logical too as it sorts by hex values.
Commented 1 year ago2024-02-15 14:37:55 UTC
in wiki page: monster_human_gruntComment #105982
^ Spawn one with a shotgun. HECU shotgunners always wear balaclavas.
[2024-08-25] I tried a weird weapon combo of just handgrenades (2) but it doesn't work as I expected:
Weapon clip amount defaults to AR's (36)
Ranged attack defaults to shotgun shot, even if grunt doesn't have one
So the guy ended up being way more OP than regular shotgunner.
Also, version 1.2 just dropped. This adds support for extended static lifts, and functional lifts that start already extended.
I highly recommend updating your local copy to this version.
The sit1 animation in barney.mdl is one of the special ones which contain sequence event ID 1003s. These will try to trigger entities in your maps, and this could be unintentional. It's important to check with Half-Life Asset Manager (modern, feature-rich descendent of HLMV. Use it instead of HLMV) for these events in the animation you want to use. If such events exist, then you can either:
Take advantage of it by naming entities you want to get triggered as part of the choreography, just like introchair, or
Avoid naming any entity in the map with the options value of the event[s]
Commented 1 year ago2024-01-17 02:08:35 UTC
in wiki page: monster_bullchickenComment #105884
The cooldown between spits is apparently reset when it loses sight of you, so you can cheese the bullsquid to turbo-spit you by timing the LOS between you and the bullsquid; immediately block LOS on or after the frame where the projectile spawns, then immediately unblock LOS the next frame (maybe even the same frame)
Commented 1 year ago2024-01-13 00:20:03 UTC
in wiki page: VERC: Doors With GlassComment #105869
I discovered a trick with using BOUNDINGBOX brush which eliminates the lip math. You make it the same width as the main door and tie it to the glass part. No messing with lip value for the glass door; use the same value as the main door.
I wrote a short journal entry on how all 15 lumps relate to each other. I used the relational model to visualize it.
Because the referencing of entries by other entries is done with indices into the lump using mostly 16-bit shorts, it places a hard limit on how many of the target lump's entries can exist before their indices becomes out of bounds for the data types used. In addition, Carmack makes a few of these data types do double (sometimes triple) duty e.g. positive values refer to one type, negative values means entirely different type, and 0 means null, so that halves the capacity of a type's max index. clipnodes suffer the most from this; an entire half (the negative half) of addressable values in 2^16 is used to assign only 2 significant values -1 and -2.
I've incorporated the information into the first section of this page. You can read the table as:
The resource A has a limit of X because it is referenced by JKL with data type T, using [Remark]
The resource clipnodes has a limit of 32768 because it is referenced by other clipnodes with data type short, using positive values > 0
This version of the map format is colloquially known as Valve20 to differentiate from the original Quake version
Valve20 is now the de-facto map format all Quake-based and Quake-derived editors and compilers support due to the precision in texture alignment
TrenchBroom uses the OS's clipboard for copy and paste (not the case with JACK/VHE3.x) and uses the map format to represent brush & entity data to be pasted. It also means clipboard-based IPC can be done using the map format.
Commented 1 year ago2024-01-06 06:19:43 UTC
in wiki page: func_detailComment #105850
What I can gather from the community's collective wisdom:
func_detail does not reduce world leaves
func_detail instead reduce VIS portals generated by HLBSP. if without it HLBSP makes VIS portals around detail geometry, with it it just treat the surrounding area as a single VIS leaf
func_detail is gone at the end of HLBSP, and is world geometry after that point
hence HLRAD cannot treat it in any way other than opaque world brush because it's gone by the time it's run
Commented 1 year ago2024-01-05 12:12:36 UTC
in wiki page: func_tracktrainComment #105848
Some findings about func_tracktrain:
wheels distance is only measured forward from origin. To make the train travel as much on the path as possible, the origin needs to be located at the center of the back axle.
wheel distance defaults to 100.
target of a path_track is fired when the origin passes the path_track.
the position and angle is set wrt the origin point as follows:
trace a line forward.
if there's enough distance to the end of the current path, keep heading
if wheel distance > distance to next path, subtract current distance to next path, then iterate the path forwards until the distance fits the path. the point where distance is 0 is the new heading.
origin moves forward
angle is adjusted to point to the heading. this will in all cases be shorter than wheel distance; the sharper the curve the more noticeable. this also means the front wheel part will always overshoot the path. but the origin is guaranteed to always be on the path.
[2024-05-12] While I am a proponent of the origin at the back axle, more realistically moving trains, I can see how it is totally incompatible with track [auto]changers. Gotta have to pick your poison, I guess.
[2024-05-13] Also, a tutorial for track trains is needed.
[2024-07-10] You can control a func_tracktrain remotely using game_counter_set entities. Value 1 throttles up one notch, -1 down a notch.
It'd be pretty cool to use the visgroups to assign attribution e.g. all of sir's prefabs is assigned a visgroup to his name. This is to comply with the "BY" aspect of the CC license.
textures can be scaled as need because now lightmap can be recalculated after any changes.
You still need to be careful because the maximum lightmap size for a face is apparently 16x16 luxels. A lot of faces you'll find in maps are already at 16 luxels on either (or both) sides. GoldSrc doesn't support lightmaps larger than that size, and scaling down a texture that results in a face with lightmaps over that size crashes the engine. (IDK if it's supported on svengine). Hence my verdict is don't do it.
As for vertex editing, I just don't recommend it at all too. It's way more cumbersome, and way way harder to get satisfactory result than to get completely broken result. I honestly don't know how a face whose vertices are non-planar would act inside the game. If there's face splitting ability in world faces and easier vertex shifting via handles vs textboxes then it might be feasible, but still not recommended because of the non-planar thing. *
The main takeaway is that just because it's doable with the BSP structure doesn't mean the game engine that's going to parse and run the BSP would like it. If the game engine doesn't like it, don't do it.
I still don't have any draft for a part 2 of this tutorial. 😅
EDIT 1: * Tested face vertex editing. It messes up lightmaps elsewhere on a map.
From reading the code it seems that sv_skyvector_* and sv_skycolor_* are the culprits of models forcibly taking the sky's color, because from looking at texlight data itself there's nothing to discern sky light from normal light. The engine probably trace a vector set in sv_skyvector_* from the origin (feet) and if it hits the sky texture, overrides the model's lighting with the sv_skycolor_*.
sv_skycolor_* is read from the brightness value of light_environment at map load, and sv_skyvector_* from the entity's angle also at map load.
[2024-09-12] I think I solved the black_hidden debacle. It's hidden as world brush BUT visible when made part of a brush entity. the folks who saw the texture probably didn't realize that it won't work on entities.
[2024-09-15] A primer about origin would be good. Models whose origin are inside the walls won't get lighting and be rendered black, and a way to shift it with QC and HLAM. Additionally, a way to have wall-mounted models take lighting from the walls instead of the floor when you shine a flashlight around, for example. I touched on the latter in my tutorial about model health/hev chargers.
Trivia: It's preset 10 (flourescent flicker) that made the news about how the lighting presets survived all the way from Quake to Half-Life Alyx unchanged.
Commented 1 year ago2023-12-16 12:33:41 UTC
in wiki page: Tutorial: Hint BrushesComment #105743
Relaying other member's comment on this page: a top-down view of the setup was sorely needed. In that aspect the Tutorial: Total Map Optimisation Part 2 (VIS, Hints) page is much more helpful (and much more thorough tbh).
Commented 1 year ago2023-12-16 12:02:30 UTC
in wiki page: SKY textureComment #105742
I found that compiling with VHLT will make sky lighting not work on sky brushes that aren't all textured with sky texture, making that particular brush not emit skylight.
It's also particular about having different sky "ceiling" brushes at different levels. Hard to explain why; I think it can only emit light from one side, and so having one sky brush act as both wall and ceiling of a skybox makes it only emit light on the wall side. So it might mean one sky brush emits light on only one face.
My solution was to have rooms with sky be at only one ceiling level each.
func_wall
's style to-3
light
's custom pattern if needed, and whether it will be initially darkBut now that VHLT has light_surface, just use that instead.
{
textures. My working theory is that it checks that palette indices 0-254 are monochromatic (black→white or the reverse). If it's neither then it assumes alphatest mode. I think I've also seen decals.wad in the wild that have the palette indices 0-254 all zeroed out (i.e. black all the way), but I haven't loaded them in game and see how the engine interprets that decal.Anyway, as I was originally typing...
X and Y scaling should be proportional to the aspect of the base texture. If the base texture is a skinny 16x196 texture then having both X and Y scales be 10 means each tile of the detail texture would be 1.6 by 19.6 pixels relative to the base. If you can't tell, this is horribly, horribly stretched.
Sadly there exists no tool today afaik that can easily plug in the aspect ratio values to you.
scroll*
textures for the entities are encoded in a hacky way by hijacking FX Color (rendercolor) and you can control the speed ofscroll*
textures in any brush entity, and even change them with env_render (I tested, it works! 😁)An algorithm you can use is:
0
if positive,1
if negativeabs(speed) // 16
(floor division)floor( abs(speed) * 16 ) % 256
(modulo or remainder)DO USE instead "change target" in trigger_changelevel of the first map to fire eleend_mm on the second level. This makes it repeatable and reliable.
If the elevator is to be used both ways, the reverse setup is also needed.
If you want to study how Valve does it, use newbspguy and open any Half-Life map with elevator changelevels.
0 ≥ x ≥ 1
range)[2024-06-05]
This is common knowledge amongst pro mappers but the momentary_* setup is used on Uplink and Blue Shift for the dialing-in sequences through an off-the-playable-area setup where the momentary_doors push a
func_pushable
through severaltrigger_multiples
that have "pushables" flag set. One of them is the "correct, dialed in" position, the others unset it.One very basic application for this that I can think of is replicating HL2 Route Kanal sliding gate setup locking at its open position by having a
trigger_once
at the very end of the momentary_door, and when the func_pushable touches it, kills the momentary_* entities and replaces them withfunc_wall_toggles
of the setup frozen at their final positions.!activator
(SC, Featureful)*locus
(SoHL, Featureful)Addendum
To trigger the same target multiple times, subsequent keys should be suffixed with#N
where N is a number. This is simply because key names need to be unique to be exported to .map properly. The game code drops the suffixes when reading the entity keyvalues.boop
0.01
boop#1
0.5
boop#2
0.9
boop#3
1.2
boop#4
1.4
boop#5
1.5
boop
.If you're already past that then resize to multiples of 16.
Protip: use a calculator.
func_train
is entirely withinfunc_train
itself. It is therefore possible to make a valid path with other entities mixed in. I've successfully mixedpath_corner
's withmomentary_doors
like this:target
=m1
wait
=0
spawnflags
= Teleport (2)target
=p2
wait
=0
target
=m2
wait
=0
spawnflags
= Teleport (2)target
=p1
wait
=0
momentary_door
's around and vary the distance thefunc_train
has to travel.It is a setup for an experiment where I can vary the time a
func_train
spends on one part of the map vs the other because it's being used to occlude LOS between me and a monster to test its AI schedule but that's off topic.But you can likewise use it to have dynamically timed sequence with the mom_doors and
func_train
's off the playable areas.My theory is that
func_train
's check the keyvalues of the entities it uses as paths (usuallypath_corner
's) without checking that their classname is actuallypath_corner
. You can therefore use any entity as long as it has keyvalues that concur with that ofpath_corner
's: atarget
, optionally await
,message
(fire on pass) orspeed
, andspawnflags
that don't conflict with that of apath_corner
(therefore flag 1 will stop thefunc_train
, flag 2 will teleport, etc.)[2024-09-22] Most monsters use "target" to patrol `path_corner`s. Should denote all attributes on whether they apply to [Apaches/Ospreys/Monsters/Trains].
[2024-09-23]
List of monsters that patrols path_corners in their target kvs:
target
attribute in their pages. For all others, also need to update thattarget
does nothing.[2024-10-07]
convert_to
.zhlt_usemodel
approach is more ideal. Maybe do both.target
keyvalue)Decided to test for myself.
Vanilla Half-Life's text engine seem to be broken for anything that's not ASCII. It consumes single-byte character sets (presumably ANSI/Windows-1252/system locale) but the text rendering is consuming UTF-8. This results in the broken text consistent with the table in this page: https://www.i18nqa.com/debug/utf8-debug.html
Haven't looked at the other SDKs or engines (candidates include Updated/Unified/Featureful/Xash-fwgs/Pathos) on how they handle text. Hopefully better than the unrecoverable mess vanilla is in right now.
ALSO, JACK will purposefully mangle non-ASCII texts. You'd need to edit the .map directly and feed it to the compilers yourself.
2024-06-29
apparently HLCSG also needs
-notextconvert
argument. sauce: singularmurdererI tested light_surface and it works exactly as I expected, proving the description is indeed incorrect. I will pass my test map to you for you to incorporate into this page. (tip:
gl_wireframe 1
would be useful when taking screenshots for this map)Edit 2024-03-17
No correction on the above has been made yet. As of now the information on light_surface page is updated and correct, yet this page is still repeating the outdated and incorrect information.I have a few test case ideas:
COLOR<RRGGBB>
. Has the unintended side effect of the alphabetical sort being quite logical too as it sorts by hex values....maybe I should attempt this myself.
[2024-08-25] I tried a weird weapon combo of just handgrenades (2) but it doesn't work as I expected:
Also, version 1.2 just dropped. This adds support for extended static lifts, and functional lifts that start already extended.
I highly recommend updating your local copy to this version.
I might have to take a look at the template and do the fix again.
sit1
animation in barney.mdl is one of the special ones which contain sequence event ID 1003s. These will try to trigger entities in your maps, and this could be unintentional. It's important to check with Half-Life Asset Manager (modern, feature-rich descendent of HLMV. Use it instead of HLMV) for these events in the animation you want to use. If such events exist, then you can either:introchair
, orBOUNDINGBOX
brush which eliminates the lip math. You make it the same width as the main door and tie it to the glass part. No messing with lip value for the glass door; use the same value as the main door.Because the referencing of entries by other entries is done with indices into the lump using mostly 16-bit shorts, it places a hard limit on how many of the target lump's entries can exist before their indices becomes out of bounds for the data types used. In addition, Carmack makes a few of these data types do double (sometimes triple) duty e.g. positive values refer to one type, negative values means entirely different type, and 0 means null, so that halves the capacity of a type's max index. clipnodes suffer the most from this; an entire half (the negative half) of addressable values in 2^16 is used to assign only 2 significant values -1 and -2.
I've incorporated the information into the first section of this page. You can read the table as:
[2024-05-12] While I am a proponent of the origin at the back axle, more realistically moving trains, I can see how it is totally incompatible with track [auto]changers. Gotta have to pick your poison, I guess.
[2024-05-13] Also, a tutorial for track trains is needed.
[2024-07-10] You can control a
func_tracktrain
remotely usinggame_counter_set
entities. Value1
throttles up one notch,-1
down a notch.As for vertex editing, I just don't recommend it at all too. It's way more cumbersome, and way way harder to get satisfactory result than to get completely broken result. I honestly don't know how a face whose vertices are non-planar would act inside the game. If there's face splitting ability in world faces and easier vertex shifting via handles vs textboxes then it might be feasible, but still not recommended because of the non-planar thing. *
The main takeaway is that just because it's doable with the BSP structure doesn't mean the game engine that's going to parse and run the BSP would like it. If the game engine doesn't like it, don't do it.
I still don't have any draft for a part 2 of this tutorial. 😅
EDIT 1:
* Tested face vertex editing. It messes up lightmaps elsewhere on a map.
sv_skyvector_*
andsv_skycolor_*
are the culprits of models forcibly taking the sky's color, because from looking at texlight data itself there's nothing to discern sky light from normal light. The engine probably trace a vector set in sv_skyvector_* from the origin (feet) and if it hits the sky texture, overrides the model's lighting with the sv_skycolor_*.sv_skycolor_*
is read from the brightness value oflight_environment
at map load, andsv_skyvector_*
from the entity's angle also at map load.[2024-09-12] I think I solved the black_hidden debacle. It's hidden as world brush BUT visible when made part of a brush entity. the folks who saw the texture probably didn't realize that it won't work on entities.
[2024-09-15] A primer about origin would be good. Models whose origin are inside the walls won't get lighting and be rendered black, and a way to shift it with QC and HLAM. Additionally, a way to have wall-mounted models take lighting from the walls instead of the floor when you shine a flashlight around, for example. I touched on the latter in my tutorial about model health/hev chargers.
P.S. it was a 4 but 1 star had to be docked because I can't eat the cookies 🚫🍪😭
This tutorial definitely needs a part 2 for the more advanced tasks e.g. vertex manipulation, bsp import/export, lightmap editing.
It's also particular about having different sky "ceiling" brushes at different levels. Hard to explain why; I think it can only emit light from one side, and so having one sky brush act as both wall and ceiling of a skybox makes it only emit light on the wall side. So it might mean one sky brush emits light on only one face.
My solution was to have rooms with sky be at only one ceiling level each.