Jump to content
BMac

[Tutorial] Adding New Abilities to a Class (v4.1.0+)

Recommended Posts

You should be familiar with the Modding Basic Concepts tutorial before following this one.
 
In this tutorial, I'm going to show you how to use a BaseProgressionTableAppendGameData object to add a new ability to a class progression table (ClassProgressionTableGameData) in the game.  You can also use this object to modify character progression tables (CharacterProgressionTableGameData).
 
BaseProgressionTableAppendGameData is a new game data type that was added in v4.1.0.  It simply contains a list of abilities that can be unlocked (along with the requirements needed to unlock them), and a reference to an existing progression table where you want to insert those abilities.
 
Here's an example game data object I created for this tutorial. This object adds the talent Fast Runner as an eligible talent for Priests at Power Level 1.

{
	"GameDataObjects": [
		{
			"$type": "Game.GameData.BaseProgressionTableAppendGameData, Assembly-CSharp",
			"DebugName": "Priest_FastRunner",
			"ID": "5ec6e46a-4e3f-4f78-affe-0d7477d3b97f",
			"Components": [
				{
					"$type": "Game.GameData.BaseProgressionTableAppendComponent, Assembly-CSharp",
					"BaseTableID": "a52e8b61-9343-4716-8a55-3168be143cc4",
					"AbilityUnlocks": [
						{
							"Note": "",
							"Category": "General",
							"UnlockStyle": "Unlock",
							"ActivationObject": "Self",
							"AddAbilityID": "935b1a37-6f38-4ccc-bbc7-296f0f76790f",
							"RemoveAbilityID": "00000000-0000-0000-0000-000000000000",
							"Prerequisites": {
								"MinimumCharacterLevel": 1,
								"PowerLevelRequirement": {
									"ClassID": "f7cb46af-a719-41c0-9a53-107eefdbce2b",
									"MinimumPowerLevel": 1
								},
								"RequiresAbilityID": "00000000-0000-0000-0000-000000000000",
								"Conditional": {
									"Operator": 0,
									"Components": []
								},
								"VisibilityConditional": {
									"Operator": 0,
									"Components": []
								},
								"IsMutuallyExclusiveUpgrade": "true"
							}
						}
					]
				}
			]
		}
	]
}

priest_table_modded.png
 
This object only has two properties:

  • BaseTableID - the GUID of the existing table to modify. For example, "a52e8b61-9343-4716-8a55-3168be143cc4" represents the PT_Priest table.
  • AbilityUnlocks - a list of UnlockableAbility entries to add to the specified table.

You can find detailed information about the various properties of UnlockableAbility by clicking the link.
 
By adding abilities to progression tables this way, you will avoid conflicts with other mods and compatibility problems with updated versions of the game.

  • Like 5

Share this post


Link to post
Share on other sites

Wow, finally! Now maybe I can go back to my subclass mods. Progression table updating has been a major drag that's why I've been lazy updating them. Thanks for this update!

 

Now if there is a way for us to override existing progression table entries (for example, I have a subclass that disables soul whip so I have to modify the conditions of soul whip) that would be even more awesome.

Share this post


Link to post
Share on other sites

 

 


Now if there is a way for us to override existing progression table entries (for example, I have a subclass that disables soul whip so I have to modify the conditions of soul whip) that would be even more awesome.

 

Yeah, it would be good to support that as well. If there is time I'll take another look at that.

 

 

 


Am i right that the old progression tables we are using for our mods so far will still work with 4.1.0? I am just a lazy guy in that aspect... :biggrin:

 

Yes, you can still override the tables the old way, and they will continue to "work" as they did before (i.e. they won't contain any changes we made to them in 4.1 and won't work with other mods on the same table).

Share this post


Link to post
Share on other sites

Huzzah on this addition!  Makes my home modding of PTs so much easier.

 

I do have one question though.  If I wanted to add an ability to ALL progression tables, could I put in a "0000" UUID into the BaseTableID field?  I ask because I have a couple of talents I'm adding to all of the base classes of the game and I didn't want to have to create 11 separate entries if I didn't have to (Yes, I'm lazy  :lol: ).

 

No big deal if I can't, and truth be told I expect I have to manually create an additional Append for each table I want changed.  But I thought I'd ask, if only for future reference. 

 

Thanks again for this addition!

 

edited

 

