News | Forum | People | FAQ | Links | Search | Register | Log in
Mapping Help
This is the place to ask about mapping problems, techniques, and bug fixing, and pretty much anything else you want to do in the level editor.

For questions about coding, check out the Coding Help thread: https://www.celephais.net/board/view_thread.php?id=60097
First | Previous | Next | Last
Yeah 
sometimes it the simple things.
Man, i really got rebb to sweat on this, i can tell you!

Sorry rebb! 
Optimizing Quake Maps 
Hi, can anyone point me in the direction of some literature that covers proper brushwork and bsp optimization?

In other words, I'm looking for ways to get the most (most being brushes, models, etc) out of bsp1.

I think max verts is around 65k, not sure about models and other things.

I'm thinking about converting a majority of the complex geometry into static meshes giving me more room for brushes. Is this a bad idea? What are the drawbacks?

Also, is there any way control how faces are split?

As I said, I just want to find the best way to maximize every little bit of space in bsp1, completely fill it to the brim in the most efficient, optimized way possible.

Any input would be greatly appreciated.

Thanks! 
 
I'm thinking about converting a majority of the complex geometry into static meshes giving me more room for brushes. Is this a bad idea? What are the drawbacks?
Sort of a bad idea. Static meshes in quake don't really blend in with the rest of the level the way they do in modern (or even semi modern) games. They also don't have any collision.
You can use .bsp files as models though. This is a better solution as you get proper collision and it will blend in with the map but the lighting will not match unless you light the bsp model in a way that matches the area in the map in which you're placing it. Also you can't rotate them without breaking collision (eg: if you rotate a bsp model, you loose collision)

Also, is there any way control how faces are split?
Nope. 
:( 
Ah, thanks necros, I was afraid that's how static meshes would behave.

I'm trying to avoid going bsp2 simply because I want maximum compatibility with the variety of ports that are currently used...

...however, having 120k+ verts in a single map would be pretty sweet...

After running around with r_wireframe 1 I noticed some faces are split in undesirable ways. I'm pretty sure many brushes could be reshaped in such a way that I get better splits... 
Things To Try 
Merge textures on large faces; upscale the textures on bigger surfaces that are out of sight; separate intersecting geometry (ever so slightly) and/or turn things into brush models - both situation-dependent, may help or actually be counterproductive; use hacks to clone often-used detail brush entities; try -forcegoodtree with rebb's txqbsp mod; don't get carried away when making a map. 
 
also: faces larger than 240x240 will be split every 240 texels, on both axises. So a 256x256 face will be split into 4 faces. Keep that in mind, and add detail in places where the extra face is already going to exist. For example a 240-tall wall brush with a 16-tall trim brush above it will have the same number of faces as a 256-tall brush, but you can put a different texture on the trim and therefore get more detail for no additional faces. 
 
external bsps can help a lot depending on what kind of map you have.

check out my ne_ruins map for some examples of using external bsps.

http://mobile.sheridanc.on.ca/~jonescor/temp/spasm0003.jpg
upper area is external bsp, trim is func_wall
http://mobile.sheridanc.on.ca/~jonescor/temp/spasm0004.jpg

http://mobile.sheridanc.on.ca/~jonescor/temp/spasm0005.jpg
again, trim is func_wall and coffins are external bsp
http://mobile.sheridanc.on.ca/~jonescor/temp/spasm0006.jpg

Note that external bsps will not light up with guns and explosions but then no one (to my knowledge?) complained about the coffins not lighting up, so i reckon as long as you are careful where you do it, it's fine. 
Necros 
is there a working link to the src?
Please, please! 
Sneaky! 
mfx, any model spawning entity will work for this, just put thing.bsp instead of thing.mdl 
Heh 
but its not just this, ijed.
I always wanted to know how the ending sequence works in particular, the slow camera ride and that fog and the awesomeness in general. 
Fair Enough 
 
Mfx 
no, the code isn't included (just the .map file)
here's the camera code and the associated portal trigger scripted entity:
http://pastebin.com/A1fjNpDz (no warranty) 
 
Yeah, Thanks Necros. 
really appreciate that! 
Quake Wiki 
needs so much love. I needed to know a bit of info for some lights (needed the slow pulse style)...

There isn't even a page for the light entity! I really haven't got the first clue about wiki page editing though otherwise I might spend a bit of time on it. 
Re: -forcegoodtreehug 
Very situational when it comes to marksurface improvement, depending on the map it may even increase marksurfs / cause leaks. Use when feeling adventurous or desperate ;) 
Thanks! 
Great advice so far. I'd like to read more about what determines how faces are split so I can make more informed decisions instead of just throwing brushes around.

@necros, I did not know you could use external bsps in that way. I can think of like five instances off the top of my head that I can go back and do that way. Other than not being affected by light from the map or weapons, explosions, etc. are there any drawbacks?



Every link to mapping tuts on quakewiki are dead :\ 
 
they draw slower. I once tried to make a huge purely decorative terrain section into an external bsp. Looked fine, collided fine, got about 10 fps though.

but that was a very extreme case.

if you're just replacing out of the way geometry that is just for looks (like the tops of distant towers or something), then external bsps are the way to go.

they just take more work to set up. you need to be a little careful with your lighting so that it matches up.

