forums | blogs | polls | tutorials | downloads | rules | help

Modding is a process...

Araknuum's picture

Modding is a process of discovery and invention. For every new feature you add or variable you edit, there is something more to learn and experiment with.

I learned today that using the right dot gasses for LOA, where they apply, is vital to not breaking the game. I also learned that Mod Priority doesn't matter if something you modded breaks the game. I learned that [actor_evil] [mind]'s are fickle, and that modding poorly can break save games. Finally, I learned that I can add simple job permissions to templates.gas, and they seem to work:

		////////////////////////////////////////
		//	job permissions

		b actor_auto_fidgets					= true;

		b actor_auto_defends_others                        	= false;
		b actor_auto_heals_others_life                     	= false;
		b actor_auto_heals_others_mana                     	= false;
		b actor_auto_heals_self_life                       	= false;
		b actor_auto_heals_self_mana                       	= false;
		b actor_auto_picks_up_items                        	= false;
		b actor_auto_xfers_mana                            	= false;

		b actor_auto_switches_to_karate			   	= true;
		b actor_auto_switches_to_melee			   	= true;
		b actor_auto_switches_to_ranged			   	= false;
		b actor_auto_switches_to_magic				= false;

		b actor_auto_uses_stored_items				= false;

		b on_enemy_entered_icz_flee                        	= false;
		b on_enemy_entered_ocz_flee                        	= false;
		b on_enemy_entered_weapon_engage_range_attack	   	= true;
		b on_enemy_spotted_alert_friends                   	= true;
		b on_enemy_spotted_attack                          	= true;
		b on_engaged_fled_abort_attack                     	= false;
		b on_engaged_lost_consciousness_abort_attack       	= true;
		b on_engaged_lost_loiter                           	= false;
		b on_engaged_lost_return_to_job_origin             	= true;
		b on_friend_entered_icz_flee                       	= false;
		b on_friend_entered_ocz_flee                       	= false;
		b on_job_reached_travel_distance_abort_attack      	= false;
		b on_life_ratio_low_flee                           	= true;
		b on_mana_ratio_low_flee                           	= false;
		b on_alert_projectile_near_missed_flee			= false;
		b on_alert_projectile_near_missed_attack		= false;
//Testing what adding my own booleans might do. -JD
		b on_engaged_lost_abort_flee				= true;
		b on_flee_distance_reached_attack			= true;

Further testing is required but, this changed so much between adding it and leaving it out. The way those first Krug act, it's eerie... Like they're sick of me coming back to that point in their history and slaughtering them over and over again and have decided to invade Ehb solely to destroy me.

Current [base_krug] [mind]:

