Jump to content

[1.10.1+] Contract Configurator [v1.30.5] [2020-10-05]


nightingale

Recommended Posts

6 hours ago, nightingale said:

 

@Chippy the Space Dog - What contract packs do you have installed?  If I remember correctly, there's one or two that disable rescue contracts (but I forget which).  In the space centre, click the Contract Configurator icon, and then check whether the RecoverAsset line is disabled or not (you can mouseover to see what disabled it, and click it to re-enable for that save).

Thank you!  It was deselected. I have Bases & Stations, Grand Tours, Tourism, Unmanned, and Remote Tech.  When I started I also had Anomalies, GAP and Field Science, but I removed those in case Rescues were being crowded out somehow. I've turned on RecoverAsset now and I'm confident I'll see rescue missions soon :)

Link to comment
Share on other sites

Probably a simple answer. Can you make a reward the same regardless of the multipliers?

I know you can write something like this:

rewardFunds = 10000.0 / @targetBody.Multiplier()

But that isn't always ideal.

Usecase is this, New Horizons sets the multiplier for Kerbin at 0.35-0.45. That's fine for science, but wreaks havoc for funds. Contracts like the ones from GAP, pay literally nothing. As in you couldn't even make your fuel back.

Just curious what the best way is.

Link to comment
Share on other sites

13 minutes ago, Nori said:

Probably a simple answer. Can you make a reward the same regardless of the multipliers?

I know you can write something like this:

rewardFunds = 10000.0 / @targetBody.Multiplier()

But that isn't always ideal.

Usecase is this, New Horizons sets the multiplier for Kerbin at 0.35-0.45. That's fine for science, but wreaks havoc for funds. Contracts like the ones from GAP, pay literally nothing. As in you couldn't even make your fuel back.

Just curious what the best way is.

Maybe this is what you want?

rewardFunds = 10000.0 / (@targetBody.IsHomeWorld() ? @targetBody.Multiplier() : 1.0)

If you're looking to do this with Module Manager....  well I'm fairly certain that's not possible (or at least very difficult) because I don't believe MM has an 'append to value' operation:

 

Link to comment
Share on other sites

1 hour ago, 5thHorseman said:

How hard would it be to add checkboxes in the "All" tab to filter out unavailable (because you don't meet the requirements) and/or completed (because you've completed the contract the maximum number of times you can ever complete it)?

Moderate difficulty.  I'd probably copy the prefabs from the archive tab and use those, so it's not *too* bad.  But big enough that I wouldn't even consider it until after 1.2.

Link to comment
Share on other sites

34 minutes ago, nightingale said:

Moderate difficulty.  I'd probably copy the prefabs from the archive tab and use those, so it's not *too* bad.  But big enough that I wouldn't even consider it until after 1.2.

Totally fair. I'll open an enhancement request so you don't have to remember. If it's not doable I'm cool with that, it'd just help my pack that has almost 300 contracts :)

Link to comment
Share on other sites

I am terrible with Syntax, and I seem to also suck at searching the wiki.

You helped me before in making a single CONTRACT_TYPE for each set of parts (propulsion, aero, pods, etc) and it works great, but it generates a contract to unlock parts that are unlocked at the start of the game (mk1 pod, flea booster, etc) and I'm trying to figure out how to exempt them from being added.

The code you gave me was this, for pods for example:

    DATA_EXPAND
    {
        type = AvailablePart
        part = AllParts().Where(p => p.Category() == Pods)

        hidden = true
    }

I'm trying to add a clause into that code that causes it to ignore parts with a "TechRequired" of "start". Currently, I have this:

    DATA_EXPAND
    {
        type = AvailablePart
        part = AllParts().Where(p => (p.Category() == Pods && p.TechRequired() != start))

        hidden = true
    }

But I also tried:

        part = AllParts().Where(p => p.Category() == Pods && p.TechRequired() != start)
        part = AllParts().Where(p => p.Category() == Pods && p => p.TechRequired() != start)

And I even tried to split it up even though I don't know if I can just define variables willy-nilly, or even if I've got this syntax correct:

	noStartPart = AllParts().Where(p => p.TechRequired() != start)
        part = noStartPart().Where(p => p.Category() == Pods)

Each attempt caused all contracts in the "Pods" category to just up and not be generated, with an error like this in the log:

