Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f52adfe
fixes / macros / personal commands ported
WolfoIsBestWolf Dec 23, 2025
0ea5623
probably finished
WolfoIsBestWolf Dec 28, 2025
ecc3766
send it
WolfoIsBestWolf Dec 30, 2025
3de7716
Update Lang.cs
WolfoIsBestWolf Dec 30, 2025
2a86899
Merge branch 'master' into master
WolfoIsBestWolf Dec 30, 2025
095edf4
set_crit & spawn_as permament1 default
WolfoIsBestWolf Dec 31, 2025
82e6e80
Merge branch 'master' of https://github.com/WolfoIsBestWolf/DebugToolkit
WolfoIsBestWolf Dec 31, 2025
1091413
Cleanup 1
WolfoIsBestWolf Dec 31, 2025
3d9beab
Update PlayerCommands.cs
WolfoIsBestWolf Dec 31, 2025
5edebd3
'give_buff' negative amount now just calls 'remove_buff'
WolfoIsBestWolf Dec 31, 2025
1867d7d
cleanse now a proper macro not rather duplicate code
WolfoIsBestWolf Dec 31, 2025
262dcb1
Update Buffs.cs
WolfoIsBestWolf Dec 31, 2025
1334a37
Cleanup 2.0
WolfoIsBestWolf Jan 1, 2026
4332549
empty spaces / unused diffs again
WolfoIsBestWolf Jan 1, 2026
21945d5
Fixed toggle_time not really working as it should if time_scale was a…
WolfoIsBestWolf Jan 3, 2026
6d824ec
Missed a type
WolfoIsBestWolf Jan 4, 2026
dd6328b
set_difficulty command
WolfoIsBestWolf Jan 9, 2026
8372c1c
Made the set_ stats 1 stat to not fill up help command.
WolfoIsBestWolf Jan 9, 2026
b0bd155
Removed 3 proposed commands due to redundancy.
WolfoIsBestWolf Jan 10, 2026
ee40a41
Small things
WolfoIsBestWolf Jan 16, 2026
f4fc38c
Buffs.TryParse Pinged fail message fix for real
WolfoIsBestWolf Jan 16, 2026
03c08d3
Update CHANGELOG.md
WolfoIsBestWolf Jan 17, 2026
eece426
give_all_items {itemTier}
WolfoIsBestWolf Jan 18, 2026
95d97ba
'give_drone' -> `spawn_minion`
WolfoIsBestWolf Jan 18, 2026
364caaa
Misc consistency of proposed changes
WolfoIsBestWolf Jan 18, 2026
c792d56
'spawn_portal' updated for DLC3
WolfoIsBestWolf Jan 18, 2026
7644540
Update Spawners.cs
WolfoIsBestWolf Jan 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 64 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,67 @@

## Changelog ##

### 3.22 ###
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a reminder that whatever changes to commands are made as a result of this review the changelog should be updated appropriately. Obviously leave this as a last thing and make sure to also update the readme.

* **3.22.0**

* Added commands:
* 'spawn_minion': Spawns characeter as your minion, specified amount and tier
* 'remove_all_minions': Removes all minions, leaving no bodies or broken ones.

* 'set_difficulty' Sets the runs selected difficulty.
* 'set_stat' Sets the given baseStat to the specified value, or resets it to the default value. For clean testing.
* 'nocooldowns': Toggles your skill cooldowns.

* 'list_drone': List drone names and ids.
* 'list_pickups': List pickup names and ids.
* 'list_difficulty': List difficulty names and ids.
* 'dump_mods': Lists all loaded mods and if they are tagged as RequiredByAll. Useful to get internal names to check for.

* 'godenemy': God mode for all monsters, to make them unhurtable.
* 'buddhaenemy': Buddha mode for all monsters, to make them unkillable.
* 'hide_model': Toggles your models visibiltiy, for screenshotting/recording.
* 'toggle_time' Toggles 'time_scale' between 0 and what it it was before.