[mind]
	{
		com_channels					= dyn_party, krug;
//Making Krug more Alert but Stupid in interesting ways. -JD
		com_range					= 16.5;
		melee_engage_range				= 14.0;
		ranged_engage_range				= 14.8;
		sight_range					= 15.0;
		sight_fov					= 90.0;
		outer_comfort_zone_range			= 6.0;
		inner_comfort_zone_range         		= 2.5;
		visibility_memory_duration			= 5.0
		on_enemy_spotted_alert_friends			= true;
		on_alert_projectile_near_missed_alert_friends	= true;
		on_enemy_spotted_attack				= true;
		on_alert_projectile_near_missed_attack		= true;
//Making Krug Relentless. -JD
		job_travel_distance_limit			= 30.0;
		on_engaged_lost_consciousness_abort_attack	= false;
		actor_life_ratio_low_threshold  		= 0.15;
		on_life_ratio_low_flee                          = true;
		flee_distance					= 7.0;
		flee_count  					= 1;
		actor_balanced_attack_preference		= 0.95;

		jat_fidget					= world\ai\jobs\common\job_fidget.skrit
			?still					= false;

		jat_flee_from_object				= world\ai\jobs\common\job_flee_from_object.skrit
			?run_chance				= 0.63;


All Krug from Farmhouse to Crypt now work together and try to draw you into more danger. Their base speed is more variable, so there is little to no overlapping as groups advance or chase you.

[body]
	{
		min_move_velocity = 0.900;
		avg_move_velocity = 2.200;
		max_move_velocity = 3.500;

I'll be changing the move_velocity for most other mobs in a similar way, as I think the variable movement speeds give combat encounters more variance and survivability. Before changing move_velocity this way, krug would stack on each other and only spread out when they reached you. That sucked bad because "1" visible krug could be 2 or more, and they were likely to all land hits at the same time. Current behavior is so awesome, for real, it feels much more immersive and challenging than vanilla.

Alas, I'm not sure yet why, but something I changed breaks save games. Trying to load any type of save I've made for a test play leads to gathering exceptions. I'll be juggling bits to see if I can make it work, I know there is no problem with SM_Krug_AI.dsres this runs fine on it's own. Only since adding custom templates.gas and formulas.gas back in through their own individual mods has loading saves been broken.

The process continues!

:spider:

blogs: 

Comments

Araknuum's picture

I assumed too much. I assumed earlier that SM_Krug_AI.dsres was the least likely mod to be breaking my saves, but I was wrong. Krug specific changes have been scrapped for now, and save games have worked fine while I fiddle with templates.gas.

I'm not discouraged, in fact it's perfectly ok, because a few of those changes I made assumed too much as well. In fact, this whole process has been centered around testing my assumptions and correcting my mistakes. This has been a hands on experience, and the main thing I'm learning is not to be afraid to try new things and revise assumptions as new data is made clear.

I assumed I could add booleans in templates.gas with a simple added line of text, but this is probably false. I found a list of these parameters in world\ai\jobs\common\brain_hero.skrit, and I'm assuming (sry ming) that I might be able to add to this list, but I want more experience and info before I'll try that. What I will be doing is using the default hero_brain.skrit and the other files in jobs/common as a reference for what changes are possible to all [mind]'s, good, evil, and indifferent.

Just reading these files is a gift of knowledge, though it has been a matter of tracking it all down and remembering where it was again later...

So, I'll just leave this here:

hero_brain Terms:
	------
		Actor 	= owner of the brain.
		Target 	= the actor that the owner is attacking or interacting with.

	Mind.ActorAlertsFriends
		On WE_ENEMY_SPOTTED, the brain will send WE_ALERT_ENEMY spotted to visible
		friends who share the same com channel.

	Mind.OnEnemySpottedAttack
		On WE_ENEMY_SPOTTED, the brain will attack the enemy, permitting standing orders
		allow it.

	Mind.OnEngagedFleedAbortAttack
		On WE_ENGAGED_FLED the brain will terminate any current attack action.  While
		fleeing, the fleeing actor will also no longer be seen as an enemy, so the
		fleeing actor will not be auto-attacked.

	Mind.ActorAttacksOthersInICZ
		If -anyone- is found in the "inner comfort zone", the brain will attack them.
	
	Mind.OnEngagedLostConsciousnessAbortAttack 
		The actor still consider unconsicous actors a threat, and auto-attack them
		when possible, given the current standing-orders.

	Mind.ActorAutoHealsSelfLife
		On WE_LIFE_RATIO_REACHED_LOW actor will drink a health potion if he has one.

	Mind.ActorAutoHealsSelfMana
		On WE_MANA_RATIO_REACHED_LOW actor will drink a health potion if he has one.

	Mind.ActorAutoPicksUpItems
		If the actor is not busy, he will periodically auto-pick up nearby items.

	Mind.ActorAutoUsesActiveSpells
		Any time the actor takes an autonomous action which require using an active
		item, he will consider using any of the active spells.

	Mind.ActorAutoUsesActiveWeapons
		Any time the actor takes an autonomous action which require using an active
		item, he will consider using any of the active weapons.

	Mind.OnEnemyEnteredICZFlee
		Actor will flee from any enemy in his "inner comfort zone."

	Mind.OnEnemyEnteredOCZFlee
		Actor will flee from any enemy in his "outer comfort zone."

	Mind.OnFriendEnteredICZFlee
		Actor will flee from any friend in his "inner comfort zone."

	Mind.OnFriendEnteredOCZFlee
		Actor will flee from any friend in his "outer comfort zone."

	Mind.OnLifeRatioLowFlee
		On WE_LIFE_RATIO_REACHED_LOW the actor will run away from the nearest enemy.

	Mind.OnManaRatioLowFlee                     
		On WE_MANA_RATIO_REACHED_LOW the actor will run away from the nearest enemy.

	Mind.OnJobReachedTravelDistanceAbortAttack
		On WE_JOB_REACHED_TRAVEL_DISTANCE, the actor will terminate any attacking
		action.

	Mind.OnEngagedLostLoiter                    
		On WE_ENGAGED_LOST, the actor will terminate any current attacking
		behavior.

	Mind.OnEngagedLostReturnToJobOrigin         
		On WE_ENGAGED_LOST, the actor will terminate any current attacking
		action and walk back to where the attacking action begun.

	Mind.ActorAutoDefendsOthers
	Mind.ActorAutoHealsOthersLife                     
	Mind.ActorAutoHealsOthersMana                     
	Mind.ActorAutoXfersMana                           

		Used only by party ai, if the actor happens to be in a party.
////////////////////////////////////////
//	party params

property	bool	form_party_on_damaged$			= true	  	doc = "When damaged (only when not attacking) try to find or form a party?";
property	bool	form_party_on_projectile_alert$		= false	  	doc = "When shot by a ranged attack try to find or form a party?";
property	bool	form_party_on_enemy_spotted$		= true	  	doc = "When spotting an enemy try to find or form a party?";
property	bool	form_party_on_alert_enemy_spotted$	= true	  	doc = "When spotting an enemy run to friends and try to find or form a party?";
property	bool	form_party_on_friend_entered_ICZ$	= false	  	doc = "Form or find a party when a friend enters ICZ?";
property	bool	form_party_on_friend_entered_OCZ$	= false	  	doc = "Form or find a party when a friend enters OCZ?";
property	bool	form_party_on_getting_friends$		= true	  	doc = "Form or find a party after running to get friends";

property	float	party_creation_distance$		= 10.0	  	doc = "How far an actor will look to for a party";
property	bool	actor_creates_own_party$		= false	  	doc = "Does this Actor create his own party?";
property	bool	actor_joins_existing_party$		= false	  	doc = "Will this Actor auto join another party?";
property	string	party_template$				= ""	  	doc = "template name of the party to create.";

property	int		stop_flee_party_size$		= -1	  	doc = "If the party size is larger than this then stop fleeing, 
                                                                                       useful for pack style attacks. (-1 to disable check).";
property	int		stop_flee_alive_party_size$	= -1	  	doc = "If the alive party size is larger than this then stop fleeing, 
                                                                                       useful for pack style attacks. (-1 to disable check).";
////////////////////////////////////////
//	friends

property	bool	get_friends$				= false	  	doc = "get friends to help.";
property	bool	run_to_friends$				= false	  	doc = "Run instead of walk to get friends.";
property	float	find_friend_range$			= -1.0	  	doc = "How far an actor will for a friend, -1 to use sight range.";

property	string	friends$						doc = "membership of friends to look for If blank will just look for same alignment.";

property	bool	guard$					= false	  	doc = "try to guard instead of creating a party on the form party conditions.";
////////////////////////////////////////
// flee/heal

property	bool	heal_life_after_flee$			= false	  	doc = "Try to heal life after fleeing from an enemy.";
property	bool	heal_mana_after_flee$		        = false	  	doc = "Try to heal mana after fleeing from an enemy.";
property	bool	heal_when_idle$				= false	  	doc = "Try to heal life when idle.";
property	float	heal_chance$				= 1.0		doc = "Chance to try to heal when Idle";

Go			m_Go$;
GoMind		m_Mind$;
Job			m_Job$;
float		m_OrigSpeed$ = 0.0;
bool		m_HealPending$;
Goid		m_Guardee$;

#include "k_job_c_attack_utils"
////////////////////////////////////////////////////////////////////////////////

:spider: