190 posts not shown on this page because they were spam
190? How is this possible?
now it's 24 posts not shown on this page because they were spam funky
#260 posted by
metlslime on 2019/07/02 03:24:16
the first time it's because you clicked on the "new 190" link. The second time you clicked on the "last 25" link.
Kill Count Bug (and How To Fix It)
#262 posted by
iw on 2019/07/28 16:56:16
dumptruck, I've found an obscure bug which affects the kill count if a map includes trigger-spawned Rotfish. I was going to email you about this, but I think an explanation of this bug might be useful for others, because it illustrates something about the engine which isn't obvious. So, I thought I'd post this here, where others can see it.
I noticed the issue in the map pd_ionous, but it should affect any map with trigger-spawned Rotfish.
The bug is that the "total monsters" count becomes incorrect after a trigger-spawned Rotfish is triggered, but the incorrect count only becomes visible to the player if they save their game, then load the saved game.
To see the bug while playing pd_ionous: simply play up to the point where the three Rotfish have been triggered and have appeared, then save and load. Assuming you're playing on Normal skill, the "total monsters" count in the status bar should be 19 when you save, but after loading, the count will jump to 22. But there really are only 19 monsters, so it becomes impossible to get 100% kills.
The tl;dr solution is to increment the total_monsters global in swimmonster_start() instead of in swimmonster_start_go(). But I expect it's not obvious why that fixes the issue, or even why the issue happens at all, so I'll explain.
There are two things going on here:
====================
Thing #1: Why the total_monsters global becomes incorrect when a trigger-spawned Rotfish is triggered
This comes down to the way progs_dump currently fixes the old Rotfish kill count bug that was present in id's original code. The old bug existed because total_monsters got incremented twice for every Rotfish, once in swimmonster_start(), and again in swimmonster_start_go().
progs_dump currently fixes this by removing the increment from swimmonster_start(), and leaving the one in swimmonster_start_go(). However, this creates an inconsistency with walking/flying monsters, because those monsters increment total_monsters in walkmonster/flymonster_start(), and not in walkmonster/flymonster_start_go().
In the usual case where a Rotfish is spawned normally, this inconsistency doesn't make a difference.
But the inconsistency causes a problem when a Rotfish is trigger-spawned. In this case, total_monsters gets incremented twice per Rotfish:
1) The first time is on map start. monster_fish() calls swimmonster_start(), which calls monster_teleport(), which increments total_monsters.
2) The second time is when the Rotfish is triggered. monster_teleport_delay() sets self.think to monster_teleport_go(). When this is called, it calls self.think1(), which is swimmonster_start_go(), which increments total_monsters again.
====================
Thing #2: Why the change to total_monsters only becomes visible to the player after they load a saved game
This comes down to the way the engine divides things between the server and client.
This applies even when a player is playing locally (i.e. when the Quake executable is acting as both the server and the client).
The progs.dat code runs on the server-side. Variables such as total_monsters are also on the server-side, and the client-side does not have direct knowledge of them.
When a player spawns for the first time, or loads a saved game, the server sends the value of total_monsters to the client, so that the client can display that number in the status bar (and during the intermission).
However, if total_monsters changes on the server after that, the server does not automatically inform the client that the value has changed. This is the thing that isn't obvious. It's why, in this case, the player doesn't immediately see that total_monsters has changed after a Rotfish is triggered, even though the variable has changed on the server-side.
Loading a saved game forces the server to send the current value of total_monsters to the client. This is why the bug becomes visible to the player after they load.
====================
(As an aside, which isn't relevant in this case, but might help someone: if a mod actually wants to update total_monsters mid-game, and wants to notify clients of the change, the answer is to send a SVC_UPDATESTAT message to the clients. Both of the mission packs, and various mods, include code showing how to do this.
But this isn't relevant to the issue I've explained here, because the code obviously isn't supposed to increment total_monsters mid-game.)
====================
But, yes, the solution in this case is just to increment total_monsters in swimmonster_start() instead of in swimmonster_start_go().
dumptruck, I hope the above makes sense? If anything is unclear, please let me know.