* 'give_all_items' Gives all items of specified itemTier.
* 'give_void': Gives Void Markers.
* 'no_interactables': Prevent interactables from spawning

* 'goto_boss': Teleports you to boss, teleporter or boss arenas on stage, (i.e. Skip directly to Mithrix on Moon2)
* 'evolve_lemurians': Triggers Artifact of Devotion evolution.

* Added macro/short commands:
* 'dtscanner': 100 BoostEquipmentRechrage & Radar Scanner equip for easy map searching.
* 'dtpeace': 'kill_all Monster & Void', 'no_enemies true', 'god true'
* 'dtcleanse': 'remove_all_buffs 0 & 1' & 'remove_all_dots'
* 'random_equip' alternative for 'give_equip random'
* 'rich', -> Set money to 2 billion.
* 'poor' -> Set money to 0.
* 'skill': shorthand for 'loadout_set_skill_variant self'
* 'skin': shorthand for 'loadout_set_skin_variant self'
* 'hide_hud': toggle 'hud_enable' convar

* Updated command functionality:
* Item commands can now grant/remove channeled items
* Item commands now mention you can type 0/1/2 instead of the name type.
* 'spawn_interactable' now also shows interactable names in auto complete.
* 'spawn_interactable' now accepts amount.
* 'create_pickup' now supports dropping drones & pickups, and can use numbers to abbreviate search.
* 'create_pickup' switched {search} and {permanent/temp} argument spots.
* 'give_equip' now accepts '-1|none' to remove your equipment.
* 'give .. remove_buff' now accept negative amounts to remove/give, like item commands.
* 'loadout_set_skill_variant' now accepts 'self'
* 'random_items' changed default value to just give Tier1,2,3
* 'hurt' third optional argument for direct damage. (bypassArmor bypassDamageCalcs).
* 'kill_all' default value now kills Monster & Void teams.
* 'true_kill' now bypasses godmode and accepts 'pinged' & 'all' as target
* 'charge_zone' default value now 100% charge.


* 'spawn_as' will set your permanent character again.
* 'run_set_stages_cleared' will now also set the loopClearCount to the expected amount. (Which is a seperate thing as of AC)
* Modded spawn cards should be usable from the start now.
* Food items can now be given by {dropTable}
* Fixed 'god 0/1'/'buddha 0/1' not setting the toggle's state.
* Fixed 'loadout_set_skin_variant' crashing the game.


### 3.21 ###

* **3.21.1**
Expand Down
26 changes: 23 additions & 3 deletions Code/AutoCompletion/AutoCompleteManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DebugToolkit.Commands;