ContractConfigurator.ContractType: CONTRACT_TYPE 'PartPods': Values captured in a DATA_EXPAND node must be deterministic (the value needs to be fixed when loaded on game startup.
ContractConfigurator.ContractType: CONTRACT_TYPE 'PartPods': Received an empty list of values when trying to do a DATA_EXPAND
ContractConfigurator.ContractType: CONTRACT_TYPE 'PartPods': Error parsing title
Exception: Unknown identifier '@/part'.

UnityEngine.Debug:Internal_LogException(Exception, Object)
UnityEngine.Debug:LogException(Exception)
ContractConfigurator.LoggingUtil:LogException(Exception)
ContractConfigurator.ConfigNodeUtil:ParseValue(ConfigNode, String, Action`1, IContractConfiguratorFactory, String, Func`2)
ContractConfigurator.ConfigNodeUtil:ParseValue(ConfigNode, String, Action`1, IContractConfiguratorFactory, Func`2)
ContractConfigurator.DeferredLoadUtil:ExecuteLoad(DeferredLoadObject`1)
System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
ContractConfigurator.ConfigNodeUtil:ExecuteDeferredLoads()
ContractConfigurator.ContractType:Load(ConfigNode)
ContractConfigurator.<LoadContractConfig>d__26:MoveNext()
ContractConfigurator.ContractConfigurator:Update()

I'm starting to think I just can't use TechRequired() to filter parts. Is this true? I don't see a list of what IS allowed to look for in the wiki, so I assumed that each thing was available. Is this not true, and if so can it be?

And assuming I CAN search on it, what am I doing wrong? What syntactical mistake am I making this time?

Link to comment
Share on other sites

30 minutes ago, 5thHorseman said:

I am terrible with Syntax, and I seem to also suck at searching the wiki.

While I still stand behind this statement, I seem to have sussed it out. I found this page that helped immensely, and finally ended up with:

        part = AllParts().Where(p => (p.Category() == Pods) && (p.UnlockCost() != 0))

which of course has nothing to do with the TechRequired thing but it IS a valid test. :)

Link to comment
Share on other sites

Another "how hard would it be..." question.

The timer parameter sets up a timer, at the end of which the contract fails. How hard would it be to allow the contract, at the end of that timer, to succeed?

I'm thinking:

PARAMETER
{
    name = Timer
    type = Timer

    duration = 1s
    timerType = CONTRACT_ACCEPTANCE
    failContract = false
    passContract = true
}

...to pretty much set up a contract that automatically succeeds.

Alternatively, is there a way to set up a contract that automatically succeeds? I haven't found one but I sometimes fail at clever.

Link to comment
Share on other sites

3 hours ago, nightingale said:

@5thHorseman - That would be the Duration parameter.  Which is separate from the Timer parameter for either historical or technical reasons (I honestly can't remember which).  Which is different still from the MissionTimer parameter, which just counts up for fun & profit.

For some reason I thought that had to be a child parameter of other things.

However, now that I test it it's a bit fidgety. It requires you to spend that time in control of a vessel, even if it's the only parameter in the contract. Time spent just sitting in the Space Center window (I understand why time in Mission control doesn't count but in the Space Center, time actually ticks) doesn't count. I understand I'm not using the parameter as it's intended, but I still wonder is there a way to make it work all on its own without having to control a ship?

I tried setting the number of seconds to 0s but - while it works the same as 1s only quicker - it still doesn't auto-complete the contract. I understand that for 99% of contract ideas you want the person to be controlling a vessel, but for my purposes, having 0s auto-complete would be perfectly fine.

I also tried being clever (which rarely gets me anywhere) and left off all parameters, and sure enough the log tells me a contract requires at least one parameter to function.

If I'm out of luck that's fine, the part test idea works, it's just a little clunky especially early in career when you only have 2 available contracts at a time.

Edited by 5thHorseman
Link to comment
Share on other sites

41 minutes ago, 5thHorseman said:

It requires you to spend that time in control of a vessel, even if it's the only parameter in the contract. Time spent just sitting in the Space Center window (I understand why time in Mission control doesn't count but in the Space Center, time actually ticks) doesn't count. I understand I'm not using the parameter as it's intended, but I still wonder is there a way to make it work all on its own without having to control a ship?

I don't know if this helps or not, but @DMagic's Orbital Science add-on creates a few new contract types that involve putting a vessel with a certain part into orbit for x amount of days. The contract keeps track of (and displays) the number of days remaining. Time counts down whether you are focusing on the target vessel, another vessel, or at the KSC or Tracking Station. The contracts can even complete while timewarping at the KSC. I don't think his mod uses CC, so I don't know what magic he uses to make this happen, but maybe looking at what he's done can help you figure out how to do what you are trying to do?

 

Link to comment
Share on other sites

@5thHorseman - Raise a GitHub issue - there shouldn't be any reason it won't work in the Space Center, so I'd call it a bug.

@Merkov - Not really helpful, since DMOS doesn't use Contract Configurator, as you said.  This is more a case of a bug - normally it works under all the circumstances you've described.

Link to comment
Share on other sites

More stuff! Yay, right?

I have a Requirement set up for all my contracts, that you must have the amount of money that the contract will cost you to take. Currently that's 10 times the "unlock cost" (thanks for adding that) and it works just fine, even with the negative number. I have these two clauses in each contract:

	advanceFunds = [email protected]() * 10

	REQUIREMENT
	{
		name = Funds
		type = Funds
		minFunds = @/part.UnlockCost() * 10
	}
	

Now this works fine. If you have the money, the contract is available to take and you can take it. It deducts your funds and accepts the contract. If you don't have the money, the contract is in the "All" tab greyed out because you don't meet the requirement.

The problem occurs when you are low on funds and accept 2 contracts in quick succession. If you have, say, 20,000 funds and there are two contracts that each cost 15,000 funds, the game allows you to take them one right after the other.

I don't know how much control you have over this aspect of it, but would it be possible to re-check a contract's requirements whenever someone clicks it to select it, instead of just on a timer? This wouldn't be a big deal if the game allowed you to go in the hole, but as it is currently it's easy to even accidentally cheat the system.

Link to comment
Share on other sites

3 hours ago, 5thHorseman said:

More stuff! Yay, right?

I have a Requirement set up for all my contracts, that you must have the amount of money that the contract will cost you to take. Currently that's 10 times the "unlock cost" (thanks for adding that) and it works just fine, even with the negative number. I have these two clauses in each contract:


	advanceFunds = [email protected]() * 10

	REQUIREMENT
	{
		name = Funds
		type = Funds
		minFunds = @/part.UnlockCost() * 10
	}
	

Now this works fine. If you have the money, the contract is available to take and you can take it. It deducts your funds and accepts the contract. If you don't have the money, the contract is in the "All" tab greyed out because you don't meet the requirement.

The problem occurs when you are low on funds and accept 2 contracts in quick succession. If you have, say, 20,000 funds and there are two contracts that each cost 15,000 funds, the game allows you to take them one right after the other.

I don't know how much control you have over this aspect of it, but would it be possible to re-check a contract's requirements whenever someone clicks it to select it, instead of just on a timer? This wouldn't be a big deal if the game allowed you to go in the hole, but as it is currently it's easy to even accidentally cheat the system.

Actually, I'd be more inclined to fix it so that it won't allow a contract to be accepted if the advance funds would cause the player to go negative - so please raise a GitHub issue to that effect.

The reason I don't want it to click on click is that it then causes player confusion, when clicking actively changes the availability of a contract.  The other option is to re-check all contracts when another one is accepted, but I think that'd be unacceptably laggy.

Also, look for the ALLOW_NEGATIVE_FUNDS in settings.cfg - got that added in 1.1.x (can't remember exactly which release).

Link to comment
Share on other sites

Okay, so what's going on WRT to the garbage creation / stutter thing?
I've been trying to alleviate the stutter in my (modded) install, and removing mods one at a time brings me to the minimal set that causes it:
Contract Configurator + any contract pack + active contract from said pack.
I have been down this road before, with the same conclusion.

I don't want to sound ungrateful, and I do love Contract Configurator... but the effect it has on the garbage collector is a bit ridiculous and it's really impacting playability here.
I have 42 other mods installed ATM, and nothing else comes close to CC for inducing stutter.

Heap allocations according to Memgraph:
Sitting in the space centre (or mission control) view, 1 stock contract active: ~3MB/s.
Same situation, 1 Tourism plus contract active: ~15MB/s.
4 stock contracts active: ~3MB/s.
4 Tourism plus contracts active: ~45MB/s.
etc...

Same (or worse) goes for any other contract pack, AFAICT.

I can toggle my stutter problems at will, just by accepting and cancelling CC contracts. Each active CC contract adds ~12MB/s to heap allocations, and it appears to be  cumulative.
This comes with a corresponding effect on observed GC stutter. What I see in the space centre is much the same in the flight scene (though somewhat more laborious to test).

I can grab logs if they would help, but I'm not seeing anything suspicious there, and nothing is throwing exceptions.

Pretty much all the "stutter" threads have a mention of Contract Configurator as a primary culprit somewhere, is this something that is being worked on?

Edited by steve_v
Link to comment
Share on other sites

@steve_v  Nightingale said he'd have something in the works for the next update.  Glad to see others are testing this too.  I really hope it works better, I have the same issue you do.

Also, I have an issue now where my game is no longer generating anything besides vanilla Satellite contracts - no synchronous, no molniya, no stationary.  I can't tell why they might have broken, are you seeing anything like this?

 

Link to comment
Share on other sites

36 minutes ago, Maxsimal said:

are you seeing anything like this?

Nope, though I have removed CC entirely now. Guess I'll just play stock contracts until the garbage issues are sorted :( This is somewhat boring, but it's better than the stutter.

Link to comment
Share on other sites

1 hour ago, nightingale said:

Can you provide info for the flight scene though?

I didn't test this as comprehensively in the flight scene (kinda keen to actually play one I 'fixed' my stutter issues by removing CC) but it was pretty close to the results I had in the space centre... off the top of my head, going from 5-6MB/s to 15-25 MB/s if I had an active contract. I'll try to get some numbers tomorrow though.
What I can say right now is no CC == no appreciable GC stutter in flight scene. Where I started (~6 active CC contracts) it was unbearable. So numbers aside, there's still too much garbage in flight.

 

1 hour ago, nightingale said:

I've moved all contract generation

I don't know anything about the internals of CC, but when you say 'generation' I take it you mean the generation of new contracts? If so, and contract generation is the main source of garbage, why does it seem to scale so neatly with number of active contracts?

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...