#archived-modding-development
1 messages ยท Page 40 of 1
you'll probably have to completely ignore the GetInt stuff
and just make soul gain return 0, and manually update the MPCharge and MPReserve
or, API could use SetInt in AddMPCharge instead of just setting it
but that'd be a "fix" to vanilla code
no, the problem is, is that they inconsistently use how they access the variables
so, some places they use GetInt/SetInt where we can hook in properly
in this case, they bypass that entirely and read/write directly to the various variables
which means for the soul gain, it's never looking at your custom max mp
that's weird
that doesn't even scratch the surface
isn't that with SoulGain() having +11 and stuff?
AddMPCharge has > this.maxMP and stuff
yup
that's the problem
it should be >this.GetInt("maxMP")
but they didn't do that
so should I just copy their code and add .getInt and use that instead of addmpcharge?
no, honestly I'd just change the values in playerdata and be done with it, and don't care about the whole changing the save's data irrevocably. it's pretty well established that opening a vanilla save with mods loaded can/will break the save unless that save was with the mod
so
just ditch the GetInt hook entirely, and then create 2 hooks, one for new game and one for after save game load, and just change PlayerData.instance.maxMP = 33.
it's not optimal, but really there isn't a good way around it
we could fix it in the API, but we generally shy away from "fixing" base game issues. (we made 1 exception with the mouse pointer lock they did recently, but otherwise....) if it's broken in vanilla, it's broken in the mod api. Otherwise we'd be doing their patching and that'd just become a nightmare
not paid to do it so don't 
you manage to get a new video card on black friday kdt?
public int OnSoulGain(int amount)
{
Log("On Soul Gain");
if (PlayerData.instance.GetInt("MPCharge") + amount > PlayerData.instance.GetInt("maxMP"))
{
if (PlayerData.instance.GetInt("MPReserve") < PlayerData.instance.GetInt("MPReserveMax"))
{
PlayerData.instance.MPReserve += amount - (PlayerData.instance.GetInt("maxMP") - PlayerData.instance.GetInt("MPCharge"));
if (PlayerData.instance.GetInt("MPReserve") > PlayerData.instance.GetInt("MPReserveMax"))
{
PlayerData.instance.MPReserve = PlayerData.instance.GetInt("MPReserveMax");
}
}
PlayerData.instance.MPCharge = PlayerData.instance.GetInt("maxMP");
}
else
{
PlayerData.instance.MPCharge += amount;
}
return 0;
}
}
would this work if I really wanna keep the save data stuff
I just used find and replace for like 10 seconds
might
it worked! 
nah, had another gpu around
oh nice
have any of you tried GPU Passthrough?
oh shit
I forgot to actually decrease the amount
my playtime on my test save went from 10 minutes to 40 minutes doing this lmao
of the 400 hours i have into HK, probably 100 of it is just working on the API
lol
the soul gain is currently 5 and that's weird
I'm gonna make it more cruel
but also be nicer
wait nvm that's too cruel
11 --> 3 might be overkill
use a bool
?
do something like
soulGain = !soulGain
soulOnHit = soulGain ? 5 : 6
would that use a global?
just put a variable in your mod class
alright
is there a round up function
because you can use charms to get more soul and stuff
how do I make Mathf exist in the current context?
using Mathf?
using UnityEngine
alright
how's this
soulGain = !soulGain;
amount = soulGain ? amount / 2 : (int)Math.Ceiling((float) amount / 2); // first hit is rounded down, second is rounded up
besides being ugly
is there a reason to not always round down?
cause then 11/2 = 5
so?
makes shit numbers
no i meant, the possible base soul gain numbers
ohh
you'll get one of those 4 values in that method
depending on charms
so, base, soul catcher, soul eater, soul catcher + soul eater
dream wielder is a lie, right
like it says increased SOUL but it doesn't actually do it
yeah dream wielder's soul gain on dreamnail hit is huge
and it's fast
so with this dream wielder is now just normal dream nail
except fast af
and soul eater + soul catcher is normal collection
soul gain, i think, only is on nail hit
MP gain from grubberfly is seperate
as is dream nail
dream wielder is probably the most effective thing for this mod then
grubberfly has MP gain?
it's fine
so tanking + dream nail is the most effective build for this mod I think
bool flag21 = this.playerData.equippedCharm_3 && damageAmount > 0;
if (flag21)
{
bool equippedCharm_ = this.playerData.equippedCharm_35;
if (equippedCharm_)
{
this.AddMPCharge(this.GRUB_SOUL_MP_COMBO);
}
else
{
this.AddMPCharge(this.GRUB_SOUL_MP);
}
}
do I add that?
ohhh
so
so grub song is correctly affected
you could change GRUB_SOUL_MP_COMBO/GRUB_SOUL_MP
no, because you're not overwriting AddMpCharge in the PlayerData class
you have your own version that your version of soul gain uses
but nothing else does
i'd just change those 2 variables
just add them to the OnInt switch, right?
no, these are in HeroController
so...hmmm
when's the best time
maybe...after scene load
HeroController should exist at that point
i think
try hooking into ModHooks.Instance.SceneChanged <---hmmm, name is not hook, boo...
alright
yeah, should work
though, i would store the initial value the first time
since the SceneChanged event fires each time you go into a new room
and if you keep doing GRUB_SOUL_MP /2, after 2 or 3 rooms, it'll be 0
๐
so the first time, store the normal value, and then just assign that every time after
like
int? grubSoulMpBase;
public void OnSceneChanged(string sceneName) {
if (grubSoulMpBase == null)
grubSoulMpBase = HeroController.Instance.GRUB_SOUL_MP:
HeroController.Instance.GRUB_SOUL_MP = grubSoulMpBase / 2;
}
or something to that effect
yup
gotta sleep now tho so 
yeah, have a good one
you too
is there any way to add custom keybinds to the debug mod?
i need noclip keybind in my life
There's not but soon
I was gonna add that a bit ago but there was a problem in the API then I was away for a week because of thanksgiving
guys how does boss rush mode work?
cant i skip to the boss i wanna fight instantly?
No
also being able to bench anywhere would be ace
but im guessing theres a reason thats not a thing already?
You can add multiple dream gate positions, which is pretty close to bench anywhere
yea i guess that'll have to do
umm
i think i found a bug with the boss rush mode
i got killed by something invisible
during the dung defender fight
sounds shitty
did you stagger him when he was swinging poop?
sounds like a pretty common vanilla bug
ah
mby , i wasnt really paying attention to his poop
Btw what is MP?
in the mod
amount of Soul
oh ok
umm
i found this glitch
he was able to move from the start and got himself stuck there
this is a glitch
correct
I think that happens literally every time in boss rush XD
lol
Also i found out if u have dream shield you can basically delete the attacks of the mantis lords, if the shield touches a mantis lord's spear it disapears
I'd assume the projectile
because the spear is part of the sprite 
well yeah that's why i asked because it would have been really weird
also plz remove wayward compass from the selections available
no
also how else would you know which way to go?
i think u should add a way to skip the charm selection
and simply not choose any
have it be a rancid egg or something
huh?
press quick map
those 2, yes
certain mods you can install more than 1 of
those that use the modding api
f1 SeemsGood
<@&328354344313421825>
Something interesting for you to look at
https://github.com/UnityPluginManager/PluginManager
Guys how do i disable boss rush mode?
@somber spear - we basically already have this with the API
@fair rampart - just create a folder inside Managed/Mods/ called, for example, "Disabled" (doesn't matter what it's called really), and drag BossRush.dll into it
ok
@buoyant wasp but you need the mod loader still, no?
the API is the loader
Mod loader needs to be updated with every single game version
yes, but so would the unity plugin engine
UPM doesnt need to be updated
because it's doing the exact same thing
No
guys how easy is it to code with unity?
Place the aforementioned files into the directory where your target game is located, and run PluginManager.Setup.exe (using Mono to do so, if not on Windows)
that's literally doing exactly what we do already, it takes the game's dll, and weaves custom code for the plugins into it
UPM author here
It doesn't touch Assembly-CSharp at all
The way it works is described in the README.md file
UPM injects a static constructor into the GameObject class found within the UnityEngine namespace. This way, it is able to execute code before anything else in the game. Using this, it loads plugins from a folder named "Plugins" in the game's folder, and instantiates any MonoBehaviour derivatives with the [OnGameInit] attribute.
It modifies UnityEngine.dll (or UnityEngine.CoreModule.dll in the case of Unity 2017.2+)
Eliminates the need to inject into specific classes, and makes it game-agnostic
that sounds... horrible
dealing with gameobjects sucks
It's nothing to do with that
It could inject into any other class, GameObject is just a class that's guaranteed to be accessed before anything else
ok, so, lets say you want to supersede the mechanism for saving. how would you accomplish that?
Which ensures the static constructor runs before anything else
Mod loader having to be updated with every single game version is really inconvenient
eh, not really anymore @somber spear . I have it building in 1 step now
it takes... 5 minutes
If you want to modify an already-existing class, then I have some plans for a feature to do that down the line
Currently you'd have to create a sort of "wrapper" class for the MonoBehaviour, which isn't ideal
@buoyant wasp and what if I'm on a different version that doesnt have mod loader support?
yeah, all of our modding is modifying existing classes
i mean we're adding a few assets, but alot of it is hooking into classes and methods to execute additional logic or replacing the logic
I'll let you know once I have the system in place then, if you're interested
it's worth looking at, but it'd have to be pretty powerful. Right now I can easily wrap a method in a class with like, 4 lines of code and it handle everything else.
and of course we'd then have to get all the modders to switch from VS to Unity Engine
some modders already use UE, but several don't
VS? You mean Visual Studio?
yes
Nothing stopping you from using that
That's just an IDE
Unity's a game engine, it has no effect on what you write your code with
"An installation of Unity 5.x or 2017.x" <-- Why would I need this?
(for reference, I use VS & Rider)
You only need that to get the .dll files
If you have a game using Unity already (such as Hollow Knight), you don't need it
some clarity there would be a good idea
since it indicates you have to install the unity framework
It does mention that, but I suppose I could word it better
but yeah, if you find a way to make it easy
"and at least one of the following:"
but yeah, I'll add a footnote later to make it clearer
but here's an example of what we have right now
namespace Modding.Patches
{
[MonoModPatch("global::SaveStats")]
public class SaveStats : global::SaveStats
{
public Dictionary<string, string> LoadedMods { get; set; }
public string Name { get; set; }
[MonoModIgnore]
public SaveStats(int maxHealth, int geo, MapZone mapZone, float playTime, int maxMPReserve, int permadeathMode, float completionPercentage, bool unlockedCompletionRate) : base(maxHealth, geo, mapZone, playTime, maxMPReserve, permadeathMode, completionPercentage, unlockedCompletionRate)
{
}
}
}
basically this says "take the SaveStats class, Add LoadedMods and Name to it.
and ignore that constructor, it's just there to satisfy compile time requirements
I see
but then i now can Save Custom data to the Save File
and I assume the installer reads these attributes and makes the appropriate changes to Assembly-CSharp then?
we distribute the modded dll at the moment, but it basically takes the "modding dll" and merges it into Assembly-CSharp, yes
and yes, we know about the legal stuff
TC looks the other way
but then we expose a ton of the methods that are often used like TakeDamage, GainMana, Attack, etc. so that you can subscribe to those as events
and modify the values inside
As in, change the access modifiers to public?
Oh, you make an eventhandler that they call?
private void orig_StartMPDrain(float time)
{
}
public void StartMPDrain(float time)
{
orig_StartMPDrain(time);
focusMP_amount *= ModHooks.Instance.OnFocusCost();
}
I see
and then modders subscribe to FocusCostHook
which they can return a modified result
and MonoMod takes StartMPDrain, renames it to orig_StartMPDrain for us
so we can call the original, let it do it's thing, then apply any changes to the result.
sometimes we prefix and append, sometimes just prefix, sometimes slightly alter behavior
Neat
that's the simple stuff, it gets more complicated with a few other methods where we have to inject stuff in the middle of it. I tinkered with doing it via IL, but ended up just decompiling the method and modifying and replacing it in the dll that gets merged. it's not ideal, and the MonoMod author is looking at how we could automate it, but for now. those methods are few.
As difficult to make as it would be, I would so much love a mod where dreamers are bosses
well, if you could reuse assetts from the game for skills and spells, that wouldn't be bad, the hardest part would be writing the behavior. NGG just re-uses behaviors that are already there
adding behaivour to something that doesn't already have it would be easy
only reason I don't add any to NGG is because it'd have to interface with existing FSM code
well, i mean in-so-far as you'd have to actually develop said behavior
not that adding it wouldn't be doable
do you guys know what -noheap does when used in steam launch options
based on the name, i suspect it disabled heap allocations
Basically how that's relevant is the game keeps running during garbage collection
it shouldn't break anything, and apparently(?) sometimes fixes stuff
can't say i've needed it myself
@buoyant wasp The most recent modding api you posted here has a weird empty file named "Mods" instead of a folder
I blame winrar for being a shit program
it's why i moved to 7-zip
cause winrar stopped improving
though in this case I just used powershell to zip the folder, so maybe it's something weird with that
Yeah, maybe
@leaden hedge Would it be cool if I used the teleport function from boss rush for something in debug?
go for it
What's wrong with clicks?
at least in my copy, I can't click on things like noclip
it does nothing
doesn't toggle the color, nor set noclip on/off
Oh yeah I remember you mentioned that
the weird thing is
all skills works, spells work, items work other than trampass
geo/etc
overcharm works, but ingsoul/grimm doesn't... it's just bizarrely inconsistent in what does and doesn't do anything
Alright I tested locally and everything you mentioned works fine
How would that be breaking this?
i have to guess that the overlay he displays is only invisible outside of the menu
but still exists
it might be blocking clickthroughs
and so the areas where those buttons are is under where it sits
cause removing it causes me to be able to click them

