Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Alter

Well what can break vanilla levels?

Recommended Posts

I have a question, I do know about seg-visible-at-once limits. But what else can break a vanilla level? I'm currently constructing a large vanilla level and i'm worried it may break the vanilla at some point with it's sheer size.

Basically I ask you people of doomworld. What can break the vanilla and it's savegames? Things? Sidedefs? Please do tell, will have to use those exact numbers as a guide to design the level.

Share this post


Link to post

I just went through this learning experience not that long ago.

Firstly, if you don't have it already, grab Chocorenderlimits. This will help you in making sure your vanilla map is within the limits.

This page will also be very handy.

Ok, so the vanilla map I made ended up being pretty massive (as you can see). Your already aware of getting HOMs from seg overflows, so there's that. I found that breaching the visplane limit happened pretty often too, though it's easier to avoid than going over the visible segs. Those two are probably going to be the ones you'll deal with the most.

Going over vissprites can be pretty easy to if your not careful. Something I learned recently is that if you have two sectors joined together, any sprites in them (regardless if you can see them or not) will count towards your vissprite limit if your look in their direction. For example, I had some monster containers set off of my main map area so they could spawn in later on. Those sectors were joined to a large starting sector in my map (so they would wake up). You could not see the monsters at all, but when I looked in their direction, it counted towards my vissprite limit (and subsequently busted that limit). I thought that was kinda weird...but it was easy to get around.

And then the last big limit I had to deal with was the BLOCKMAP limit. At first this was such an esoteric limit to me. It still kind of is because you don't really have a hard limit to look at while you map (though you can check the byte size of the BLOCKMAP lump). The thing to know is that your map can only take up so much surface area and can have only so many linedefs; I'm assuming the surface area of the map plus the number of linedefs both contribute to the byte size of the BLOCKMAP (or something like that). Anyways, if you break the BLOCKMAP limit, some places in your map will no longer adhere to the collision physics (and eventually the game will crash).

So those are the main limits I've had to deal with in my vanilla mapping experience thus far. I know there's a savegame limit too (and I'm sure my map has broken that one as well), but I guess once you break that one, the only way to "fix" it is to scale back your map. If your planning on making a big map though, there's not much you can do about that.

Anyways, that's just some advice from the recent experiences I've had. You may find that it's pretty easy to stay within the limits...or maybe not! Just depends on how you make your map. At any rate, I hope this helps :)

Share this post


Link to post
Mechadon said:

Useful stuff

I see, i'm most likely to hit the nodes the limit first so I switched my nodebuilder to ZDBSP and it's compression of nodes, went down from zennode's 20kb to 17kb. I'll have to constantly check for those limits. Thank you for the info mechadon :)

Share this post


Link to post
Mechadon said:

And then the last big limit I had to deal with was the BLOCKMAP limit. At first this was such an esoteric limit to me. It still kind of is because you don't really have a hard limit to look at while you map (though you can check the byte size of the BLOCKMAP lump). The thing to know is that your map can only take up so much surface area and can have only so many linedefs; I'm assuming the surface area of the map plus the number of linedefs both contribute to the byte size of the BLOCKMAP (or something like that).


It is my understanding, that every part of the Blockmap has to be linked in Vanilla Doom (some ports may not require this). Therefore if you have separate map sections a long distance apart, you will waste some ,er, Blockmap on void (I assume you'll have a long snake of Blockmap linking the two map sections together).

I wonder if this is one reason why the ID maps cram seperate map sections close together, rather than have them spread out all over the mapping area.

Share this post


Link to post
alterworldruler said:

I see, i'm most likely to hit the nodes the limit first so I switched my nodebuilder to ZDBSP and it's compression of nodes, went down from zennode's 20kb to 17kb. I'll have to constantly check for those limits. Thank you for the info mechadon :)

ZDBSP's compressed nodes are actually a ZDoom-specific thing. They use ZIP compression. In reasonably recent ZDBSP versions, you can generate uncompressed nodes in its extended format, using the -X parameter to force it. This will allow for some limit breaking, and also higher precision to avoid slime trails, and will be compatible with many modern ports including ZDoom itself, PrBoom-Plus, Eternity, and I think maybe also Risen3D. This is more recommended.

But for vanilla, though, you can't use any of that so it's pointless here. Doom won't load extended ZDBSP nodes at all, regardless of whether or not they're compressed, and its standard nodes aren't really very optimized for working under limitations, so I wouldn't advise using ZDBSP for vanilla maps at all.

ZenNode with -n2 -nu -rf -bc is your best bet there, as it'll try to reduce the seg count, limit potential visplane splits as much as possible, and compress your blockmap, allowing you to fit a bit more into your map before hitting the limits.

