
I'm hesitant to post this as I worry it might be considered poor taste or else "cheating," but I was wondering if anyone knows of a simple way to tweak weapon stats for someone who's not really knowledgeable about modding in general. The reason I asked is I tried the DMCWO mod and - while I'm not a huge fan of most of what it does - I did enjoy some of the changes to some of the weapons, specifically some of the ones I don't really use. I was wondering if I can make my own MUUUCH simpler mod to tweak just one or two stats on just one or two weapons. Not for multiplayer, obviously - I have a number of mods that I keep either for personal use or for private lobbies.
However, it occurs to me that it's useful to mod guns and try them out for real if I'm going to make actual suggestions on the official forums. Last one I suggested was an 80-damage, 180-RPM machinegun with a 50-round mag and 150 total ammo. Underpowered? Overpowered? Just plain stupid? I think it's pretty cool, but I'm guessing. Being able to test this out on my own and see just how far out of whack it is would be awesome, but I'd need to pick and existing gun and mod it to those stats to see. Is there a simple way to do that? I can kind of tell how DMCWO is doing it - messing with tweak_data - but I'm sure there's more to it than just making a lua file with tweak_data.gun.stat = new_stat, right?
So... Am I out of line asking for this?

OK, I think I finally understand what's going on here. I need to override the WeaponTweakData:init(tweak_data) method to first execute itself, then execute a bunch of other data assignments. The data structure can be found in the file you linked me to, and WeaponTweakData:init(tweak_data) itself is in lib/tweak_data/weapontweakdata. I'll have to look at my other BLT mods and figure out how to put together a mod.txt for it, since I'd rather use BLT if at all possible.
Lua confuses me with its basic syntax, but that's largely because I'm used to the C++/Java Syntax. It seems to work in a very similar fashion, just everything is called differently and uses different keywords. I'll let you know if I succeed when I get home.

Yup, it worked! Of course, slowing down the Brenner to 180 RPM had the unfortunate side effect of making its fire sounds completely ridiculous and I couldn't fix it at all. Apparently, you can only replace an auto-fire sound with another auto-fire sound, and those don't work well with low fire rates. In either case, though, I managed to tweak weapon stats consistently. Thank you kindly! :)

Yeah, it ended up not very good. I upped it to 375 RPM and now it's actually usable, but I'm concerned that 80 damage may be a bit much at that point. It still puts out less damage than the Buzzsaw (30 000 per minute vs 36 000) but it melts Bulldozers like you wouldn't believe. Definitely needs more recoil, but I'll work on that another time. For now I'm mostly concerned about ammo pickup. The Brenner ammo pick-up is so much that I can keep nearly topped up constantly. That's good, but it won't cut it as an official suggestion.
Do you have any idea how the ammo pick-up stat works? It uses a function of some kind, but I don't recognise the numbers in it. edit I believe it's the "self.hk21.AMMO_PICKUP = self:_pickup_chance(80, 1.5)" function, but I can't tell what those stats are.

The first number is how much max ammo the game pretends your weapon has when it figures out how much ammo you pick up. 80 is equivalent to the Eagle Heavy, 150 is equivalent to the CAR-4, and so on.
The second number doesn't matter. It's supposed to determine the multiplier applied to the max ammo to get the final pickup range, but both cases result in the 2-5% pickups commonly used right now.

Ah, excellent! So apparently ammo pickup equivalent to an 80-round rifle is enough to keep this theoretical LMG stocked to the gills. This is... Unexpected. I'll have to think about it.
How does one mod the speed penalty of an LMG or the Minigun, by the way? It's not in TweakData that I can determine. I'm experimenting with the Minigun to see if I can justify dropping the slowdown if I can drop its performance, but I can't actually test it that way.

