@ericw, I still think the same way as I did 4 years ago, detect overflows and trivially accept the entity when it happens.
DP can get away with just making these entities visible, as it has a proper deltaing protocol anyway. with the vanilla or fitz protocols you really can't get away with just unconditionally broadcasting ents.
makestatic can be made to work with solid entities by making an invisible clone in ssqc (same modelindex, but the model field clear so it never gets sent). a mod can do this even without mapper assitance.
however, what it can't do is avelocity. the client won't see that field with makestatic, which is what really limits its use in this case.
quake's zone memory is stupid, the hunk too. I could say lots against it, but my chief complaint would be that it breaks valgrind's use-after-free checks.
R U B I C O N R U M B L E P A C K
Re: R U B I C O N R U M B L E P A C K
Ah, I remember reading that somewhere, Spike - yes, sounds like the most appealing approach to me. Thanks for the note MH. I guess dynamically allocating the leafs array would stop any flickering entities, but have the problem that weirdo entities, like the rotator touching many 10s of thousands of leafs, could cause some slowdown during scanning that huge leaf array. Would need benchmarking I guess.
Re: R U B I C O N R U M B L E P A C K
From FTE:Spike wrote:@ericw, I still think the same way as I did 4 years ago, detect overflows and trivially accept the entity when it happens.
DP can get away with just making these entities visible, as it has a proper deltaing protocol anyway. with the vanilla or fitz protocols you really can't get away with just unconditionally broadcasting ents.
Code: Select all
// add an efrag if the node is a leaf
if ( node->contents < 0)
{
if (ent->num_leafs >= MAX_ENT_LEAFS) <------------- Baker: MAX_ENT_LEAFS defined as 16 in FTEQW for Quake
{
ent->num_leafs = MAX_ENT_LEAFS+1; //too many. mark it as such so we can trivially accept huge mega-big brush models.
return;
}
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Re: R U B I C O N R U M B L E P A C K
Of the maps I checked, start.bsp and e1m2.bsp both overflow the 16. With start I think it's the floor covering the entrance to end.bsp, with e1m2 it's the two floor-button-activated pillars after the SK door. I guess the reason the brushes don't disappear (and hence this problem was never really noticed before) is that the areas they're in are small enough that they're always going to be in some visible leaf.Baker wrote:Does that happen often on run-of-the-mill maps?
I didn't bother checking any more as that was enough to confirm that id1 maps need a fix too.
For dynamic allocation you just take a static array of shorts sized at MAX_MAP_LEAFS, write into that, then allocate for real and memcpy over the number of leafnums that were written, so it's one allocation even for the crazy big entities. The obvious downside is address-space fragmentation but in practice it doesn't seem a big deal.
The trivial-accept idea is probably the least invasive way of handling it overall, as a tradeoff against extra net traffic and unnecessarily drawing stuff. Maybe bump the max to 32 to handle the common cases and fall back on trivial-accept for the insane stuff.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
Re: R U B I C O N R U M B L E P A C K
Not too many entities hit the 32. The trivial accept method works very well!
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Re: R U B I C O N R U M B L E P A C K
Well I went ahead and put in the trivial-accept fix into Quakespasm. It's just a one-line change, in SV_WriteEntitiesToClient():
Seems to work perfectly so far.
Code: Select all
for (i=0 ; i < ent->num_leafs ; i++)
if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) ))
break;
+
+ // ericw -- added ent->num_leafs < MAX_ENT_LEAFS condition.
+ //
+ // if ent->num_leafs == MAX_ENT_LEAFS, the ent is visible from too many leafs
+ // for us to say whether it's in the PVS, so don't try to vis cull it.
+ // this commonly happens with rotators, because they often have huge bboxes
+ // spanning the entire map, or really tall lifts, etc.
+ if (i == ent->num_leafs && ent->num_leafs < MAX_ENT_LEAFS)
- if (i == ent->num_leafs)
continue; // not visible
}
Re: R U B I C O N R U M B L E P A C K
glad to see this bug finally vanquished.
Re: R U B I C O N R U M B L E P A C K
I meant to do this earlier, but here's an overview of changes from Quakespasm related to RRP:
(edit: added protocol 666 and lightmaps)
Required:
(edit: added protocol 666 and lightmaps)
Required:
- Protocol 666 (or equivalent high-limit protocol)
- MAX_LIGHTMAPS >= 255, for 128x128 lightmap pages.
- Basic BSP2 support (i.e. able to run Something Wicked)
- These limit bumps:
Code: Select all
#define MAX_MAP_LEAFS 65535 //johnfitz -- was 8192 #define MAX_VISEDICTS 4096 // larger, now we support BSP2 // These are needed for a lot of edicts to fit in the signon buffer. telefragged.bsp has 3390 edicts at map load. #define NET_MAXMESSAGE 64000 /* ericw -- was 32000 */ #define MAX_MSGLEN 64000 // max length of a reliable message //ericw -- was 32000 #define MAX_EFRAGS 4096 //ericw -- was 2048 //johnfitz -- was 640 #define MAX_CHANNELS 1024 // ericw -- was 512 /* johnfitz -- was 128 */
- edict_t struct: leafnums must be of type “int”.
- fence texture support ( http://sourceforge.net/p/quakespasm/code/970 , http://sourceforge.net/p/quakespasm/code/972 ). Telefragged.bsp uses them on world surfaces too.
- MAX_ENT_LEAFS to 32, plus this patch:
sv_main.cCode: Select all
- if (i == ent->num_leafs) + + // ericw -- added ent->num_leafs < MAX_ENT_LEAFS condition. + // + // if ent->num_leafs == MAX_ENT_LEAFS, the ent is visible from too many leafs + // for us to say whether it's in the PVS, so don't try to vis cull it. + // this commonly happens with rotators, because they often have huge bboxes + // spanning the entire map, or really tall lifts, etc. + if (i == ent->num_leafs && ent->num_leafs < MAX_ENT_LEAFS) continue; // not visible
- CalcSurfaceExtents: add casts to double to ‘val’ calculation to prevent compiler from rounding intermediate values to 32-bit:
see also: http://sourceforge.net/p/quakespasm/code/908/
Code: Select all
val = ((double)v->position[0] * (double)tex->vecs[j][0]) + ((double)v->position[1] * (double)tex->vecs[j][1]) + ((double)v->position[2] * (double)tex->vecs[j][2]) + (double)tex->vecs[j][3];
- MH’s dynamic light batching (http://sourceforge.net/p/quakespasm/code/933)
- AllocBlock: when inserting a surface lightmap into the array of lightmap textures, start at the last texture instead of the first. Reduces map load times by several seconds for big maps. (http://sourceforge.net/p/quakespasm/code/956)