a final draw back: skip textures won't be removed when the bsp is loaded as a model.

however, faces removed as part of the qbsp filling process are still removed as a bsp model.
AND faces which are not facing the player don't cause collision.

so you can make concave models whose outside faces are culled:

http://mobile.sheridanc.on.ca/~jonescor/temp/spasm0206.jpg
this is the external model, has a lot of useless faces removed due to bsp culling

http://mobile.sheridanc.on.ca/~jonescor/temp/spasm0207.jpg
as a model, all the skip faces are visible, sadly.

http://mobile.sheridanc.on.ca/~jonescor/temp/spasm0208.jpg
but from the bottom (where the skip face is facing away from the camera) we can't see it, so it looks fine! 
 
they draw slower. I once tried to make a huge purely decorative terrain section into an external bsp. Looked fine, collided fine, got about 10 fps though.

True, the code for drawing brushmodel faces is different than for drawing the world, it might be less optimized and worse if drawing thousands of polys.

http://mobile.sheridanc.on.ca/~jonescor/temp/spasm0207.jpg
as a model, all the skip faces are visible, sadly.


Yes, i never did add proper support to newskip.exe for creating external bsp mapmodels. :( 
Func Walls 
What's the best approach?

All I need is a collection of brushes to appear once triggered, they don't need to do anything.

I think in Q2 it was a behaviour of func_wall; if given a targetname then they would start 'off' and wait to be triggered.

Glancing at the QC, the use function is this, basically;


// change to alternate textures
self.frame = 1 - self.frame;


Not sure what that does... although it makes sense that it would change to different animated +textures. Might have to try that out with some signposting monitors.

Anyway, my though on spawning func walls was to add a spawnflag START_OFF which decouples the startup functions from the creation of the entity if set (and will disable the skin changing).

Is this the optimal method? I assume any entities inside it when its created will become stuck, and if the player can see the thing pop into existence it'll look pretty goofy, but aside from those drawbacks it should work, along with proper collision. 
 
it makes sense that it would change to different animated +textures

That is exactly what it does, it works just like func_button where +<number> swaps to +<alpha>.


As for your question... perhaps just a really fast func_door with start_open and toggle? 
 
"classname" "info_notnull"
"use" "func_wall"
"targetname" "t1"
{
brush
}
 
Thanks 
But the hackery options are going to be pretty high maintenance for what I'm planning. Basically I want to reconstruct large parts of a level once the player reaches a certain point.

Doors I've used before and they work ok, but do have the downside of crushing and moving stuff around.

Writing the entity type into the mapfile / entity entry in editor would work, but if I have, say, 20+ of these and need to modify them then it'll turn into a headache pretty quickly.

From the rambling post before really I'm asking if there are any problems turning on lumps of brushwork during run time. Apparently not.

Only time will tell :) 
 
ijed: if you are using standard progs (or progs that hasn't modified SUB_CalcMove), then as long as the speed setting on the door is high enough that the move would be completed in less than 0.1 seconds, the progs just does a setOrigin() call instead of normal physics movement, so Scampie's suggestion would work fine.

see if (traveltime < 0.1):
void(vector tdest, float tspeed, void() func) SUB_CalcMove =
{
local vector vdestdelta;
local float len, traveltime;

if (!tspeed)
objerror("No speed is defined!");

self.think1 = func;
self.finaldest = tdest;
self.think = SUB_CalcMoveDone;

if (tdest == self.origin)
{
self.velocity = '0 0 0';
self.nextthink = self.ltime + 0.1;
return;
}

// set destdelta to the vector needed to move
vdestdelta = tdest - self.origin;

// calculate length of vector
len = vlen (vdestdelta);

// divide by speed to get time to reach dest
traveltime = len / tspeed;

if (traveltime < 0.1)
{
self.velocity = '0 0 0';
self.nextthink = self.ltime + 0.1;
return;
}

// set nextthink to trigger a think when dest is reached
self.nextthink = self.ltime + traveltime;

// scale the destdelta vector by the time spent traveling to get velocity
self.velocity = vdestdelta * (1/traveltime); // qcc won't take vec/float
};

void() SUB_CalcMoveDone =
{
setorigin(self, self.finaldest);
self.velocity = '0 0 0';
self.nextthink = -1;
if (self.think1)
self.think1();
};


 
Func_detail? 
I'm not quite sure I understand func_detail. Does it just turn the brush into an entity? Is this something that's fairly safe/advantageous to use? Any tips or knowledge on the application of func_detail?

I realized making floor grates/grids from regular brushes is really expensive. Each "hole" is just as pricy as a cube, minus two faces. I went in and removed some from a small room and got about 5k verts back. The effect was cool, especially the way it cast light, but too expensive.

Now that I'm pressed for space I'm going back and seeing how I put high detail in the wrong areas.

From now on, action packed or dark areas will be relatively low detail, while slow, well lit areas will be for the scenic stuff. I know this is a no-brainier but it's also my latest epiphany...lol...

tangent: is it possible for one to manipulated the way light is cast with an "invisible brush", in other words, is there a brush that only effects light, so no visibility, collision, etc.

On could use low detail invisible brushes to cheaply cast light that looks as if its coming from behind a grate and just use a texture with transparency as the grate. I think. 
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.