Hmm... I'm having some degree of trouble tweaking anything in upgradestweakdata. I found the stat in question - "self.weapon_movement_penalty.minigun = 0.6" which is in the function "UpgradesTweakData:_init_pd2_values()". However, I'm unable to do anything with that function, since none of the changes I attempt to make seem to have any effect. I don't see any obvious errors in the BLT logs, the game doesn't crash - it's almost like my changes just aren't changing anything. I was able to replicate B Dawg's example code (thank you kindly, by the way) for messing with "WeaponTweakData : init" but I'm not able to replicate the same apporach for "UpgradesTweakData : _init_pd2_values()".
Now, you're probably going to laugh at me as I legitimately do not understand the intricacies of Lua beyond what I know from other languages and what I assume to be the case, but here's what I'm trying to do:
local old_init = UpgradesTweakData:_init_pd2_values
function UpgradesTweakData:_init_pd2_values()
old_init(self)
self.weapon_movement_penalty.minigun = 0.8
end
I'm still not sure what the deal with "self" is, but I see it done all over the place in other mods and it appears to be some kind of global variable. I even read an article about using "self" as a means of abstracting a function such that it doesn't depend on a specific object, which I'm not entirely sure how that works. Obviously this is a different case, but I don't know which part of my assumption is mistaken. I'm really not trying to do anything major, just reduce the Minigun movement penalty down from 0.6 to 0.8 - the same as LMGs. With all the other tweaks I've done to it, it really doesn't need that penalty, but I can't seem to disable it and I'm running out of options.
edit
So after reading a few articles, it seems like "self" is a reference to a function's parent class (or I'm guessing parent context of some description - not that familiar with Lua), and it's good practice to use that parameter in function calls to specify context. The colon operator : obfuscates the "self" reference (in a way that really reminds me of C++) for convenience. I'm starting to follow the logic here. But unless method names which start with an underscore _ are somehow special, then it seems to me like my code should work. I create a local variable to hold the original function from the original class, I create a new function within the context of the original class and then call the original function within the context of the class I'm currently in so it can do all its housekeeping first, then I can follow after it and change a few of the things it changed. Presuming this function gets called by the game where appropriate (I'm guessing on startup?), it's good to have any changes to do with that function happen inside it.
Still don't know what I'm missing here, however.

For setting simple values in tweakdata entries I always just used persists, which are usually okay as long as they actually have a testvar set correctly so your FPS doesn't get bombarded with crap due to the script running infinitely rather just once.
For example:
if not WhoDoYouSplatSquid then WhoDoYouSplatSquid = true
tweak_data.upgrades.weapon_movement_penalty.minigun = 0.8
end

Persist scripts seem to be a bit over my head, though, as I'm not entirely sure how they work. I could try and copy the way DMCWO does it, which... Appears to include announcing a "global" which I don't know what that does and a lua script which has absolute references to specific values to tweak without needing to override entire functions. That brings in the following question, then: When do persist-scripts run? I think lua hook scripts attempt to inject themselves within the game's own lua structures and run when the functions they override are called, but... When do persist scripts run? Or are they running constantly? Putting in a logical check in there to ensure the change only happens one seems reasonable, but wouldn't that also have the game constantly do the logical check? Or is that not considered to have a meaningful impact on processor load (seems reasonable). When do persist scripts run?
I'll try and do it the way you have it set up, see what happens.
edit
Aha! It worked! The Minigun runs pretty well now! :) So... What was I doing wrong before? I'd love to know so I don't repeat the same error.

Oh, absolutely. My primary goal here is to test guns for suggestions made on the official forums, not to play the game with them in public games. If I make a claim that a gun with "such and such" stats would be a good addition and not overpowered, I'd like to have actual hands-on experience with it to back up my data. Or, as it turns out, refute said data since the design I was trying to create turned out to be a complete mess.
Moreover, I'm not looking to create overpowered weapons, far from it. I'm trying to use stats-modding to prove that specific weapon designs are expressly NOT overpowered. And it's a good thing I tried it, because several of the designs I thought would work ended up far more powerful than they should have been. I've been working on a model machinegun and nearly everything I've done to it is nerf it in every iteration - worse recoil, less ammo pick-up, then even less ammo pick-up, ETC.
But that doesn't change your point. What I'm doing is cheating and I would not use those weapons in a public game. There there for me to experiment so I can speak about weapon design from experience. Nothing more. Not that I could get away with doing that in a public game anyway - the guns are VERY obviously modded. This is strictly for private experimentation.