Share this post


Link to post
esselfortium said:

ZenNode with -n2 -nu -rf -bc is your best bet there, as it'll try to reduce the seg count, limit potential visplane splits as much as possible, and compress your blockmap, allowing you to fit a bit more into your map before hitting the limits.

One problem sir, when I save map with this combination, I get no blockmap/reject/nodes in my map. I checked the wad after saving it, using SLADE. If you want to be specific, here's how I set up the zennode in DB2:

zennode_vanilla
{
title = "ZenNode - Vanilla";
compiler = "zennode";
parameters = "-n2 -nu -rf -bc %FI -o %FI";
}

Share this post


Link to post

Other stuff:
- intercepts overflow
- moving sectors limit
- shootable linedefs limit (at the same time)
- revived crushed monsters
- moving sectors below -512 floor height

For the sprite limit, you can replace decorations with monsters that remove its corpse (like lost soul), for monsters that won't get revived by archvile.

Share this post


Link to post

You also have the intercepts overflow to work around. In HR2, for example, there are some areas that can generate a lot of corpses and unreachable pickups (like the Pedestal in MAP28 where Archviles and chaingunners spawn). Shooting at those with a hitscan weapon can overwrite some vital data and prevent collision detection from working at all.

Share this post


Link to post
alterworldruler said:

One problem sir, when I save map with this combination, I get no blockmap/reject/nodes in my map. I checked the wad after saving it, using SLADE. If you want to be specific, here's how I set up the zennode in DB2:

zennode_vanilla
{
title = "ZenNode - Vanilla";
compiler = "zennode";
parameters = "-n2 -nu -rf -bc %FI -o %FI";
}

Question about the issue still stands, anyone who has DB2 can check what is wrong by adding this to their Compilers/Zennode.cfg?

Share this post


Link to post

I'm not sure but it might be causing problems to add -n2 -nu -rf -bc before the input/output stuff rather than after it.

Here's the exact setup I use:

	zennode_optimized
	{
		title = "ZenNode - Vanilla Optimized";
		compiler = "zennode";
		parameters = "%FI -o %FI -n2 -nu -rf -bc";
	}

Share this post


Link to post

Well, another question, when designing large levels, how to avoid exceeding the savegame limit. What increases it and how to prevent it partially?

Share this post


Link to post

Including mobjs that are spawned during the game, such as projectiles. So a map may be barely within the buffer size at start up, and exceed it after actually starting playing it.

Share this post


Link to post
esselfortium said:

ZDBSP's compressed nodes ... will be compatible with many modern ports including ZDoom itself, PrBoom-Plus, Eternity, and I think maybe also Risen3D.


Risen3D automatically rebuilds both the blockmap and nodes internally.

Share this post


Link to post
alterworldruler said:

Well, another question, when designing large levels, how to avoid exceeding the savegame limit. What increases it and how to prevent it partially?


Mobjs, as kristus said (factor in 152 bytes for each one) are the most important factor, plus information for each sector in the map (the height and textures of sectors are saved, since they can vary during gameplay). The status of specials such as doors, crushers etc. is also saved. To get an upper bound, consider about 10 bytes per sector, and an upper bound of 60 bytes per special.

The gamesave size limit is 180224 bytes. I seriously don't know what they were smoking back at id to implement the buffer in this way:

save_p = savebuffer = screens[1]+0x4000; 
That's right. THEY USED THE FUCKING SCREEN BUFFERS FOR SAVING (that ought to lead to some interesting visuals, if you manage to take a peek at them). When the whole game had a -relatively intelligent- memory management system. Looks almost like an afterthought or something implemented by a developer who thought that allocating sufficient memory or writing/reading savegames using a streamed reading approach would be too much of a task.

And, to top that, they do the buffer overrun check AFTER going through the effort of saving (and possibly after already having corrupted memory and crashed):
    if (length > SAVEGAMESIZE) 
	I_Error ("Savegame buffer overrun"); 
Yeah, that MIGHT work sometimes.

Share this post


Link to post

Well, compare with Heretic's approach:

//==========================================================================
//
// SV_Open
//
//==========================================================================

void SV_Open(char *fileName)
{
	MallocFailureOk = true;
	save_p = savebuffer = Z_Malloc(SAVEGAMESIZE, PU_STATIC, NULL);
	MallocFailureOk = false;
	if(savebuffer == NULL)
	{ // Not enough memory - use file save method
		SaveGameType = SVG_FILE;
		SaveGameFP = fopen(fileName, "wb");
	}
	else
	{
		SaveGameType = SVG_RAM;
	}
}
Not only it uses proper dynamic memory allocation, it also has a "streaming" fallback method.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×