sezero / quakespasm

QuakeSpasm -- A modern, cross-platform Quake game engine based on FitzQuake.

Home Page:https://sourceforge.net/projects/quakespasm/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Increase instruction limit

Flecked42 opened this issue · comments

There was some recent discussion about increasing the instruction limit in QS and Ironwail.
I figured I'd get the ball rolling.

Can you elaborate?

QuakeC's instruction limit is too limiting for modern hardware and can wreak all kinds of havoc in even the most basic scenarios (the example discussed in the mapping Discord was the Thunderbolt's underwater discharge catching too many entities and throwing a runaway loop error). There's a belief that removing this limit (either by increasing it significantly or truly removing it) in Quakespasm will help get the ball rolling for it to be adopted into other ports since it ensures as much mod compatibility as possible across modern ports.

I made a test map with 1000 fish.

fish_test.zip

Discharging the LG in the water will crash the map in QuakeSpasm and Ironwail.

It does not crash the map in vkQuake.

I see. It's the runaway loop detection in PR_ExecuteProgram():
https://github.com/sezero/quakespasm/blob/master/Quake/pr_exec.c#L386-L390

vkQuake bumps it from 100000 to 268435456 (0x10000000) which is insane.
@andrei-drexler, @temx, @Novum, @Shpoike: What do you guys think?

quakeforge seems to had it bumped to 1000000: doing the same in qs
makes it survive that fish_test map, i.e.:

diff --git a/Quake/pr_exec.c b/Quake/pr_exec.c
index 60355d2..ce72138 100644
--- a/Quake/pr_exec.c
+++ b/Quake/pr_exec.c
@@ -383,7 +383,7 @@ void PR_ExecuteProgram (func_t fnum)
     {
 	st++;	/* next statement */
 
-	if (++profile > 100000)
+	if (++profile > 1000000)
 	{
 		pr_xstatement = st - pr_statements;
 		PR_RunError("runaway loop error");

Comments?

I don't see any reason to keep the instruction limit as small as possible. Your average CPU nowadays has multiple orders of magnitude more power so I wouldn't let concerns back in 1996 dictate how it should be set in 2023. My biggest concern being constantly needing to expand it as mods get bigger.

Personally, I agree with vkQuake's approach of virtually removing it. I don't think any modder is realistically ever going to need it and it seems to cause more headaches than it does fix things.

I don't see any reason to keep the instruction limit as small as possible. Your average CPU nowadays has multiple orders of magnitude more power so I wouldn't let concerns back in 1996 dictate how it should be set in 2023. My biggest concern being constantly needing to expand it as mods get bigger.

Personally, I agree with vkQuake's approach of virtually removing it. I don't think any modder is realistically ever going to need it and it seems to cause more headaches than it does fix things.

A runaway loop need not happen only because of 1000 fishes being electrocuted in a pool.

1000 fish may be an extreme example but it can happen in real maps these days.

1000 fish may be an extreme example but it can happen in real maps these days.

Yes, and a 1000000 runaway loop limit survives that.

A runaway loop can easily happen because of a badly constructed logic in
qc code, a miscompiled progs, and so on. That's why I don't want to bump
the limit to insane numbers.

Waiting for others' comments.

A runaway loop need not happen only because of 1000 fishes being electrocuted in a pool.

Anything can trigger it because it's not a runaway loop detector, it's a simple instruction limit. This either needs to be fundamentally fixed (much more annoying to implement proper infinite loop detection) or the limit increased significantly to ensure it never gets reached within any reasonable modern usage (which is what vkQuake does). Even at a limit of 0x10000000 a modern CPU will hit that in much less than 1000ms in cases where an actual infinite loop is reached, and ideally devs aren't releasing their mods with infinite loops.

commented

100000 is already hit in existing levels: just load Dwell 2's d2m8 and fire the thunderbolt underwater.
0x10000000 is a little too much and causes e.g. trying to start MP in a level without MP starts to hang for several seconds (-game alk1.2 +deathmatch 1 +map start).
This was lowered to 0x1000000 in vkQuake 1.30 just to prevent this (the time it takes depends on what the loop is actually doing, but 16M seems reasonable).

Thanks @temx. 1M already seems to handle d2m8, but OK, I'll bump it to 16M shortly.

Fixed in git. Change will be part of 0.96.0 release, whenever that happens.