Jump to content

[1.8.x-1.12.x] Module Manager 4.2.3 (July 03th 2023) - Fireworks season


sarbian

Recommended Posts

18 hours ago, blowfish said:

Okay, that makes more sense.  Does building the new "welded" part config involve MM patching, or are you putting it in the game database in its final state?

In it's final state - but the idea of being able to apply patches instead can be useful in the long run. However, baby-steps - we don't need to build up Rome in a single shot.

What I need on the short run, in a nutshell:

  1. A standard method to inject new parts into the GameDatabase without stomping on other people's toes.
    1. Handling concurrency, i.e., as more than one can try the stunt at the same time, this mechanism runs the calls in a Critical Region
  2. A standard method, probably similar, to edit an existent part on the same requirements (Critical Region, etc)
  3. A Reflection safe way to allow Add'Ons to check/instantiate the feature, to overcome that nasty Mono's runtime bug.
  4. A strong recommendation to every Add'On author to use that methods, so we can inject/edit/create nodes on the GameDatabase at runtime without wasting scarce resources (as my hair) in the process. :) 

I think we can reach these requirements on this way:

// Names and symbols as example only - no naming suggestions are intended on what follows

using mmgdbu = ModuleManager.GameDatabaseUtils;

void function foobar() {
	List<ConfigNode> nodes_to_add = this.create_a_lot_of_nodes();
	using (ConfigNode node = mmgdbu.Find(<some criteria>) // This locks the thread if the MUTEX cannot be acquired now
	{	// Node and everything inside (including other sub nodes) is now locked on MM.
		node.change("datum", new_value);
		ConfigNode foo = node.get("BAR");   
		foo.add("lisias", "was here!");
		foo.add("moar_nodes", nodes_to_add);
	}
	// The lock is lifted. Any other thread will be able to acquired that node (or its sons) now.
}

ScanSAT, KIS, KAS, TweakScale and everybody else would need to acquired a lock before finishing their business on the GameDatabase - what will ensure integrity as everybody tries to do that at the same time on startup.

This will probably be useful for VAB/SPH editing extensions too on the long run. Some extensions does some computations on the background, and if anyone else changes that same ConfigNode, we can have a crash on the same way TweakScale was getting on Startup in the past.

Edited by Lisias
uh. yeah. mero tyops.
Link to comment
Share on other sites

Hi there. I've been trying to get a small patch working for the past week, scouring the web/threads for information but since I can't figure it out:
Is it normal that you cannot use a | in a HAS block? Or well, you can, but everything after it will be ignored without error.

What I'm trying to do is target a subset of experimentID's and within that subset target the subset that has a xmitDataScalar key <1.
My current (working) patch is this:

Spoiler

@PART[*]:HAS[@MODULE:HAS[#experimentID[*]&#xmitDataScalar[<1]]]:FOR[zJognt]
{
	@MODULE:HAS[#experimentID[temperatureScan]]
	{
		//%xmitCheck = #$xmitDataScalar$ | $experimentID$ | $../name$
		@xmitDataScalar = 1.0
	}
	@MODULE:HAS[#experimentID[barometerScan]]
	{
		//%xmitCheck = #$xmitDataScalar$ | $experimentID$ | $../name$
		@xmitDataScalar = 1.0
	}
	@MODULE:HAS[#experimentID[seismicScan]]
	{
		//%xmitCheck = #$xmitDataScalar$ | $experimentID$ | $../name$
		@xmitDataScalar = 1.0
	}
	@MODULE:HAS[#experimentID[gravityScan]]
	{
		//%xmitCheck = #$xmitDataScalar$ | $experimentID$ | $../name$
		@xmitDataScalar = 1.0
	}
	@MODULE:HAS[#experimentID[atmosphereAnalysis]]
	{
		//%xmitCheck = #$xmitDataScalar$ | $experimentID$ | $../name$
		@xmitDataScalar = 1.0
	}
	@MODULE:HAS[#experimentID[infraredTelescope]]
	{
		//%xmitCheck = #$xmitDataScalar$ | $experimentID$ | $../name$
		@xmitDataScalar = 1.0
	}
}

 

 

But I just can't accept that I can't get it done without having to repeat the 'set key' bit. I've been trying the following, but that only targets those with temperatureScan. :/
I've also tried placing all the experiment types in the first experimentID block but that also did not work. Even dropping the subset of the subset (xmitDataScalar <1) didn't make a difference.

Spoiler

@PART[*]:HAS[@MODULE:HAS[#experimentID[temperatureScan]|#experimentID[barometerScan]|#experimentID[seismicScan]|#experimentID[gravityScan]|#experimentID[atmosphereAnalysis]|#experimentID[infraredTelescope]]]
{
	@MODULE:HAS[#experimentID[temperatureScan]|#experimentID[barometerScan]|#experimentID[seismicScan]|#experimentID[gravityScan]|#experimentID[atmosphereAnalysis]|#experimentID[infraredTelescope]]
	{	
		%xmitCheck = #$xmitDataScalar$ | $experimentID$ | $../name$
		//@xmitDataScalar = 1
	}
}

Note: This is not the exact exact code, tried a lot, deleted a lot, settled for the 'ugly' but working version above (which is exact).

Edited by Jognt
Link to comment
Share on other sites

1 hour ago, Jognt said:

Is it normal that you cannot use a | in a HAS block? Or well, you can, but everything after it will be ignored without error.

Yeah, had the same issue a few month ago, seem to be normal^^

How about addressing every part with module "ModuleScienceExperiment" and if it has the key xmitDataScalar < 1, do your stuff:

@PART[*]:HAS[@MODULE[ModuleScienceExperiment]]
{
	@MODULE[ModuleScienceExperiment]:HAS[#xmitDataScalar[<1]]
	{
		@xmitDataScalar = 1.0
	}
}

Any specific reason why you want to identify the parts by their experiment ID?

Edited by 4x4cheesecake
Link to comment
Share on other sites

10 hours ago, 4x4cheesecake said:

Yeah, had the same issue a few month ago, seem to be normal^^

How about addressing every part with module "ModuleScienceExperiment" and if it has the key xmitDataScalar < 1, do your stuff:


@PART[*]:HAS[@MODULE[ModuleScienceExperiment]]
{
	@MODULE[ModuleScienceExperiment]:HAS[#xmitDataScalar[<1]]
	{
		@xmitDataScalar = 1.0
	}
}

 

Drat.. it works in the PART[] bit, in the NEEDS[] bit, but not in the HAS[] bit? :huh:

I'd rather not address it by going for ModuleScienceExperiment because:
1. I don't want it to apply to stuff like Goo/Science Jr;
2. Some mods utilize their own science module while still utilizing stock experimentIDs (like DMagic and US2);

The goal is a patch that is broad enough to cover every part (stock or modded) that calls for specific stock experimentIDs yet narrow enough to not hit all the science parts.

Edit: The reason for using experimentID is so that I can target all experiments regardless of their module name that are of that type while ignoring other types.
By type I mean 'numerical value'. Any experiment that boils down to 'what does the sensor say?' should be 100% transmittable. But stuff that requires a wise scientist to interpret what he sees should be partial.

Edit2: I guess I could target the rerunnable=true key as it looks like it's only present on the exact experiments I defined, but I'm not sure about the odds of mods adding experiments that would add it for 'non simple' science.

 

Edited by Jognt
Link to comment
Share on other sites

7 minutes ago, Gordon Dry said:

@blowfish in https://github.com/sarbian/ModuleManager/wiki/Module-Manager-Handbook it says:


& or , for "AND"
| for "OR"

Is this also valid for @PART[abc|def] ? Is that an OR or an AND?

Module Manager Syntax page says:

You can use & for AND, | for OR and ! for NOT in the needs listing.

I would imagine that means you can't use it in the PART part, but I suppose it's no guarantee.

Edited by UnanimousCoward
Link to comment
Share on other sites

Question about HAS:
How do I target 'stuff' that does not have the HAS?

Reason I ask is because of the new deployed experiments. I've always played with Maculator's Science Full Value mod which sets the baseValue to scienceCap, but Breaking Ground's deployed experiments use the baseValue for the amount they create per hour.
So I was looking to target all EXPERIMENT_DEFINITION:HAS[!id[deployed*]] which does not work (tried several versions of ! placement with/without #id instead of id).

I ended up adding a oldBV value to all experiment_definition's, targeting all of them, then setting them back for those with deployed* in their id, and removing the oldBV from all definitions afterwards, but I am wondering if there's a better way.

Link to comment
Share on other sites

13 minutes ago, Jognt said:

Question about HAS:
How do I target 'stuff' that does not have the HAS?

Reason I ask is because of the new deployed experiments. I've always played with Maculator's Science Full Value mod which sets the baseValue to scienceCap, but Breaking Ground's deployed experiments use the baseValue for the amount they create per hour.
So I was looking to target all EXPERIMENT_DEFINITION:HAS[!id[deployed*]] which does not work (tried several versions of ! placement with/without #id instead of id).

I ended up adding a oldBV value to all experiment_definition's, targeting all of them, then setting them back for those with deployed* in their id, and removing the oldBV from all definitions afterwards, but I am wondering if there's a better way.

in a :HAS block

  • @ means "has node"
  • ! means "does not have node"
  • # means "has value"
  • ~ means "does not have value"
Link to comment
Share on other sites

6 minutes ago, blowfish said:

in a :HAS block

  • @ means "has node"
  • ! means "does not have node"
  • # means "has value"
  • ~ means "does not have value"

Wait, do you mean key or value? If I write "~id[software]" is it going to ignore anything with an "id =" key/value, or is it going to ignore any "id =" that have "software" in it?

Edit: Thank you for the reply :)

Edited by Jognt
Link to comment
Share on other sites

1 minute ago, Jognt said:

Wait, do you mean key or value? If I write "~id[software]" is it going to ignore anything with an "id =" key/value, or is it going to ignore any "id =" that have "software" in it?

Edit: Thank you for the reply :)

:HAS[#foo[bar]]

  • will match foo = bar
  • will not match foo = baz
  • will not match a node without foo

:HAS[~foo[bar]]

  • will match foo = baz
  • will match a node without foo
  • will not match foo = bar
Link to comment
Share on other sites

1 minute ago, blowfish said:

:HAS[#foo[bar]]

  • will match foo = bar
  • will not match foo = baz
  • will not match a node without foo

:HAS[~foo[bar]]

  • will match foo = baz
  • will match a node without foo
  • will not match foo = bar

Thank you very much! :)

Link to comment
Share on other sites

@Lisias okay, so again correct me if I'm wrong, but it sounds like you don't actually need ModuleManager to re-patch the game database (which would take extra time), but to act as a coordinator for other mods recompiling parts via the part loader?

Link to comment
Share on other sites

13 hours ago, blowfish said:

@Lisias okay, so again correct me if I'm wrong, but it sounds like you don't actually need ModuleManager to re-patch the game database (which would take extra time), but to act as a coordinator for other mods recompiling parts via the part loader?

Yes, it's exactly this. I like the term "Arbitrator" more than "Coordinator", as this feature needs to be somewhat authoritative on the decision making, but it's it. Even by not allowing re-patching (and I never considered this before, this good idea is your fault!! :D ), such arbitration appears to be better implemented on Module Manager due it's inherent nature of handling the GameDatabase.

Third parties being able to recompiling parts via part loader would be one of the features under the authority of such Arbitrator - the problem to be solved is to allow access to GameDatabase under Critical Sections to prevent the Add'Ons triggering a Toe Stomping Fest.

Locking up the whole GameDatabase would be highly inefficient as it would serialize processes that could be executed concurrently, but it's a quick & dirty way to solve the problem for a POC (Proof of Concept).

Link to comment
Share on other sites

Hey sorry, very newbie mod-writing question:

I'm trying to get my mind around a way to set up something where specific tech tree nodes are reliant on a specific "building level", so for instance maybe you can only unlock heavyRocketry if you have VAB level 2 or something.

I think maybe theres a hacky way to do it by writing a module that reads building levels and then locks a node based on if MM drops a line somehow adding "building level" requirements to specific tech nodes, but i cannot get my mind around how to crack such a thing out.

Is there a smoother system that already exists through MM that i need to read up on? Has anyone seem something similar to this done?

Link to comment
Share on other sites

Question: can module manager patch the rocsdef.cfg file where Squad keeps the Breaking Ground surface features in order to add them to planet packs (or just mod stock planets) without modifying that file? And if so, how?

Link to comment
Share on other sites

14 hours ago, juanml82 said:

Question: can module manager patch the rocsdef.cfg file where Squad keeps the Breaking Ground surface features in order to add them to planet packs (or just mod stock planets) without modifying that file? And if so, how?

Spoiler

ROC_DEFINITION:NEEDS[GPP,SquadExpansion/Serenity]{
  Type = GaelVolcanicEjecta
  displayName = Volcanic Ejecta
  prefabName = dunaEjecta
  modelName = dunaEjecta
  OrientateUp = true
  Depth = 0.5
  CanBeTaken = true
  Frequency = 5  
  CastShadows = true
  ReceiveShadows = true
  CollisionThreshold = 50
  SmallROC = true
  RandomDepth = true
  RandomOrientation = false
  RandomRotation = true
  localSpaceScanPoints = 0, 0.4, 0
  CELESTIALBODY{
    Name = Gael
    Biome = Pligia Shores
    Biome = Volcano
  }
}

Have yet to find any on the surface, but the syntax is valid, and ConfigCache shows it as proper node.

Edited by Corax
*$+/&% forum software
Link to comment
Share on other sites

On 6/10/2019 at 11:50 AM, Corax said:
  Reveal hidden contents

ROC_DEFINITION:NEEDS[GPP,SquadExpansion/Serenity]{
  Type = GaelVolcanicEjecta
  displayName = Volcanic Ejecta
  prefabName = dunaEjecta
  modelName = dunaEjecta
  OrientateUp = true
  Depth = 0.5
  CanBeTaken = true
  Frequency = 5  
  CastShadows = true
  ReceiveShadows = true
  CollisionThreshold = 50
  SmallROC = true
  RandomDepth = true
  RandomOrientation = false
  RandomRotation = true
  localSpaceScanPoints = 0, 0.4, 0
  CELESTIALBODY{
    Name = Gael
    Biome = Pligia Shores
    Biome = Volcano
  }
}

Have yet to find any on the surface, but the syntax is valid, and ConfigCache shows it as proper node.

Huh. It doesn't seem to be working, though probably not because of the syntax. Even the ROC finder in the cheat menu finds nothing

Link to comment
Share on other sites

3 hours ago, juanml82 said:

Huh. It doesn't seem to be working, though probably not because of the syntax. Even the ROC finder in the cheat menu finds nothing

Yes, I'm still figuring it out, like I said I have yet to find any... that snippet was just to answer your question of whether and how it is possible to patch the ROCs.

Link to comment
Share on other sites

I have a part which has two ModuleAnimateGeneric modules.  The only significant difference between them is the animationName

I need to replace one of them, but I can't assume any specific order.  Is it possible to delete a  module based on a value inside the module?

Link to comment
Share on other sites

1 hour ago, linuxgurugamer said:

I have a part which has two ModuleAnimateGeneric modules.  The only significant difference between them is the animationName

I need to replace one of them, but I can't assume any specific order.  Is it possible to delete a  module based on a value inside the module?

so something like :

  • @MODULE[ModuleAnimateGeneric]:HAS[name=this]{}
  • @MODULE[ModuleAnimateGeneric]:HAS[name=that]{}

was thinking the same.

Link to comment
Share on other sites

6 hours ago, linuxgurugamer said:

That actually worked!  Surprised me, but it was a pleasant surprise

well blow me up out of an airlock and call me Jeb....hotdiggitydarn and Jiminy Crickets!

can't wait to see the patch now.

Edited by zer0Kerbal
Link to comment
Share on other sites

am attempting to write a patch that puts SAS into a part, but limits it due to the techtree.

pseudocode:

Spoiler

@PART[dohickieone]]:FOR[] {
	MODULE[ModuleSAS]:HAS[@MODULE[!ModuleSAS]] {
		name = ModuleSAS
		SASServiceLevel = 0
		@SASServiceLevel:NEEDS[advUnmanned] = 1
	}
}

 

this should work - just need help on the :NEEDS statement - how to reference the techtree for a specific tech?

Edited by zer0Kerbal
unbalanced brackets
Link to comment
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.

×
×
  • Create New...