namespace DebugToolkit
{
Expand Down Expand Up @@ -69,18 +70,29 @@ internal static void RegisterAutoCompleteCommands()
var parser = new AutoCompleteParser();
parser.RegisterStaticVariable("0", "0");
parser.RegisterStaticVariable("1", "1");
parser.RegisterStaticVariable("count", "count");
parser.RegisterStaticVariable("droneTier", "droneTier");
parser.RegisterStaticVariable("duration", "duration");
parser.RegisterStaticVariable("skill_slot", "skill_slot");
parser.RegisterStaticVariable("skill_variant", "skill_variant");
Comment on lines 71 to +77
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why 0 and 1 have been added as static variables is so that in the command args we can do {some_bool (0|1)} instead of {some_bool ('0'|'1')}. They're basically there for convenience. When you add "count" there, in give_item {item} [count] the count will appear as an actual autocomplete option when typing the second argument, which we don't want.

parser.RegisterStaticVariable("ai", MasterCatalog.allAiMasters.Select(i => $"{(int)i.masterIndex}|{i.name}|{StringFinder.GetLangInvar(StringFinder.GetMasterName(i))}"), 1);
parser.RegisterStaticVariable("artifact", ArtifactCatalog.artifactDefs.Select(i => $"{(int)i.artifactIndex}|{i.cachedName}|{StringFinder.GetLangInvar(i.nameToken)}"), 1);
parser.RegisterStaticVariable("difficulty", R2API.DifficultyAPI.difficultyDefinitions.Select(i => $"{(int)i.Key}|{StringFinder.GetLangInvar(i.Value.nameToken)}"), 1);
parser.RegisterStaticVariable("body", BodyCatalog.allBodyPrefabBodyBodyComponents.Select(i => $"{(int)i.bodyIndex}|{i.name}|{StringFinder.GetLangInvar(i.baseNameToken)}"), 1);
parser.RegisterStaticVariable("buff", BuffCatalog.buffDefs.Select(i => $"{(int)i.buffIndex}|{StringFinder.GetLangInvar(i.name)}"), 1);
parser.RegisterStaticVariable("droptable", ItemTierCatalog.allItemTierDefs.OrderBy(i => i.tier).Select(i => $"{(int)i.tier}|{i.name}"), 1);
parser.RegisterStaticVariable("itemTier", ItemTierCatalog.allItemTierDefs.OrderBy(i => i.tier).Select(i => $"{(int)i.tier}|{i.name}"), 1);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename this to itemtier? Mainly because we have already established with list_itemtier the expectation of what that should be called. But also for the consistency of snake case. It would be nice we if could also rename droneTier to either drone_tier or dronetier. Whichever you prefer, though the former looks better to me.

parser.RegisterStaticVariable("dot", DotController.dotDefs.Select((d, i) => $"{i}|{(DotController.DotIndex)i}"), 1);
parser.RegisterStaticVariable("elite", new string[] { "-1|None" }.
Concat(EliteCatalog.eliteDefs.Select(i => $"{(int)i.eliteIndex}|{i.name}|{StringFinder.GetLangInvar(i.modifierToken)}")),
1
);
parser.RegisterStaticVariable("equip", EquipmentCatalog.equipmentDefs.Select(i => $"{(int)i.equipmentIndex}|{i.name}|{StringFinder.GetLangInvar(i.nameToken)}"), 1);
parser.RegisterStaticVariable("equip", new string[] { "-1|None" }.
Concat(EquipmentCatalog.equipmentDefs.Select(i => $"{(int)i.equipmentIndex}|{i.name}|{StringFinder.GetLangInvar(i.nameToken)}")),
1
);
parser.RegisterStaticVariable("item", ItemCatalog.allItemDefs.Select(i => $"{(int)i.itemIndex}|{i.name}|{StringFinder.GetLangInvar(i.nameToken)}"), 1);
parser.RegisterStaticVariable("drone", DroneCatalog.allDroneDefs.Select(i => $"{(int)i.droneIndex}|{i.name}|{StringFinder.GetLangInvar(i.nameToken)}"), 1);
parser.RegisterStaticVariable("specific_stage", SceneCatalog.allSceneDefs.Where(i => !i.isOfflineScene).Select(i => $"{(int)i.sceneDefIndex}|{i.cachedName}|{StringFinder.GetLangInvar(i.nameToken)}"), 1);
parser.RegisterStaticVariable("team", new string[] { "-1|None" }.
Concat(TeamCatalog.teamDefs.Select((t, i) => $"{i}|{(TeamIndex)i}")),
Expand All @@ -89,10 +101,18 @@ internal static void RegisterAutoCompleteCommands()

parser.RegisterStaticVariable("permission_level", CollectEnumNames(typeof(Permissions.Level), typeof(int)), 1);

parser.RegisterDynamicVariable("director_card", StringFinder.Instance.DirectorCards, "spawnCard", autocompleteIndex: 1);
parser.RegisterDynamicVariable("interactable", StringFinder.Instance.InteractableSpawnCards, autocompleteIndex: 1);
parser.RegisterStaticVariable("director_card", StringFinder.Instance.DirectorCards.Select(i => $"{i}|{i.GetSpawnCard().name}"), autocompleteIndex: 1);
parser.RegisterStaticVariable("interactable", StringFinder.Instance.InteractableSpawnCards.Select(i => $"{StringFinder.Instance.InteractableSpawnCards.IndexOf(i)}|{i.name}|{StringFinder.GetLangInvar(i.prefab?.GetComponent<IDisplayNameProvider>()?.GetDisplayName())}"), autocompleteIndex: 1);

parser.RegisterDynamicVariable("player", NetworkUser.instancesList, "userName");

parser.RegisterStaticVariable("item_type", CollectEnumNames(typeof(Items.ItemType), typeof(int)), 1);
parser.RegisterStaticVariable("pickup_type", CollectEnumNames(typeof(Items.PickupType), typeof(int)), 1);
parser.RegisterStaticVariable("search", CollectEnumNames(typeof(Items.PickupSearch), typeof(int)), 1);

parser.RegisterStaticVariable("stat", CollectEnumNames(typeof(PlayerCommands.Stat), typeof(int)), 1);
parser.RegisterStaticVariable("portal", Spawners.portals.Select(i => $"{i.Key}"), 1);

parser.Scan(System.Reflection.Assembly.GetExecutingAssembly());
}

Expand Down
10 changes: 6 additions & 4 deletions Code/DT-Commands/Buffs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ private static void CCGiveBuff(ConCommandArgs args)
}
if (iCount < 0)
{
Log.MessageNetworked(String.Format(Lang.NEGATIVE_ARG, "count"), args, LogLevel.MessageClientOnly);
args.userArgs[1] = (-iCount).ToString();
CCRemoveBuff(args);
Comment on lines -93 to +94
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

give_buff is technically not syntactically the opposite of remove_buff, which is why negative stacks were not supported from the beginning. give_buff buff 1 4 intends to add one stack for 4 seconds. -1 stacks here wouldn't make sense. In fact, remove_buff for timed stacks always removes the oldest timed stack.

return;
}

