Research cost is capped

Fixed Research & Tech
deagato [discord] · 1 year ago

Research cost is capped at Fix32.MaxValue (2,097,151)

W 06:32:16,749 S------ ~Mai: New science cost 2633387 of 'ResearchRocketsCapacityInc' too large, reducing it to 2096151.
  at Mafi.Core.Research.ResearchNode.updateCurrentCost ()
  at Mafi.Core.Research.ResearchNode.Mafi.Core.Research.IResearchNodeFriend.SetBaseCost (System.Int32 baseScienceCost)

image.jpg

Rockets capacity 15, admiral difficulty (+50% cost)

deagato [discord] · 1 year ago

TEMPFIX - RESEARCH COST CAPPED 15.7627->12.54492 (id:ResearchRocketsCapacityInc, capped:2096151, real:2633387, ratio:0.7958984)

Ran out of useful research to do, so i "fixed" it by scaling the points generated by the labs

eryk500 [discord] · 1 year ago

I'm guessing it's because this value get's stored in an Fix32 at some point, yes? Probably upgrading to a Fix64 might be the "dev" solution to this 🤔.

slopth [discord] · 1 year ago

unrelated side question - why wouldn't that be fix64 to begin with?

or more broadly

why not make everything 64bit from the ground up

when math is involved, it can impact performance, so you want to only want to up the address sizes when actually needed?

deagato [discord] · 1 year ago

Mostly perf related, you can fit more(double) in the cache if you use 32 instead of 64bits

In this case is not perf related, just a type carried around

deagato [discord] · 1 year ago
  • it helps to keep the saves small

And smaller save, smaller saving times

Captain Marek Captain Marek · 1 year ago

Is the research speed issue achievable without cheats? Can anyone share a save with this issue?

deagato [discord] · 1 year ago

It's easily achievable without cheats, i'm at rocket cargo size 19 and the problem was first found at rocket cargo size 15.
The current research costs 13M (still capped at 2.1M)

And the "speed" is not the issue.

I already "patched" it with a mod, feel free to ask if you need more infos

Captain Marek Captain Marek · 1 year ago

Could you DM me the patch source code if you have it?

deagato [discord] · 1 year ago

This is the workaround since i can't change types around the codebase.
It's an Harmony patch that applies a multiplier to the research points before they are applied by the game.

static void Prefix(ResearchManager __instance, ref Fix32 stepsDone)
{
    if (!__instance.CurrentResearch.HasValue)
        return;

    var research = __instance.CurrentResearch.Value;
    if (!TryGetRatio(research, out var ratio, out var realCost))
        return;

    stepsDone = stepsDone * ratio;
}

static bool TryGetRatio(ResearchNode research, out Fix32 ratio, out int realCost)
{
    var baseCost = __m_baseScienceCost.GetValue(research);
    realCost = research.Proto.CostFn(baseCost, research.TimesResearched);
    if (realCost < Fix32.MaxIntValue)
    {
        ratio = 0;
        return false;
    }

    ratio = ((Fix64)research.ScienceCost / realCost).ToFix32();
    return true;
}
Captain Marek Captain Marek · 1 year ago

Thanks, I will see what can be done

deagato [discord] · 1 year ago

Current example: RESEARCH COST CAPPED 21.34375->3.459961 (id:ResearchRocketsCapacityInc, level:19, capped cost:2096151, real cost:12896123, ratio:0.1621094
21.34 is 256/12 (recipe is 4lab equip/5 days or 48/60days)
The value is multiplied by 0.162 to work inside the Fix32 range

image.jpg

Captain Marek Captain Marek · 1 year ago

Ok, I've changed StepsDone to be an int instead of Fix32 so that research costs are all ints. That should fix this issue.

deagato [discord] · 1 year ago

What about the fractional part of stepsDone for ReportResearchStepsDone(Fix32 stepsDone)? will it be truncated?

Captain Marek Captain Marek · 1 year ago

Fractional steps are preserved but only integer part is added to StepsDone

stepsDone += m_unaccountedStepsFraction;
m_unaccountedStepsFraction = stepsDone.FractionalPart;
int stepsToAdd = stepsDone.IntegerPart.Min(node.RemainingSteps);
deagato [discord] · 1 year ago

Yeah, i saw the same logic used for handling fractions for pop needs.
I'll give you the ok once i can test it in experimental but it seems pretty straightforward

Thanks

Captain Marek Captain Marek · 1 year ago

Yeah, this pattern is used in many places for tracking fractions. Now that we do track fractions, I guess we could even track excess after research is done:

stepsDone += m_unaccountedStepsFraction;
int stepsToAdd = stepsDone.IntegerPart;
m_unaccountedStepsFraction = stepsDone.FractionalPart;
if (stepsToAdd > node.RemainingSteps) {
    m_unaccountedStepsFraction += stepsToAdd - node.RemainingSteps;
    stepsToAdd = node.RemainingSteps;
}

This probably won't change anything significant, maybe a tiny bit faster research in the early game.

deagato [discord] · 1 year ago

The other day i was thinking if having a global research counter could be used to accumulate research points.
And have it auto spent on queued nodes or manually once you have enough points to unlock a node in one go

Just a thought, the current model works.

Captain Marek Captain Marek · 1 year ago

That model kind of breaks the immersion that you are researching something specific, but I can see the appeal of not needing to think what to do and just unlock things as needed.

Closed as ✅ Fixed

10 Showing 1–20 of 27