oh I thought the default behaviour for canvas elements wasn't to block raycasts
apparently not zzz
well, at least we know what the cause is anyway.
k, i moved all the methods in ModHooks.Instance that call the actual hooks to internal since the only thing that should ever be calling them is in Assembly-CSharp. This means folks won't be trying to call ModHooks.Instance.GetPlayerBool(string name) directly anymore.
tested and all seems to still work the same, which is expected
Neat
Any opinions on the best way to save an arbitrary number of KeyCode -> function pairs given only string, int, bool, and float dictionaries?
you can always add your own dictionary
Does that still serialize properly?
like public SerializableIntDictionary
sorry, in a match,
public SerializableIntDictionary KeyCodes;
KeyCodes should just map directly to ints
Would something like this work?
public SerializableDictionary<KeyCode, MethodInfo> binds;```
you can just do
int x;
x = (int)KeyCode.A
KeyCode a = (KeyCode) x
I feel like MethodInfo there might break it
Alright I can use a string instead and build the MethodInfo when it's requested then cache it
yeah
as long as the dictionary inherits from SerializableDictionary and the 2 types are they themselves serializable, it should work
I would rather not mix this into the int dictionary already in the settings
yeah, it doesn't hurt to have more
the 4 that are there are just there to reduce boilerplate
That makes sense
Now I've gotta figure out how to store class name, function name, parameter names, and what to put into those parameters in a string
I might just make my own serializable MethodInfo class
why do you need that
couldn't you just have a dictionary in the mod that maps the name to the method?
i guarantee it's easier
the serialization unity provides is crap
(hence the need for the stupid SerializationDictionary which is the unofficial/official way to have dictionaries)
"Oh, it's so fast, except it supports almost nothing" - literally their readme, sorta
Not hard to be fast when nothing works with it
pretty much
This way of doing it also gives me a convenient list of all the possible binds
And I could probably use UnityAction instead of MethodInfo to make it a bit easier
I dunno, UnityAction is a lot less flexible
We'll see
the irony being that json.net which is the defacto standard serializer, probably could serialize/deserialize the save game data in < 20ms, which for saving/loading is low enough that you probably wouldn't notice if it was shoved into a thread
Oh, you can't have arbitrary parameters on a UnityAction
So nevermind about that
Yeah 20ms is nothing
i have half a mind to test that out sometime, just to amuse myself
you could probably get everything of interest saving fast enough to not even cause frame drops
on every frame I mean 
lol
actually, yeah, if you capped at 60, that gives you what....16ms per frame. sure you could probably do it that way. i bet them encrypting the data costs more time than that
oh well
still stuck using the sucky one
Combine that with unsafe code and potentially a native library and it could go even faster
I'm just saying if you're going to fix saving, you might aswell fix the fact that 90% of playerdata never changes, or is pointless
it has both nail damage and nailsmithUpgrades ๐ค
so, "fix the game?"
by the way, on the topic of hooking methods at runtime
I came across this recently: https://github.com/pardeike/Harmony
I tried it out, and it works
Offers the ability to hook both before and after methods, or replace them entirely
yeah, i looked at harmony when i was hunting around
You give it the MethodInfo structs for the appropriate methods
It's very cool
I'm thinking of wrapping a simpler API around it, gonna see what I can do
I think the reason I didn't like it was that it required alot of bootstrapping and a few other things. one of the authors that works on Harmony is the one who wrote MonoMod which is what i settled on. I think I also wasn't thrilled with harmony having 2 dozen issues open and no commits in the last 5 months'
Heh, that's fair I guess
Yeah, it's annoying to maintain, at least in my experience
yup, and it's annoying to get right in the first place
especially if patching the IL causes the stack size to change
Yeah
@leaden hedge https://clips.twitch.tv/TacitPiercingPlumagePJSugar
weird lol
I'll probably be replacing shinies with a ui
but yeah grimm and THK are buggy
and if they bug out, it breaks it on reload
Sounds annoying
I assume its something to do with the shiny drops somehow getting unreferenced, I'll probably just put it into an inventory screen once I finish that code
Noticed this going through changing things in debug
private static void GrimmchildClicked()
{
if (!DebugMod.GrimmTroupe())
{
Console.AddLine("Grimmchild does not exist on this patch");
return;
}
if (!PlayerData.instance.GetBoolInternal("gotCharm_40"))
{
PlayerData.instance.SetBoolInternal("gotCharm_40", true);
}
PlayerData.instance.SetIntInternal("grimmChildLevel", PlayerData.instance.GetIntInternal("grimmChildLevel") + 1);
if (PlayerData.instance.GetIntInternal("grimmChildLevel") >= 6)
{
PlayerData.instance.SetIntInternal("grimmChildLevel", 0);
}
panel.GetButton("Kingsoul", "Charms Panel").UpdateText("Kingsoul: " + PlayerData.instance.royalCharmState);
}```
Updating kingsoul text when the grimmchild state changes
What a god
why can VS not tell System.Func<string,string,string> apart from System.Func<string,string,Sprite> but mono can ๐ค
Alright, I'm not hardcoding binds anywhere anymore
And I've got the toggle all key working with this in Initialize
if (settings.FirstRun)
{
settings.FirstRun = false;
settings.binds.Clear();
settings.binds.Add("Toggle All UI", (int)KeyCode.F1);
}```
Now for the hard part
Gotta add UI for this
There will in total be 78 bindable things
Basically everything that could be even slightly useful to anyone
So apparently using System.Web.UI makes the assembly unloadable
Good thing all I wanted from there is the Pair class and it's super easy to just make my own
some try this 
@leaden hedge Ciplax just started streaming boss rush if you want to watch new version stuff
@leaden hedge reward skip ready yet?
The Pair class was added in .net 4.5 I think, which is probably why trying to use it in a Mod breaks stuff
Tuples were added in 4.0 iirc
ah, so they were
I guess this shows a simple example of how my proposed ModInventory works
PaneHandler.cs and Rewards.cs
Alright I'm working really slowly because I keep getting distracted but keybinds are working pretty well now
I don't think I care enough to make it say proper button names for controller binds
4/13...lol
There's a lot of binds
i'd argue it might be better to have the binds be a large area where you can have multiple categories visible at once
Yeah but that's way more work
otherwise you're going to have a hard time dealing with " hmm, did I bind this key to something else already? IDK, let me flip through these 13 pages and look"
I could have it ask for confirmation on binding a duplicate
Also, unrelated but this is horrible:
foreach (KeyCode kc in Enum.GetValues(typeof(KeyCode)))
{
if (Input.GetKeyDown(kc))
{
DebugMod.settings.binds[bind.Key] = (int)kc;
HelpPanel.UpdateHelpText();
break;
}
}```
"Hey this key is already bound to X,Y,Z"
Is there a better way to check pressed keys?
I guess you're not likely to know off the top of your head
He's just using the built in input handler to check pre-set actions
I think
That's easy, hard part is checking for an arbitrary key press
does Input have some sort of method that just returns all currently pressed key(s)?
Closest thing is a string of all keyboard keys currently pressed
Yes it's horrible
not string[]?
It's just a string
boggle
I mean you can just convert it to a char array
But still that leaves out joystick and mouse buttons
I'd say that there has to be a better way, but after having dealt with all this code in the last month....
I don't have high expectations for Unity functionality
no bugs yet for boss rush with common reward pickups
Impossible
Alright I've got it putting a warning in the console and requiring a double press for duplicate binds now
Optimally it would also eat the input when settings binds
But I can't be bothered to figure that out
eh, good enough
Yeah, pretty much my thoughts
It is a bit terrible how it works, though
There's not really any "waiting" state
It just sets the bind to KeyCode.None
And any bind with that KeyCode attempts to set itself to any key that's pressed
It works, though
Which is pretty much my criteria for "good enough"
maybe when kdt finalizes his UI updates we can make the binds window bigger 
so was this teleport code you were working on for just quickly moving around the map? or were you doing something with the boss respawning?
I want to eventually add better options for practice
Kinda like save states you can set
Move to a certain room at the given position with a stored gear preset and respawn bosses in the room
ah, i was thinking of something similar, though i was thinking of forking bossrush to do it
yeah, there are alot of things i go to use that i use at work all the time, only to find out that it doesn't work in 3.5
I think I broke something important
[ERROR]:[API] - Error: System.OutOfMemoryException: Out of memory
Alright I fixed it
Loading all images for debug mod from the assembly as embedded resources now
Uploaded that and API 1.2.2.1-19 to the drive
I don't think either of those are horribly broken
lol
so loading images externally causes issues?
and yeah, -19 seems to work pretty well, i've done several bossrush/randos on it
Nah external images is fine
Just a bit harder to fuck up installation when it's literally one file
i have -20, which is where i moved all the methods to internal that i'll probably upload later. it's otherwise identical to -19.
haha
yeah
also means that if you change the images
you don't have to worry about cleaning up the old ones if the names change
I don't think I would want to embed something that's likely to change
Like the randomizer xml
right, but i mean, if for whatever reason you deleted an image because it wasn't needed anymore
it really would just stay out there forever
the old way
That's assuming I care enough to delete unused images
haha
it could be 20mb, it's not like it's changing 10x a week and requiring you to download 1gb files everytime it changes ๐
1GB mods the dream
sigh i think tonight i'm going to try and figure out how to ship the default CA's so that mods can use https correctly
the other thing that it's time to start looking at is doing modloading so that you have all the mods installed, but be able to selectively activate/inactivate them without having to shuffle the dlls in/out
If Unload was ever used it'd be pretty easy for mod makers to support it on their end
right, the biggest things is just to make sure the hooks for the mod are un-registered, and ui elements/input stuff is undone.
though i had considered something where the hook part could be done automagically, but events are not 1st class entities in C#
(which pisses me off to no end)
I'd say it's good enough to just call Initialize/Unload and leave the rest to the mod
yeah, mostly i just had spent last night pouring over the internet trying to figure out how to make it so that i could make the event subscription stuff in the hooks less verbose. I really like having the logging noting when a mod subscribes to the event, but it means that 1 line turns into 8. outside of doing T4 template transformations before the build, there is no way to make an "abstract" event like a normal type. anything else is just a ugly hack
it doesn't change the functionality, it just bugs my internal OCD that code i write is clean and pure
Just go back to dnspy and you won't have to worry about clean code because it's impossible
don't get me wrong, i love dnspy, it's now one of my favorite tools i never knew existed, but... i love my source control too much
guys
i wanna install randomizer
but i already have an api installed
for 1.2.1.4
what do i do?
install the 1.2.2.1 api
alright
(well, assuming you've installed 1.2.2.1 game)
InControl has action.ListenForBinding() which sets the actions binding to the next viable input, although you'd have to make an action set
ok, lets try out this new fancy bossrush update
hmm, did you change the font size so less of the boss name shows @leaden hedge?
yeah its a hack of the inventory code
ah
so the previous and next pane is rewards
It's going to change so boss select is the next pane
yup, makes sense
so you can toggle between them to go forward when you want
rather than having a key to skip
but yeah, this is what the text looks like, assuming ciplax had the saem
yep looks the same
yay. i got "inventory storage"
yeah if you kill something whilst in the middle of a spell or dash
nice upswing
are the 3 dots supposed to do something?
they are placeholders
I'm going to put the image of the item inside them
when I can be bothered to crop out and mask 60 odd sprites
haha
well, you can look at the randomizer overlay, all the sprites in it are an even 160x160
which might not be quite big enough, but
or 152x152, idk, they are all completely uniform
I think iirc the circle is just 80x80
but yeah, then you wouldn't have to crop and resize and center and all that crap
๐
a thought
between the kill and the ability to select an item, put a short input CD, like 1-1.5 seconds
twice now, i've killed the boss with something like a spell right when i went to hit with the nail, and accidentally picked a random item
oh, i guess it's not nail, but jump, but yeah, in any case, just a small delay between kill and select
^Yes please! I hate when I'm upslashing to kill a boss (usually gruz mother) and it instantly picks a charm for me
lol, that's weird
look at where the right tendril is
just kind of hanging out there
so, reviews of updated boss rush. the new selection screen fixes alot of problems
assuming you can put in the delay. cause i'm sorry, but sometimes you kill a boss earlier than expected and you've already gone to press an input to dodge or something and select on accident.
as far as counting boss hp, i do like the notion that someone proposed a while back to give health bars for bosses on the bottom,
that'd be neat
I specifically avoided delay in the design, because delay makes uis feel like shite
but I guess for the first input I can put like .2 seconds or something
that might be enough, yeah
false knight is still broken
so as soon as the fight starts he jumps on your face
oh damn is bossrush getting further updates
probs
@leaden hedgedying to CG2 still send me to king's pass
Stop dying
kdt's answer to every bug is "git gud"
Either that or "Not my problem"
Me: Watcher knights are placed poorly and make a huge difficulty spike
Kdt: they are easy just dodge them and damage them
Someone else: but he is right they are hard
KDT: not my problem
There was a conversation that went down like that
Just get good
"this boss that guards a key completion point is harder than i expected"
hmm..... imagine that

But Uumuu is more tedious than anything and Herrah doesn't even have a boss
eh, i don't care if it's difficult, i just care if it's broken
so, being stuck in the spawn animation while a boss smashes your face, is not cool
having to do the boss with little or no abilities, well, that's just tough. honestly the new boss rush design might be too easy at this point. everything after the first 9 is generally a face roll
mmhmm
when you couldn't choose which ones you fought, it was alot easier to get screwed by rng drops
and so the "perfect" kill thing helped alleviate that
honestly now that you can pick the order, i'm not sure it's needed. or maybe there should be a "hard" mode for it where even perfect kills still only let you get 1 item.
Guys help when i start the game with boss rush mod installed instead of the usual menu there's just a help button, when i press it it just says "not my problem"
@leaden hedge
lol
what version of unity does HK run on?
Looks like this is a thing
Application.unityVersion
going down the rabbit hole, doesn't seem to help
guess i can log it
see what happens
its 5.4.3f1, if anyone ever needs to know
Boss rush is too easy? What if I put every item into tiers so stuff like fluke / lv2 spells / f str required 2 pickups instead of one 
Just make it so you can only pick up an item if you don't get hit
Bet that'd stop the complaining
You can open globalgamemanagers in a hex editor to quickly check the Unity version
or mainData for pre-5.x games
(really, you can check any UnityFS or asset file, but those two files are the ones I go for)
i think there is a number of ways we could balance it
i think the way it is now, is good for "easy", but i think a harder variant for more seasoned players would be good
either reducing the max you can get to 1, or making it so that the better stuff takes multiple drops (though doing it that way would mean that it would be exceptionally unlikely to ever get lvl2 of anything
or, make it so charms actually cost notches. you still get, 11 notches, but no longer allow for all of them to be equipped, you're limitted to what you use
But the max charm notches is 2,147,483,647, not 11 
suppose you could do some kind of currency based system
Yeah and have the option to buy stuff like nail damage upgrades, spells, and charms
maybe award bonus points if you beat a boss in one try without dying
So basically do it how Kein did is what I'm getting here
tbh I like KDT's implementation better
no way people would just save up for fluke and lv2 fireball
(when it works ;) )
i never played the old boss rush
so
i'm just saying we need to have some sort of hard mode and figure out how to balance it
Less health?
I was thinking 16 masks
but they're all blue
That way you actively see how well you're doing
kinda like Cuphead's King Dice fight
and steel soul of course
kinda implied yeah
I'm getting rid of the guaranteed drop
and unless you can beat my average time you get nothing 
personally not a big fan of the "rush" part of boss rush
I'm more of a survival guy
Is the latest boss rush in the drive folder?
no
Where can I find it?
Lel dreamshield kills Gruzz mommy without her waking up
this fixes mawlek, fc, being able to press buttons on the inventory instantly, and adds a timer per boss 
You can make it skip the intro cutscene I'm pretty sure
I think you can just set the first scene somewhere in gamemanager
but its a hardcoded string
I guess I could hook into the function to get scene name
and replace the first cutscene with FK's room
timer per boss?
like, if you don't finish you die?
or just "how fast did i kill this boss"
no it just says how fast you killed the boss
oh nice
it has a number under to compare to, but I've only added the first few
did you figure out why the text sizes on the select screen (why they suddenly went big)
I need more averages for later bosses due to number of builds / drops
dunno, I made them smaller again, disabled the bold and put them on horizontal overflow
they are still a little too big
though
You should be able to change the first scene with the before scene load hook already
I mean technically it would change all times you enter Tutorial_01/King's Pass but whatever
Doesn't matter for boss rush
Note to self NEVER get glowing womb
For me it's Hornet
they keep freezing time causing me to miss an input and hit a spike or something dumb
Unbreakable heart doesn't work?
I don't think I can heal past them, so they're effectively blue masks
also I got Joni's and now everything is... odd
joni's is bad
jonis is broken
never, ever, ever take jonis
lol
@leaden hedge - I assume you're calling the UpdateBlueHealth method and it still freaks?
yes
bleh
I'm getting a lot of frame loss and stuttering
probably not even from boss rush though
public override bool IsCurrent()
{
try
{
GithubVersionHelper helper = new GithubVersionHelper("iamwyza/HollowKnightRandomizerTracker");
Version currentVersion = new Version(GetVersion());
Version newVersion = new Version(helper.GetVersion());
LogDebug($"Comparing Versions: {newVersion} > {currentVersion}");
return newVersion.CompareTo(currentVersion) < 0;
}
catch (Exception ex)
{
LogError("Couldn't check version" + ex);
}
return true;
}
How do I have to set this up on github for it to be able to get the version properly?
its probably looking at the latest tag
you can look at the modding api one right now
i have it setup
so for the API i did this code
{
GithubVersionHelper githubVersionHelper = new GithubVersionHelper("seanpr96/HollowKnight.Modding");
string currentGithubVersion = githubVersionHelper.GetVersion();
string[] temp = currentGithubVersion.Split('-');
int modVersionRevision = Convert.ToInt32(temp[1]);
Version tempNewVersion = new Version(temp[0]);
Version tempGameVersion = new Version(gameVersion.major, gameVersion.minor, gameVersion.revision, gameVersion.package);
Logger.LogDebug("Checking Game Version: " + tempGameVersion+ " < " + tempNewVersion);
if (tempGameVersion < tempNewVersion || (tempGameVersion == tempNewVersion && modVersionRevision > _modVersion))
IsCurrent = false;
}
catch (Exception ex)
{
Logger.LogError("[API] - Couldn't check for new version." + ex);
}
it will go fetch the latest release name, and then compare it to the one they have installed
if they don't, you get the "new update avialable
Alright
though, that said, naming doesn't matter per modder. They can use whatever design to name and compare they want, the "IsCurrent()" funciton just cares if it's true or false. if it's false it will say "New Update Available"
using semantic versioning though makes it alot easier since the .net version class supports it already
I had the collector break using dreamshield once
that's a vanilla game bug
collector is just broken
in vanilla
fluke breaks him, weavers break him, sporeshroom breaks him, defenders crest breaks him
grimmchild simultaneously breaks and fixes him if you wait long enough
the beta release notes said they were fixing him, so...
yup
oh, right, forgot about that bug
@leaden hedge - if you kill HK any time other than before radiance, you don't get your MP/HP UI back
until you die
mod's too ez
for speedrunners yes
gotta say, it has the best loading screen ever
@leaden hedge if u load a normal savefile in boss rush, u'll get stuck with boss rush load screen
"place holder loading screen"
@cedar raven - correct
don't try to start anything other than "new game" while bossrush is installed
kdt is working on an expanded version of "More Saves" which will have some icons to point out when a save has different mods associated with it
to help reduce that
collector is broken in boss rush
it stays in dead position where you are supposed to hit him
you probably had one of the dozen things i mentioned above
im looking at a stream
this is a vanilla game bug
oh
not related to boss rush
ok
yup, basically any damage other than nail, dive, abyss, or regular fireball can and often does break him
so fluke, weaver, dreamshield, sporeshroom, etc all will do that
yeah he used dreamshield
i mean... we "could" turn off those abilities during the collector fight in the mod yeah Wyza?
to prevent this softlock
dat kinda sux
could, yes. though the next patch is suppose to fix him period
and that's been in beta a couple weeks, i'd be surprised if it didn't drop soon
probably ๐
he'll probably fly through the ceiling now or some random shit
Also quick slash can break him
how do you get the enemies in a scene
or just the enemies on screen
debug mod's EnemyData confuses me significantly
have you looked at the source code for the mod?
how's the Blackmoth mod? I've been curious about trying it
http://www.moddb.com/mods/hollow-knight-lightbringer
Vote Lightbringer mod of the year!
I voted for http://www.moddb.com/mods/sonicexe-generations

1.2.2.1-21 (BETA) - Some changes to the way the Logger was done to try and resolve some concurrent access issues. Mod.Instance no longer exists by default (turns out Static fields/properties are static to the base class and not inherited classes), so if you were using MyNewMod.Instance, you'll need to add your own instance field. As far as I know, only 2 mods were using this anyway. Added the new github version helper to let you use github releases to notify folks when new versions of the mods are out. (will update examples here shortly to show how). Also all the methods which actually call the hooks are now internal, so you can't accidentally try to call them from outside of Assembly-Csharp. should reduce confusion.
yeah, problem is
whatever the last mod that is instantiated is
is what Instance would be
Nice
yeah....works great with 1 mod, does bizzare stuff with multiple ๐
thankfully it's a 2 line fix for mods
https://github.com/seanpr96/HollowKnight.Modding/blob/master/ExampleMods/Source/ExampleMod2/ExampleMod2.cs has a sample of the github version checking code and how to update the mod to handle Instance now.
Fixed the Instance thing already for debug mod
figured as much
it's dead simple these days thankfully
it used to be a pain, but now it's literally "draft release" "give version number" "optionally give notes/name" "publish"
Sounds easy
I really need to fix up the debug mod code one of these days
I've got stuff like clicking a button calls a function that calls another function that calls the function that actually does stuff
lol
I just need to switch from storing the button functions as UnityActions to MethodInfo and I'll have a lot more flexibility
not that you'd want to, but I use a addon called Resharper (it's pay, so). Honestly to me VS without resharper isn't VS, but i digress. It does so much stuff to help reduce unecessary code, formating, converting loops to linq, i mean, it's insaine. All that to say. It has a bunch of "best practice" coding styles like naming conventions. it's rather scary to see everything that dnspy spits out with the squiggly lines
hehe. I used it for years at the college i worked at, and then it's basically manditory where i work
yeah, but I do enough coding that it's worth it to me
Well I'm gonna apply for the free products
Can't hurt
They don't even ask for reasoning, they just want a .edu email address
So it can't be that exclusive
nah, it's like MS
they want to hook you while your at a school
so that when you leave
you have to buy it ๐
looks like they do open source licenses too
@copper nacelle if you're using api, oncollider will list everything with a hitbox as they spawn
Then you just need to use FSMUtility.ContainsFSM(gameObject, "health_manager_enemy"), to check if its an enemy
(fair warning on Oncollider, make sure any operations you do in that hook are fast, it's called an absurdely huge number of times)
Mainly during load
yeah, 10k+ times easily
so filter as early as you can in the call to only do work on what you need to and return if not.
Comparing layers is probably faster then containsfsm
I think enemies are on 11 and 17
so @leaden hedge changed the logging in -21 a little bit which shys away from your approach of using the Modhooks.Logger in favor of the Logger that's part of the Mod class. if you want to log for the Mod itself, you should just remove Modhooks.Logger entirely so that it's just "Log(somemessage)". if you're wanting to do a global logging, just use Logger.Log now. Logger is now a static class (had to change it because was having threading issues with it being created multiple times). Should be fairly trivial to do a find/replaceall
guess i could make a wrapper class to make it backwards compatible, but meh
can you make it work with implicits 
like, auto convert an int/float to string?
yes
yeah
i can do that np
I think i'll just add an overload that accepts type object and then just do .ToString() on whatever you pass it
so for all the basic types, it'll "just work"
1.2.2.1-22 - Adds Overloaded methods for all logging to allow for you to pass in an object to which it will do a "ToString()" on. @leaden hedge
gotta be somethign weird with powershell doing the zip
powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::CreateFromDirectory('$(SolutionDir)\OutputFinal', '$(SolutionDir)\ModdingAPI.zip'); }"
guess i'll go look up how to do it with 7z instead, probably just as easy
I don't seem to have a refence to Log in mod class
Cause you're trying to access a instance method from an static method
if you need to do that
internal static BossRush Instance;
then in Initialize
Instance = this;
then you can do
Instance.Log("striing!");
Done with homework for tonight, time to see what resharper is all about
also, ahhhhhhh kdt is a white theme editor person, my eyes
Haha yeah I use dark mode on literally everything
mmhmm
Also resharper is giving me 154 warnings so that's a bit daunting
its just vs i use white theme on
hehe, yeah, though it does have the "fix this warning, fix in file, fix in project"
is there something I can return to GetSaveFileNameHook to make it not save / load
hmm
i mean, you could pass in a file that doesn't exist
to prevent loading
to prevent saving
oh, lol
just do
GameManager.GameConfig.disableSaveGame= true;
cause the save function does this
if (!this.gameConfig.disableSaveGame)
to prevent loading just return a file that doesn't exist though, an error will show up in the output log, but w/e
[ERROR]:[API] - Error: System.MissingMethodException: Method not found: 'Modding.ModHooks.get_Logger'.
at Modding.ModLoader.LoadMods () [0x00000] in <filename unknown>:0
yup
that's what i meant about not using ModHooks.Logger anymore
and using either just straight "Logger"
or
Log (if you're in the Mod class)
im not using ModHooks.Logger
hmmm
this happens between the end of Initialized BossRush and the start of Saving Global Settings
full modlog?
[INFO]:[API] - Adding GitHub SSL Cert to Allow for Checking of Mod Versions
[INFO]:CN=*.github.com, O="GitHub, Inc.", L=San Francisco, S=California, C=US
[INFO]:GameLoading
[INFO]:[API] - Trying to load mods
[INFO]:[BossRush] - Initializing BossRush
[INFO]:[BossRush] - Initialized BossRush
[ERROR]:[API] - Error: System.MissingMethodException: Method not found: 'Modding.ModHooks.get_Logger'.
at Modding.ModLoader.LoadMods () [0x00000] in <filename unknown>:0
[INFO]:Saving Global Settings
[INFO]:Saving Global Settings
any other mods in your mod folder?
oh yeah I have moresaves 
that probably has the same issue
no longer has any real save slots, and has version checking
interesting, you moved watcher knights
Wow way to get bullied into changes by casuals
it doesn't really make a difference, you just do WK and broken vessel instead of each other
the last boss you did in phase 1 was WK and first in phase 2 was usually Broken Vessel
now its just last in p1 = vessel, first in p2 is wk
Broken vessel is definitely easier than watchers
It's like one of the easiest bosses in the game
hmm]
this will fix GPZ
k
not gonna run it tonight, should have went to bed an hour ago ๐
i like the extra timers, but I kind of wonder if there isn't a better way for htem to be handled display wise, they take up alot of realestate and are somewhat distracting since they are always ticking
also, not sure what you changed exactly, but those timers seem to affect stuff in weird ways
the final screen that gives you the game time
said 15 hours
and 82% completion
its probably loading whatever slot you clicked on
ah
Force camera follow cheat that actually works
What a world
That's been broken since release and literally nobody has complained so I guess nobody uses it
But I fixed it anyway
thats the opposite of how it should work ๐ค
everyone complains something is broken and not fixing it anyway
But yeah it was a pain to make work because Team Cherry are assholes and do their camera locking in LateUpdate
I'm gonna try to get rid of the black bars around all the scenes now too
So you can actually use debug to practice oob
Pretty sure avast has taken it upon itself to start deleting my game executable
So that's fun
I only even have that garbage installed because my school requires an av to use the internet
I don't really like any antivirus
It's needless bloat
Best av is just not being an idiot
r u sure?
They help me alot when im downloading things im not sure if are a virus or not
Why are you downloading things that sketchy in the first place?