As a related question, if the standard null 0 UUID can't be put in a BaseTableID, can multiple UUIDs be put in it?  And if so, is there a limit.  Might be interesting to do something like BaseTableID [uUID1, UUID2, ..., UUIDX].

 

Probably a long shot, but no harm in asking, I reckon. :)

Edited by Zap Gun For Hire
  • Like 1

Share this post


Link to post
Share on other sites

No, that won't work unfortunately, you can only put one GUID in there.  I could potentially add support for it if I have time.

  • Like 1

Share this post


Link to post
Share on other sites

Wotcha @zapgunforhire

 

Are you only after modifying the "$type": "Game.GameData.CharacterProgressionTableGameData, Assembly-CSharp", ones?

 

I can automate this

 

I simply need an example and the specific $type to mess with

 

Did this for @Spherikal a few months ago for his enhanced UI

 

Our Slack is still alive so PM me there with specifics and I'll write it for you - it's only an hour or so's work (beats doing it manually)

 

This is simply a conversion job and I have the base code from Spherikal's on my system

  • Like 1

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Share this post


Link to post
Share on other sites

No, that won't work unfortunately, you can only put one GUID in there.  I could potentially add support for it if I have time.

 

Figured as much, but I thought I'd ask.  Not so much for the base classes, but all of the companion PT's out there which I'm also doing.

Wotcha @zapgunforhire

 

Are you only after modifying the "$type": "Game.GameData.CharacterProgressionTableGameData, Assembly-CSharp", ones?

 

I can automate this

 

I simply need an example and the specific $type to mess with

 

Did this for @Spherikal a few months ago for his enhanced UI

 

Our Slack is still alive so PM me there with specifics and I'll write it for you - it's only an hour or so's work (beats doing it manually)

 

This is simply a conversion job and I have the base code from Spherikal's on my system

 

Thanks for the offer, but no worries. :) I can do it pretty quickly on my own end as well.  Was more curious about the idea than anything else. 

Share this post


Link to post
Share on other sites

Just looked at my code

 

150 lines of PHP with expected directories

 

I'll upload it if you like with the assumptions I make if you want

 

Warning - you'll need about 25G on a Linux server or a VM running Ubuntu

 

Sod it - I'll write a howto to generealize the method


OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Share this post


Link to post
Share on other sites

NP Zappy

 

If you've got it covered that's good enough for me

 

Your friend (always) Simon (well just about everyone knows my name <g>)

 

Note I didn't use your real name...

Edited by peardox

OK Fair warning has been applied

 

I'm gonna move the domain to https://perspak.com early Feb but will keep all content

 

There are reasons behind this move which basically boil down to unifying my release schedule

 

My friends are welcome to play (I'll set you up your own areas if you desire them)

 

Please note that this process is messy so may take a few weeks 

Share this post


Link to post
Share on other sites

Huzzah on this addition!  Makes my home modding of PTs so much easier.

 

I do have one question though.  If I wanted to add an ability to ALL progression tables, could I put in a "0000" UUID into the BaseTableID field?  I ask because I have a couple of talents I'm adding to all of the base classes of the game and I didn't want to have to create 11 separate entries if I didn't have to (Yes, I'm lazy  :lol: ).

 

No big deal if I can't, and truth be told I expect I have to manually create an additional Append for each table I want changed.  But I thought I'd ask, if only for future reference. 

 

Thanks again for this addition!

 

edited

 

As a related question, if the standard null 0 UUID can't be put in a BaseTableID, can multiple UUIDs be put in it?  And if so, is there a limit.  Might be interesting to do something like BaseTableID [uUID1, UUID2, ..., UUIDX].

 

Probably a long shot, but no harm in asking, I reckon. :)

 

 

No, that won't work unfortunately, you can only put one GUID in there.  I could potentially add support for it if I have time.

 

After a lot of trial and error, I actually figured out a way to have it so something can go into all classes at one time.  :thumbsup:   Instead of pointing the "BaseTableID": to a CLASS or COMPANION PT, I pointed it to  the RACIAL PT that defines what races get what  ("b2afaada-c140-42c3-9f02-2f919e45b49d") and followed the template of "Weapon Proficiency: Unarmed" (with a couple of further modifications).

 

Worked like a charm.   :dancing:

 

In fact, if I had thought of this before, I would have saved myself a ton of hassle (not to mention around a couple dozen UUIDs).  :facepalm:

 

Now the ability I am adding IS an Auto-Granted one, so I don't know what would happen if someone tried to use this back-door trick for a user selected one on level up.  But at least I'm happy.  :lol:

 

====

 

Fun fact though.  Only reason I even hit upon this is I was getting VERY annoyed trying to figure out how to stop the multi-class hired adventurers I was creating as an edge case from getting duplicate copies of my auto-granted ability.  I tried every last thing I could think of and kept seeing duplication.

 

Then I finally thought, "Hey... Wait a second.  Racial traits don't get duped on character creation.  Maybe I should figure out how they're put into characters."

 

Little while latter: SUCCESS!!  Even works for Imported Characters on hiring, which is even better than inserting into the class PTs, as they weren't getting the new Auto Generated trait until they leveled up.

 

Still need to clean up my code a little, but it seems to be working as I want now. :)

Edited by Zap Gun For Hire
  • Like 1

Share this post


Link to post
Share on other sites

You know how recipes have a line to add an itemmod and a line to remove one? Would it be possible to have something similar with this? RemoveAbilitiesFromProgressionTable or something? Or maybe make them invisible rather than removing them? If that could be done then in addition to adding abilities to progression tables we could also replace abilities, which would be very exciting

Share this post


Link to post
Share on other sites

You know how recipes have a line to add an itemmod and a line to remove one? Would it be possible to have something similar with this? RemoveAbilitiesFromProgressionTable or something? Or maybe make them invisible rather than removing them? If that could be done then in addition to adding abilities to progression tables we could also replace abilities, which would be very exciting

{
							"Note": "PL 5 Unlock - Weapon Training",
							"Category": "General",
							"UnlockStyle": "Unlock",
							"ActivationObject": "Self",
							"AddAbilityID": "c6649642-7729-4386-ae1c-6980351fe8c6",
							"RemoveAbilityID": "00000000-0000-0000-0000-000000000000",
							"Prerequisites": {
								"MinimumCharacterLevel": 1,
								"PowerLevelRequirement": {
									"ClassID": "ccdc9675-e2a7-46fa-83e9-7a5368b56265",
									"MinimumPowerLevel": 5
								},
								"RequiresAbilityID": "00000000-0000-0000-0000-000000000000",
								"Conditional": {
									"Operator": 0,
									"Components": []
								},
								"VisibilityConditional": {
									"Operator": 0,
									"Components": []
								},
								"IsMutuallyExclusiveUpgrade": "true"
							}
						}

This is one of the custom abilities I have on my home mods (it lets a class select an additional Weapon Set at level up starting at Power Level 5) that is part of a larger set of abilities I am adding to a PT (so I'm not posting the entire code block here). I know for a fact that VisibilityConditional can remove something from view on a PT, in both standard and append.  I haven't played around with RemoveAbilityID or RequiresAbilityID, but just at a glance it looks like it should be able to remove an ability and replace it with a different one.

 

Or have you tried that and it didn't do what you wanted?

Edited by Zap Gun For Hire

Share this post


Link to post
Share on other sites

It looks to me like removing an ability from a progression table is actually just making it invisible via the VisibilityConditional. I've started using the conditional "Boolean AlwaysFalse()" as a means for making something invisible.

 

When you upgrade an ability you're actually training a new ability and removing the old, hence the RemoveAbilityID. This would not function to remove an ability from the PT completely though. Interestingly (in previous version; untested in 4.1), I could RemoveAbilityID while having a "0000-" in the AddAbilityID without causing problems.

 

RequiresAbilityID is mostly, but not entirely, the aesthetic for connecting two abilities with a line. I say not entirely because it does have some functionality beyond the connecting line but I've never tried to track down exactly what that functionality is.

  • Like 1

Share this post


Link to post
Share on other sites

So, it looks like this new capability does not allow us to modify existing entries on a class progression table (ClassProgressionTableGameData). I have not researched the "modify" potential of the CharacterProgressionTableGameData but I'm assuming it is the same.

 

I guess I just misread and assumed that that was the new capability. So, if we want to remove, rearrange, or reconnect existing abilities we have to still override the entire progression table.

 

Can anyone else confirm?

Share this post


Link to post
Share on other sites

BMac,can you use this method to add multiple abilities to the same table?  If so could you show another example?  Thanks.

Share this post


Link to post
Share on other sites

So, it looks like this new capability does not allow us to modify existing entries on a class progression table (ClassProgressionTableGameData). I have not researched the "modify" potential of the CharacterProgressionTableGameData but I'm assuming it is the same.

 

I guess I just misread and assumed that that was the new capability. So, if we want to remove, rearrange, or reconnect existing abilities we have to still override the entire progression table.

 

Can anyone else confirm?

Unfortunately, yes, that's correct.

 

BMac,can you use this method to add multiple abilities to the same table?  If so could you show another example?  Thanks.

Yes, you just need to duplicate the object in the AbilityUnlocks array. This example redundantly adds the same ability twice, just to show the syntax:

 

{
	"GameDataObjects": [
		{
			"$type": "Game.GameData.BaseProgressionTableAppendGameData, Assembly-CSharp",
			"DebugName": "Priest_FastRunner",
			"ID": "5ec6e46a-4e3f-4f78-affe-0d7477d3b97f",
			"Components": [
				{
					"$type": "Game.GameData.BaseProgressionTableAppendComponent, Assembly-CSharp",
					"BaseTableID": "a52e8b61-9343-4716-8a55-3168be143cc4",
					"AbilityUnlocks": [
						{
							"Note": "",
							"Category": "General",
							"UnlockStyle": "Unlock",
							"ActivationObject": "Self",
							"AddAbilityID": "935b1a37-6f38-4ccc-bbc7-296f0f76790f",
							"RemoveAbilityID": "00000000-0000-0000-0000-000000000000",
							"Prerequisites": {
								"MinimumCharacterLevel": 1,
								"PowerLevelRequirement": {
									"ClassID": "f7cb46af-a719-41c0-9a53-107eefdbce2b",
									"MinimumPowerLevel": 1
								},
								"RequiresAbilityID": "00000000-0000-0000-0000-000000000000",
								"Conditional": {
									"Operator": 0,
									"Components": []
								},
								"VisibilityConditional": {
									"Operator": 0,
									"Components": []
								},
								"IsMutuallyExclusiveUpgrade": "true"
							}
						},
						{
							"Note": "",
							"Category": "General",
							"UnlockStyle": "Unlock",
							"ActivationObject": "Self",
							"AddAbilityID": "935b1a37-6f38-4ccc-bbc7-296f0f76790f",
							"RemoveAbilityID": "00000000-0000-0000-0000-000000000000",
							"Prerequisites": {
								"MinimumCharacterLevel": 1,
								"PowerLevelRequirement": {
									"ClassID": "f7cb46af-a719-41c0-9a53-107eefdbce2b",
									"MinimumPowerLevel": 1
								},
								"RequiresAbilityID": "00000000-0000-0000-0000-000000000000",
								"Conditional": {
									"Operator": 0,
									"Components": []
								},
								"VisibilityConditional": {
									"Operator": 0,
									"Components": []
								},
								"IsMutuallyExclusiveUpgrade": "true"
							}
						}
					]
				}
			]
		}
	]
}

Share this post


Link to post
Share on other sites

Presumably that bug is why there's the new "tactical override" line. Now to fill that in I just need to remember what all my items do!

Share this post


Link to post
Share on other sites

@BMac: Do you have any idea why our modded abilities are completly broken in turn-based-mode so there is "shaken" everywhere in the decriptions?

 

Would be really cool if we could fix this! :)

 

https://forums.obsidian.net/topic/105780-mod-the-class-project/?p=2136867

 

I think I know what's up there. You can probably fix it by adding "OverrideDescriptionStringTactical": -1 to your status effects. Unfortunately it sounds like that's defaulting to 0 when omitted, which indicates string ID 0, whereas -1 indicates "don't use this".  I'll see if I can do something about that on my end for 4.1.1. 

"As the murderhobo mantra goes: 'If you can't kill it, steal it.'" - Prince of Lies

Share this post


Link to post
Share on other sites

Unsure if this is the right place to ask, but what about adding completely new spells to the game?

 

I'm considering making a Paladin pack that adds a handful of spells and strikes to the various kits to enhance the strengths and weaknesses of a given Order. For some spells I can just give access via the method in the OP, but I'm less sure about adding in new spells.

Share this post


Link to post
Share on other sites

Yes, you can create new spells and add them to progression tables this way.  You'll just need to create a new GenericAbilityGameData object with a new GUID in addition to making the object described here.  I don't believe we have a tutorial specifically about creating spells, but the basic concepts tutorial and  this tutorial may help.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...