My experiment continues, and this time for real. I've been trying to make a mod which makes all guns aim like LMGs do: no iron sights, just "hipzoom." I've asked people to make one like that for me in the past and was told it was too much work. OK, fair enough - I'll make my own. However, I'm running into an issue with that. I'm trying to make this into multiple "persist" scripts, but it seems like BLT will only execute the first script in the list that I've given it. If I put my sights tweaks in there, the guns aim correctly. If I move my sights tweaks into any subsequent scripts, then nothing happens - they don't get executed. I don't understand why that is.
edit
Actually, I figured it out - I was using the same variable to end both scripts, so the first one would set it to true and the second script would never execute because "done == true."
Let me take this chance to ask, though - how are weapon sights calculated? It seems like the lines I care about are these:
self.stances.baka.steelsight.shoulders.translation = pivot_head_translation - pivot_shoulder_translation:rotate_with(pivot_shoulder_rotation:inverse()):rotate_with(pivot_head_rotation)
self.stances.baka.steelsight.shoulders.rotation = pivot_head_rotation * pivot_shoulder_rotation:inverse()
self.stances.baka.steelsight.zoom_fov = false
I know what all the pivot_thing variables are - vectors and rotation angles. I know what those are in theory (Bachelor's degree in applied mathematics 10 years ago, so I still remember a bit of it), but I can't follow the "rotate_with" chain of events. What is this saying? What is it actually doing? I mean sure, I can just copy-paste the lines and it SEEMS to work, but still - how is the whole system hooked up? Also, what is the "zoom_fov" variable for? This is taken from the Micro Uiz which doesn't support sights, but changing this to true doesn't seem to change anything.
Finally, are those alignment settings JUST for steel sights or will they affect scopes? I kind of don't want to mess with scopes for the moment.
edit
Oh, and the code I'm referring to comes from playertweakdata.

I'd like to necro this thread, since the CrimeFest update has sort of undone my experimental changes. I figured out more or less how to restore most of my old changes, but something still eludes me - accuracy and stability. Before than now, they're set in the stats array:
self.m134.stats = {
damage = 38,
spread = 5,
recoil = 2,
spread_moving = 9,
zoom = 1,
concealment = 5,
suppression = 4,
alert_size = 8,
extra_ammo = 6,
total_ammo_mod = 21,
value = 9
}
Thing is, the only thing in this array which seems to correspond to an in-game stat directly is damage. I don't even know what half that stuff does, like value and extra_ammo. I know what spread and recoil do, or what they used to - set the value of accuracy and stability from their old tables. They still seem to do that, but I don't know in what way those values correspond to the final values in the game. I picked 8 for spread, for instance, and that came out as 28 accuracy in-game. Is there still a table somewhere I can check?
And - as before - I'm discussing weapons strictly for suggestions testing and not guns that I would actually use in a game. The deeper I dive into the game's numbers, the greater my need to try out the results first-hand, as a means of giving context to my calculations.

I'm pretty sure both accuracy and stability are indexed by 4, meaning that for every point of accuracy or stability you add, you get +4 accuracy/stability.
Not entirely sure how the new spread and recoil stats work, though. I haven't looked at weapontweakdata much since Crimefest.
Also the zoom_fov is probably meant to be a number value which determines how much your FOV increases by zooming in. It's used to give certain weapons more zoom than others. They probably set it to false, to indicate that the Micro Uzi does not have its own zoom in value.

Yikes, sorry for the late response. Thank you for the explanation. The zoom level tripped me up. Brute force experimentation suggested that accuracy and stability increased by 4 for every 1 "unit." It would also explain why accuracy/stability mods work the way they do - they still shift as many "units" up or down, they just do it over a different table. Really weird design there, but I got my experimental guns working. Something's odd about my calculations on stability, however, so I've tabled the project for the moment. I don't have a good enough mathematical model to approximate it.
I've done some weapon tweaking of my own regarding LMGs and Battle Rifles. The hook_id for modifying weapon stats would be ''lib/tweak_data/weapontweakdata'' for BLT (it's called PostRequire with the old PD2hook.yml)
I've done only some basic changes, here's some of my code that makes LMGs have a bit more Damage/Stability (note, these are not all of the stats a weapon has, these are just the basic ones that are easy to understand and modify):
--Feel free to use different weapon names and numbers, these are just examples. Brenner originally has 14 damage and 5 recoil, being able to reach 34 damage and 19 stability (if modded for 18 accuracy). I modified it to 17 damage and 6 recoil, which lets it reach 42 damage and 20 stability.
Here's some info regarding statistics:
Statistics in the code are not equivalent to the actual statistics in game, there's a certain multiplier for each one that I don't really know (2x or so for damage, not sure for the other stats). The higher the spread, the higher the accuracy of the weapon in-game, the higher the recoil, the higher the stability of the weapon is in-game, etc... etc... I haven't really tried modifying any of the other stats such as spread_moving or ammo, so play around with those and check the in-game statistics with Better Stats GUI.
Some extra, modifying the number of ammo in a magazine and the total ammo of the weapon:
The weapon's total ammo is CLIP_AMMO_MAX multiplied by NR_CLIPS_MAX, with that 150x2=300 total ammo (without the fully loaded skill, if you also wish to modify this, add it somewhere in the code above)
Regarding rate of fire, there are 2 lines of code which numbers can be different for certain weapons like the KSP, so you'll have to experiment with those:
Here is the source code for all the weapons, their file names, other hidden spread modifiers and etc...
https://bitbucket.org/YaPh1l/payday-2-lua/src/8f6fd49d0c9beb0d9f952b8c2a586f04fafb8766/lib/tweak_data/weapontweakdata.lua?at=master&fileviewer=file-view-default
Have fun.