FAForever Forums
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Login
    The current pre-release of the client ("pioneer" in the version) is only compatible to itself. So you can only play with other testers. Please be aware!

    Mod for dynamic growth in prices for economic buildings

    Scheduled Pinned Locked Moved Modding & Tools
    9 Posts 4 Posters 131 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • cychwa_klaymbergC Offline
      cychwa_klaymberg
      last edited by

      Our game has one distinctive feature that makes it stand out from many other games. I'm talking about economic growth, which, under certain conditions, scales almost infinitely, is limited only by the overall unit limits, and can lead to some crazy resource income values. For some, this is good; for others, it's bad. I can confidently say that more advanced players, thanks to their experience and skill, grow their economies much faster and better than average players, snowballing their economic superiority. I don't want to talk about countermeasures, raids, long-range artillery, and everything else that, in the standard game, is essentially game-breaking and won't allow the economy to grow indefinitely. I understand that. However, I still set myself the goal of somehow balancing or complicating economic growth.

      I have two ideas for how to change this.

      • set a hard limit on buildings of a specific type, for example, T3 Mass Fabricators based on their ID.
      • somehow dynamically increase the construction cost of a building of a specific type, for example, T3 Mass Fabricators based on their ID.

      I tried to use a neural network to force it to write me scripts for both options, but unfortunately, it didn’t lead to any results.
      Basically, what the neural network sent simply resulted in a black screen or a complete breakdown of the commander.
      The latest code she sent me looks like this. It's supposed to change resource consumption, even without changing the cost in the Blueprint or the cost display on the icon, but it still doesn't work.

      local EcoGroupMapping = {
      ['ueb1201'] = 'T2_Energy', ['urb1201'] = 'T2_Energy', ['uab1201'] = 'T2_Energy', ['uxb1201'] = 'T2_Energy',
      ['ueb1303'] = 'T3_Mass', ['urb1303'] = 'T3_Mass', ['uab1303'] = 'T3_Mass', ['uxb1303'] = 'T3_Mass',
      ['ueb1104'] = 'T2_Mass', ['urb1104'] = 'T2_Mass', ['uab1104'] = 'T2_Mass', ['uxb1104'] = 'T2_Mass',
      }

      -- 1. ВАШ ХУК НА НАЧАЛО СТРОИТЕЛЬСТВА (Через ветеранство фундамента)
      local oldVeterancyOnCreate = VeterancyComponent.OnCreate
      function VeterancyComponent.OnCreate(self)
      if oldVeterancyOnCreate then oldVeterancyOnCreate(self) end

      local id = self:GetUnitId()
      local groupName = EcoGroupMapping[id]
      
      if groupName and self.GetFractionComplete and self:GetFractionComplete() < 1 then
          local brain = self:GetAIBrain()
          if brain then
              if not brain.CustomEcoGroupCount then
                  brain.CustomEcoGroupCount = { T2_Energy = 0, T3_Mass = 0, T2_Mass = 0 }
              end
      
              local currentCount = brain.CustomEcoGroupCount[groupName] or 0
              local priceMultiplier = math.pow(2, currentCount)
      
              if priceMultiplier > 1 then
                  local bp = self:GetBlueprint()
                  if bp and bp.Economy then
                      local extraMass = bp.Economy.BuildCostMass * (priceMultiplier - 1)
                      local extraEnergy = bp.Economy.BuildCostEnergy * (priceMultiplier - 1)
                      local buildTimeSeconds = bp.Economy.BuildTime / 10 
      
                      FloatingEntityText(self.EntityId, string.format("Налог на группу %s: х%d!", groupName, priceMultiplier))
      
                      self:ForkThread(function(buildingSelf)
                          local taxMassSec = extraMass / buildTimeSeconds
                          local taxEnergySec = extraEnergy / buildTimeSeconds
      
                          while not buildingSelf:IsDead() and buildingSelf:GetFractionComplete() < 1 do
                              -- Проверяем наличие ресурсов, чтобы не уходить в ошибку при нулевом балансе
                              if brain.GetEconomyStored then
                                  brain:DumpMass(taxMassSec)
                                  brain:DumpEnergy(taxEnergySec)
                              end
                              WaitSeconds(1.0)
                          end
                      end)
                  end
              end
          end
      end
      

      end

      -- 2. БЕЗОПАСНАЯ ИНЪЕКЦИЯ ХУКОВ В КЛАСС UNIT (Чтобы не ломать Командира и другие моды)
      local oldUnitOnStopBeingBuilt = Unit.OnStopBeingBuilt
      Unit.OnStopBeingBuilt = function(self, builder, layer)
      if oldUnitOnStopBeingBuilt then oldUnitOnStopBeingBuilt(self, builder, layer) end

      local id = self:GetUnitId()
      local groupName = EcoGroupMapping[id]
      
      if groupName then
          local brain = self:GetAIBrain()
          if brain then
              if not brain.CustomEcoGroupCount then
                  brain.CustomEcoGroupCount = { T2_Energy = 0, T3_Mass = 0, T2_Mass = 0 }
              end
      
              local newCount = (brain.CustomEcoGroupCount[groupName] or 0) + 1
              brain.CustomEcoGroupCount[groupName] = newCount
      
              FloatingEntityText(self.EntityId, string.format("Группа %s: %d шт. Следующее х%d дороже!", groupName, newCount, math.pow(2, newCount)))
          end
      end
      

      end

      local oldUnitOnKilled = Unit.OnKilled
      Unit.OnKilled = function(self, instigator, type, overkillRatio)
      local id = self:GetUnitId()
      local groupName = EcoGroupMapping[id]

      if groupName then
          local brain = self:GetAIBrain()
          if brain and brain.CustomEcoGroupCount then
              local currentCount = brain.CustomEcoGroupCount[groupName] or 0
              if currentCount > 0 then
                  brain.CustomEcoGroupCount[groupName] = currentCount - 1
              end
          end
      end
      
      if oldUnitOnKilled then oldUnitOnKilled(self, instigator, type, overkillRatio) end
      

      end

      Please tell me how I can do it?

      1 Reply Last reply Reply Quote 0
      • maudlin27M Offline
        maudlin27
        last edited by

        You could alternatively reduce the resources generated by such buildings by using a sim mod and applying buffs to the units either when created or on an ongoing basis
        Eg resource generation of the nth building is max(1, 100 - n) / 100%

        The PCx mod is an example of using buffs to modify resource generation values

        M27AI and M28AI developer:
        https://forum.faforever.com/topic/2373/ai-development-guide-and-m27ai-v81-devlog
        https://forum.faforever.com/topic/5331/m28ai-devlog-v294
        M28 trophy holders: Radde, Yew (Radde trophy, v285) and Zwaffel (Sladow trophy, v284)

        cychwa_klaymbergC 1 Reply Last reply Reply Quote 0
        • cychwa_klaymbergC Offline
          cychwa_klaymberg @maudlin27
          last edited by

          @maudlin27 Can you write in more detail how this works and in which folders it is located?

          1 Reply Last reply Reply Quote 0
          • maudlin27M Offline
            maudlin27
            last edited by

            It'll be in the mod folder, e.g.:
            C:\ProgramData\FAForever\user\My Games\Gas Powered Games\Supreme Commander Forged Alliance\mods\PlayerModifierPCx

            It applies a resource buff to every resource generating unit when that unit is created, with the buff being a factor determined by the game options

            If you need help on modding more generally I'd suggest asking in the modding discord channel part of the FAF discord:
            https://discord.com/channels/197033481883222026/832710161847287819

            M27AI and M28AI developer:
            https://forum.faforever.com/topic/2373/ai-development-guide-and-m27ai-v81-devlog
            https://forum.faforever.com/topic/5331/m28ai-devlog-v294
            M28 trophy holders: Radde, Yew (Radde trophy, v285) and Zwaffel (Sladow trophy, v284)

            1 Reply Last reply Reply Quote 0
            • D Offline
              Defiant
              last edited by

              A very different option is to make a Handicap sim mod, which nerfs players to earn lower eco income throughout the game. This could be a nice way to challenge more experienced players.

              maudlin27M cychwa_klaymbergC 2 Replies Last reply Reply Quote 0
              • maudlin27M Offline
                maudlin27 @Defiant
                last edited by

                @Defiant https://forum.faforever.com/topic/10117/player-modifier-pcx-balance-games-between-different-rated-players

                M27AI and M28AI developer:
                https://forum.faforever.com/topic/2373/ai-development-guide-and-m27ai-v81-devlog
                https://forum.faforever.com/topic/5331/m28ai-devlog-v294
                M28 trophy holders: Radde, Yew (Radde trophy, v285) and Zwaffel (Sladow trophy, v284)

                1 Reply Last reply Reply Quote 1
                • cychwa_klaymbergC Offline
                  cychwa_klaymberg @Defiant
                  last edited by

                  @Defiant said:

                  A very different option is to make a Handicap sim mod, which nerfs players to earn lower eco income throughout the game. This could be a nice way to challenge more experienced players.

                  Yes, I agree. Such a mod already exists, but it won't solve my problem; it will only prolong it and give some players an unfair advantage early on. Plus, it's not always clear what level the player is facing. It could be someone with a 100 rating and 10 games, who's been playing mods their whole life and is very good. Or it could be someone with a 1500 rating and 1000 games, but knows nothing except Dual Gap.

                  1 Reply Last reply Reply Quote 0
                  • N Offline
                    Nomander Balance Team
                    last edited by

                    You could hook OnProductionPaused and OnProductionActive of the MassFabricationUnit class for fabs, MassCollectionUnit for mex, or Unit class for both mex and fabs (might mess with RAS upgrades though).
                    There you can access in self.Brain a shared counter of units and a list of units. You would adjust the counter and list, calculate the correct mass production modifier using the counter, re-create the Buff Blueprint using the new value (make sure it uses "REPLACE" for stacking), and then go through the list of units applying the new buff.

                    If you want an example of a game with non-linearly non-exponentially scaling economy there's zero-k: https://zero-k.info/mediawiki/Cold_Takes/5_-_Making_Metal
                    Basically you have to use a square root on mass production to counteract the exponential scaling of reinvesting eco.

                    1 Reply Last reply Reply Quote 0
                    • cychwa_klaymbergC Offline
                      cychwa_klaymberg
                      last edited by

                      😮
                      it sounds complicated

                      1 Reply Last reply Reply Quote 0

                      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                      With your input, this post could be even better 💗

                      Register Login
                      • First post
                        Last post