For Total Conversions and projects that don't otherwise fall under the other categories.
Forum rules
The Projects forums are only for projects. If you are asking questions about a project, either find that project's thread, or start a thread in the General section instead.
Greetings! "For everyone" means that this project will be useful for regular players, mod authors using Decorate, ZScript, ACS and DeHackEd, and map designers.
ZChecker is an in-game tool that primarily aims to facilitate easy and convenient debugging of actors, displaying real-time actor data and controlling them. In addition, the tool allows you to create actors by their partial names, view all actors from all loaded archives, sort them into categories, and even partially control the game world. The entire ZChecker, including its help information, is available in English and Russian.
ZChecker postulates (guarantees):
No external object can change without explicit instruction from the user.
The stability of the project is sufficient for it to be included in the permanent autoload list.
The game’s performance with the tool running should always be comparable to the performance without it.
Minimal supported engine versions are GZDoom 3.3.1+, LZDoom 3.60+, and QZDoom 2.1+. A list of the other ports tested is available in Section 4.
This thread also has a FAQ on the tool (why you need it, how to use it, and so on).
There's a detailed breakdown of the basics below (and the game itself also has a detailed help screen available with a console command), but as they say, seeing is believing... Therefore:
ZChecker presentation
There is also a separate menu for commands, and at first it may be more convenient than working through the console. However, you should keep in mind that the menu is only a shell for a few important commands.
The main tool for real-time monitoring of actor properties (telemetry of actors). Each infopanel is linked to one actor, and up to three infopanels can be on the screen at the same time, accessible with numbers 1, 2 and 3, respectively. Each panel is divided into logical components. You can customize their visibility, order, and options specific to a certain feature (such as the number of rows in the inventory display). As of the latest version, v0.87, there are 15 infopanels, which include:
Various technical information like classname;
Position, speed, size;
Inventory;
Nearby states;
Actor pointers (e.g., AAPTR_TARGET);
Linked sectors;
TID, TID to hate, arguments;
…and other actor properties.
Spoiler: More screenshots
For the details about the addition command, “zcadd”, see section “2. Console commands (CCMDs)” and a link to the README file in it.
ZChecker console commands greatly expand the engine's built-in suite:
Many added convenient options for working with actors, including improved replacements for some built-in commands.
Allow interaction with other parts of ZChecker (infopanels and the the Everything map).
Provide useful information about some static data that may be required during development.
Manipulate instances of the Thinker superclass (the base class for all objects that directly interact with the world).
All original ZChecker commands start with "zc". The main starting point is the "zchelp" console command (displays full in-game help information with examples), and the most frequently used commands are covered in the corresponding repository README section.
Spoiler: More screenshots
The <whom> parameter can be either an infopanel number ("1", "2", or "3"), a pointer to the player (keyword "self" or "s"), a target under the cursor ("lt" or "linetarget"), or a camera ("cam[era]"). By default, unless otherwise specified, targets whatever is under the mouse pointer.
In almost any place where the <class> is present, it can be specified by using a class mask. "*" (asterisk) will correspond to zero or more characters, "-" (hyphen) to one or more. For example, the class mask "z*man" without third-party modifications will be unambiguously recognized as "Zombieman", and "a-a-a-a" - as "ArachnotronPlasma". In case of ambiguity, you should choose an item from the list with a colon (like "*card:4" - choose the fourth option from the list of things ending in "card").
=============== ─ ============================== ─ ===============
3. The “Everything” map
Maps of the "Everything" kind are essentially a library, an exposition of all loaded actors. Attention: with some modifications the level may fail to start, if runtime errors occur in these modifications when loading with ZChecker! Whether they are inadvertent or intentional is not so important. You can either fix them yourself, or contact the author of that modification. Or us, the LLDM Doom Modding team, but with 98% probability we will redirect you to the author anyway .
All loaded actors are divided into twenty-odd categories: small monsters, large monsters, weapons, keys, passable decorations, shootable decorations, projectiles, player classes and so on.
Spoiler: More screenshots
Next to each actor there is an associated infoactor:
When you look at it, the class name of the linked actor appears, and the infoactor itself changes transparency.
Clicking on it will recreate the linked actor if the last one does not exist or if it is dead.
If the ZChecker console command is used on the infoactor, it will be passed to the linked actor.
infoactor’s color encodes the current state of the linked actor:
Green means that the linked actor exists and is alive.
Yellow means that the linked actor exists but is dead (has the +bCORPSE flag or health <= 0).
Red means that the linked actor does not exist.
Its height encodes the flags of the linked actor when it appears:
The top position, above eye level, means that the linked actor has a +SPAWNCEILING flag and is therefore created on the ceiling.
The middle position says that the actor is not affected by gravity (there are +bNOGRAVITY or +bNOINTERACTION flags).
In all other cases, the infoactor is in the lower position.
The Everything map adds some new CCMDs that start with “zcev”. All of them can be explained with the “zchelp zcev” command.
At the start of the level, all actor types appear on the map automatically. However, when debugging, it is often necessary to recreate the level without restarting it; for this purpose you can use command "zcev re[create]", or the corresponding item "Recreate actors" in the menu. There are also settings for what exactly will be created on the level:
=============== ─ ============================== ─ ===============
4. Advanced management. Technical and API for creating custom add-ons
Similar tool can't be done in Decorate/ACS, but you can run your Zandronum/DSDA-Doom/etc. mod in GZDoom to debug with ZChecker (as long as your mod works in GZDoom).
The project was tested on GZDoom 3.3.1, QZDoom 2.0, GZDoom 3.4.0, QZDoom 2.1pre, GZDoom 3.6.0, LZDoom 3.87a, LZDoom 3.87c, LZDoom 3.88, QZDoom g4.5.0, GZDoom 4.8.0, GZDoom 4.8.1, GZDoom 4. 9.1, GZDoom 4.10.0, GZDoom 4.11.0, and GZDoom 4.11.3. Multiplayer was tested on GZDoom 4.8.2 with a 3.6-gigabyte modification, as well as on LZDoom 3.87c.
Subsequently, all information from here will be moved to a separate project guide.
Spoiler: Adding to autoexec, useful extra aliases, and API
A few useful aliases not included in the base package:
// Just a convenient actor deletion:
alias zcx "zcact %1 rm %2"
// Interaction with the actors’ StatNums sets:
alias zcta "zcthinkers a %1 %2 %3"
// Warps the actor to someone (by default, linetarget to self):
alias zcwarp "zcsetprop %1 rel:%2 x:0,y:0 %3"
* * *
To add the project to the autoload list:
Find and open the *ZDoom configuration file.
Find the "[Global.Autoload]" section (usually found within the first fifty lines of the file).
Under it, add the following line "Path=/path/to/ZChecker.pk3" (e.g. "Path=C:\Games\GZDoom\Tools\ZChecker.pk3". Of course, without quotation marks).
ZChecker API
First things first: you can write to me freely via almost any communication channels I use, though Discord (I'm on the official ZDoom Discord server) and Doom Power forum is still preferable. Whenever possible and I have the time, I'll try to help you with the code. I also accept questions about searching in the commit tree, as it is a challenge to search for something specific in an unfamiliar language.
Before anything else, I would like to remind you of the project's postulates:
No external object may change without explicit instruction from the user.
The stability of the project must be sufficient for it to be included in the permanent autoload list.
The speed of the game with the tool should be close to the speed of the game without it.
Also, regarding modifications of the ZChecker core, we have a restriction on the minimum engine and language versions (GZDoom 3.3.1+, ZScript version 3.3.0): as far as I see, not a single thing has been added in the last seven years that radically changes the language enough to make sense to break compatibility. I suggest that infopanels and CCMDs that use unemulated new features be brought out as addons.
The localization update is done via the "./SyncLocalization.py" startup file. It converts the contents of "LANGUAGE.gzdoom400.csv" into two files, "LANGUAGE.gzdoom330.enu" and "LANGUAGE.gzdoom330.rus". The encoding for gzdoom400 is Unicode, for gzdoom330.rus is CP-1251, for gzdoom400.enu is seven-bit ASCII.
Creating an infopanel
Will be affected: ZScript (at least two overridden methods), CVARINFO (one line), and zchecker.cfg (one line).
Create a class inherited from "ZCBaseInfoPanelPart" (in radical cases, from "ZCBaseInfoPanelPart_PlayScope", if UI-scope is not enough. But that's not safe). Let’s assume it’s called "ZCInfopanel1".
Create an int user variable in CVARINFO and set a binary visibility mask for it. Usually it is either 0x00 (nowhere) or 0xFFFF (everywhere).
Override "virtual void OnCreate()". At the very least, it requires string variables "optionCVarName" (which CVar to bind the info panel to - you need to bind it to the one from step 2) and "optionLabel" (the displayed name of the info panel). More can be added for your needs.
Add "infopanel ZCInfopanel1" to "zchecker.cfg" (of course, the configuration file may not be in the ZChecker core, the project checks all matches).
Override "virtual String GetInfo( Actor thing, ZCheckerField thingfield )" - this method will return the output string. "Actor thing" - what we are working with (guaranteed not NULL), "ZCheckerField thingfield" - auxiliary class for passing various metainformation (see the corresponding class in "/ZScript/Core/ZCDataStructures.zsc").
It should work!
Creating a console command
Will be affected: ZScript (minimum three overridden methods), KEYCONF (one line per command alias), and zchecker.cfg (one line).
Create a class inherited from "ZCConsoleCommand". Let the name be "ZCNewCCMD".
In "zchecker.cfg" add the line "ccmd ZCNewCCMD".
Override "virtual void InitCCMD()". In it, "SetupCCMDInterface( String neteventname, String helpheader, String helpdesc, class tooltipClass = NULL, String helpaliases = "" )" must be called. The main thing here is the first one, "neteventname", this string will link the user input and this class. Let’s say, it’ll be "zc_newccmd".
Add the new alias string to KEYCONF. It should look something like alias zcnewccmd "netevent zc_newccmd`%1`%2`%3". The two backtick characters are the delimiter, "%1"..."%3" are user arguments with a space. To prevent the parser from losing the last user arguments, which should be treated as invalid, I recommend making their number 1 or 2 higher than necessary (see also "Parameterizable console commands").
Override "virtual bool HandleArguments()". It returns "true" if the "Usage" help warning is not needed, and "false" if it is required. It is in "HandleArguments()" that the full parsing of passed arguments should be performed - by the way, they will be stored in already recognized form in the dynamic array "ccmd.args" (respectively, their number is "ccmd.args.Size()").
Override "virtual void DoCommand( void )". The command itself will be executed here.
That's it!
Note: it’s best to avoid the backtick character (“`") and double grids ("##", see "Parameterizable console commands") in the syntax of the new command to avoid ambiguous parsing and possible conflicts with the core code.
Parameterizable console commands
Additional parameters are specified by the first argument, which must start with two grids ("##"). The parameter separator is the same. If such a parameter is found, all subsequent ones are shifted one closer to the start.
Available parameters:
"##nousage". Disables help information display when parameters are entered incorrectly (more specifically, when "ZCConsoleCommand::HandleArguments()" returns false).
"##loglevel:?" or "##ll:?". Forces a different LogLevel for the duration of one command's execution.
alias zcaddlistget "zcthinkers ##nousage actors add:%2 %1 %3"
Keep in mind that in this way you can fool the protection system against entering too many arguments. If a command has to take one argument, it will have to take two to check for overflow. This means that any parameter can push the last argument entered beyond the argument specified in KEYCONF: "zcsmth ##debug first second" → "zcsmth %1 %2" → ["zcsmth first" with the parameter "LogLevel:4", but the “second” argument is lost].
Creating a new “Everything” map.
It's worth noting that the Everything map is not the only one. The main map is "Everything_simple", the additional map is "Everything_alternative"; any other map identifiers are not distinguished by anything yet. At the moment the "Everything" levels are all the maps whose identifier starts with "EVERYTHING_" and whose name contains the word "ZChecker". When such a map is loaded, a check of special user properties is run for all sectors.
String/Text "user_zcsector_type". Category type. Hardcoded at the moment. Can be one of (without quotation marks):
Integer “user_zcsector_typesegment”. Segment number of the specified category.
Float “user_zcsector_jump_x”. How far relative to the previous actor to shift in X (in pixels).
Float “user_zcsector_jump_y”. How far relative to the previous actor to shift in Y (in pixels).
Integer “user_zcsector_jumpamount”. How many actors can be spawned in this segment of the category. If the limit is exceeded, the generator moves to the next segment or, if there is no limit, displays a message in the console.
Float “user_zcsector_infoofs_x”. How far relative to the current actor should the infoactor be shifted along the X-axis (in mappixels).
Float “user_zcsector_infoofs_y”. How far relative to the current actor should the infoactor be shifted along the X-axis (in mappixels).
String/Text “user_zcsector_categoryheader_name”. The name of the entire category (localized automatically).
Float “user_zcsector_categoryheader_ofsx”. Offset of the header actor of the entire category relative to the center of the current sector along the X axis.
Float “user_zcsector_categoryheader_ofsy”. Offset of the header actor of the entire category relative to the center of the current sector along the Y axis.
If no categories are found, a warning message will be displayed. Also log level “3. Development/API” can be useful when creating a map.
Otherwise, there are no restrictions on maps of the "Everything" kind.
* * *
Have fun modding!
And Happy New Year!
Last edited by JSO_x on Mon Feb 05, 2024 3:18 am, edited 2 times in total.
Noticed that forget to update a version string in the tool files ("v0.86" to "v0.87"); otherwise everything is fine, previously downloaded version is actually release and full. I've updated the repository archive anyway.
* * *
In the next week I'll post a FAQ. "How ZChecker can be useful for regular players", "Can the tool be used for projects under Zandronum / DSDA-Doom / other port", "How to debug projects more effective" and other related questions...
Spoiler: How compatible is ZChecker (with other modifications, with old versions, ...)?
As compatible as possible. During the development period about fifty different modifications for ZDoom, GZDoom and Zandronum were launched with the project. Even bugs of different engine versions were found, taken into account and leveled out: GZDoom 3.3.1, QZDoom 2.1, GZDoom 4.6.0, GZDoom 4.9.1.
Spoiler: Why ZChecker for common players/reviewers?
The most enjoyable part is creating actors by incomplete names and in any quantity (command "zcsummon"), as well as viewing everyone and everything on the "Everything" map. I, as a player, also found ZChecker useful for deleting glitched actors ("zcact rm").
Spoiler: Why do mappers (map testers) need ZChecker?
There are several geometry-related infopanels in the tool. When testing various maps, I often use the player info panel ("zcadd self") with information about sectors and portals to give the exact coordinates to the mapper.
Spoiler: Why do modders need ZChecker?
- Debugging and testing of individual actors;
- Mass debugging and mass optimization on Everything;
- Problem diagnosis;
- Understanding the actor device, the ZScript, and the game engine as a whole (ZChecker includes working with almost every major subsystem available from under ZScript);
- Real-time experiments with built-in properties;
- And other, less important and in some places even unnoticeable, but no less useful things...
Personally, the tool comes in handy in almost every project, both my own and team projects.
Spoiler: Can it be used for mods for Zandronum, DSDA-Doom, Eternity and so on?
Yes, quite: if the modification is compatible with GZDoom, you can debug it via ZChecker. That is, the target port of the project is any, but with additional debugging in GZDoom, LZDoom, VkDoom, QZDoom (or other port with ZScript >3.3.0 support).
Spoiler: My mod started to slow down. How to debug it more efficiently?
The "Everything" map. It can show a lot of flaws and defects. The commands "profilethinkers 7" to view the most voracious actors, "zcaddlistget" to get a list of actors sorted by time of appearance in the world, and "zcaddlistget <number>" to add to the info panel are often helpful. Jumping to an actor in the infopanel can be done via "zcsetprop s rel:<to whom> x:0,y:0". Removal is either via the built-in "remove <class>" or via "zcthinkers rm:all <class>".
Also see "What are some built-in commands that work well with ZChecker?" (next Q&A).
Spoiler: What are some built-in commands that work well with ZChecker?
There are many! But here are the main ones:
- "profilethinkers 7". How much time the CPU takes to process this or that actor.
- "alias". An alias for a command or several commands - there are examples of use in section 4.
- "freeze". Freezing the world.
- "i_timescale <number>". Accelerate/decelerate in-game time.
Spoiler: My [complex actor with a lot of states] is broken and I can't find the cause. ZChecker will help?
Yes! In info panels there is an option to enable tracing (output) of played stats.
It also makes sense to add output of its name (""####" "#" 0 A_Log("Spawn:" )") after each state label (like "Spawn:").
P. S.: for complex projects this method shows incredible efficiency. In one of them I managed to reduce the debugging time to twenty minutes (without it about eight hours were spent before).
Spoiler: The map "Everything" does not start/hang.
ZChecker creates all actors from all loaded mods. It is impossible to predict in advance how an actor from a third-party mod will behave...
Spoiler: Can I create a copy of linetarget actor on "Everything"?
You can, and not only on "Everything": there's a paired command "zccopyclass" for copying / "zccopysummon" for pasting. Modified properties of the copied actor are not transferred.