Expand Down Expand Up @@ -147,7 +148,7 @@ private static void CCGiveBuff(ConCommandArgs args)
{
body.AddTimedBuff(buff, duration);
}
Log.MessageNetworked($"Gave {iCount} {name} to {target.name} for {duration} seconds", args);
Log.MessageNetworked($"Gave {iCount} {name} to {target.name} for <color=#53E9FF>{duration} seconds</color>", args);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should avoid colors in logs as much as possible. The main reason I've used green/red for enabled/disabled is because for toggle commands it's very easy to not notice if you're toggling it to the wrong value.

}
}

Expand Down Expand Up @@ -175,7 +176,8 @@ private static void CCRemoveBuff(ConCommandArgs args)
}
if (iCount < 0)
{
Log.MessageNetworked(String.Format(Lang.NEGATIVE_ARG, "count"), args, LogLevel.MessageClientOnly);
args.userArgs[1] = (-iCount).ToString();
CCGiveBuff(args);
Comment on lines -178 to +180
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same argument as above. Negative stacks for remove_buff is not synonymous with positive stacks of give_buff. remove_buff's 3rd argument is supposed to be a bool for whether the buff type is timed or not. give_buff on the other hand expects an explicit integer for the duration of the timed buff. And yes, I'm aware that you can technically pass any non-zero value for bool and it'll count as true, but we'll getting into some implicit conversions here that are not as straightforward as just give_item -> remove_item for negative stacks.

return;
}

Expand Down Expand Up @@ -615,7 +617,7 @@ internal static CommandTarget ParseTarget(ConCommandArgs args, int index)
target = targetMaster?.GetBody();
}
}
if (target == null)
if (target == null && failMessage == null)
{
failMessage = Lang.PLAYER_NOTFOUND;
}
Expand Down
Loading