Ruby Scripting
#28
Your Verbose Code Might Be Wasting Your Computing Time!

The present post will consist of an actual request that asked any scripter to alter the default actors' behavior in VX ACE in battle.

The Default Behavior & Its Actual Code

Actors' actions are based on AGI just like it happens to enemies.

Code:
module BattleManager
  def self.make_action_orders
    @action_battlers = []
    @action_battlers += $game_party.members unless @surprise
    @action_battlers += $game_troop.members unless @preemptive
    @action_battlers.each {|battler| battler.make_speed }
    @action_battlers.sort! {|a,b| b.speed - a.speed }
  end
end

What the maker does is to create an array of battlers before adding the party members and the enemy troopers depending on the battle start type: normal, surprise or preemptive. Then it sorts them all based on their actions's lowest speed. (It uses the battler's AGI and perhaps the ATK speed as well.)

The Desired Behavior

Actors' actions order should be based on their party index instead.
Enemy actions would remain unaltered.

The Solution Originally Posted by Another Scripter

Code:
module BattleManager
  def self.make_action_orders
    @action_battlers = []
    party_battlers = []
    troop_battlers = []
    party_battlers += $game_party.members unless @surprise
    troop_battlers += $game_troop.members unless @preemptive
    troop_battlers.each {|battler| battler.make_speed }
    troop_battlers.sort! {|a,b| b.speed - a.speed }
    @action_battlers += party_battlers
    @action_battlers += troop_battlers
  end
end

By just looking at the code, any experienced scripter would soon notice that the OP has replaced 3 lines of code with 7 custom ones. These lines are very slight variations of the original code.

First, let's mention the merits this scriptlet has. It's quite readable, methodical, and it works as intended.

The downside is that it's not as concise as it should be. It doesn't show any signs of it being a slightly creative solution. So it's just a simple one.

NOTE: For some reason the actors ALWAYS go first, even if no one had asked for this feature at all.

Can that piece of code be shortened somehow?

The answer is yes, it can! Grinning And it's extremely easy to implement for sure!

The Compact Code I'm Proposing

Code:
module BattleManager
  def self.make_action_orders
    @action_battlers = @surprise ? [] : $game_party.members
    troop_battlers = @preemptive ? [] : $game_troop.members
    troop_battlers.each {|battler| battler.make_speed }
    troop_battlers.sort! {|a,b| b.speed - a.speed }
    @action_battlers += troop_battlers
  end
end

The method's first line already assigns the party members to the battlers' actions array. It's followed by a similar array focused on the enemies only. Both check if there's a flag that might exclude them from being processed while sorting the actions. Then let's say it has found some enemies and the next 2 lines proceed to find the actions and sort them by their corresponding speed as usual. Finally, it just add the sorted array of troopers to the original list of battlers.

OK, this scriptlet is no longer as newcomer-friendly as the previous one for sure, yet, it handles the creation of arrays or assignment of existing ones to the @action_battlers array without packing too much stuff inside that method. And it doesn't create arrays that are quite similar nor does it imitate other arrays' behaviors or method calls unnecessarily.

NOTE: Actors STILL go first. Enemies will also have to wait for the party to finish attacking them before they launch their counterattack.

Stop Assuming You Know All About How the Requestor Wants to Alter a Given Feature

What would happen if one day the original requestor, an average forumer, finally realizes that your code grants the actors an inexcusable advantage over their enemies?

If that ever happens, you'd be forced to refactor your code to take that situation into account from that point onwards.

How could we solve that issue?

Well, we could alter the original code to include a way to easily check who should go first.

In this particular case we'll assume the change will be PERMANENT and should be defined before the game loads.

Now let's take a look at this code:

Code:
module BattleManager
  PARTY_GOES_FIRST = true
  def self.find_party_battlers
    @surprise ? [] : $game_party.members
  end

  def self.find_enemy_battlers
    @preemptive ? [] : $game_troop.members
  end

  def self.make_action_orders
    if PARTY_GOES_FIRST
      battlers = find_party_battlers
      other_battlers = find_enemy_battlers
    else
      battlers = find_enemy_battlers
      other_battlers = find_party_battlers
    end
    other_battlers.each {|battler| battler.make_speed }
    other_battlers.sort! {|a,b| b.speed - a.speed }
    @action_battlers = battlers + other_battlers
  end
end

There are 4 changes applied to the scriptlet that allows the game developer to predefine the team that will attack first.
  • We use a CONSTANT that will hold a boolean value.
  • We encapsulate the ternary conditions so we can easily call them from the make_action_orders method in any order.
  • We define a conditional if statement using our custom constant as the actual test.
    Adding == true to the condition is optional in Ruby for any existing object is true except for false and nil objects. Even 0 is true...
  • @action_battlers concatenates the preferred team and the remaining one in that particular order.

NOTE: Here I let you treat the other battlers as the ones that will be sorted by their actions' speed. If that's not what you want to implement, rename the lines that alter other_battlers as battlers. Now it will only sort the first group by their party or enemy indexes.

Thoughts on Refactoring [Pieces of] Code

Normally, we wouldn't touch a functional scriptlet and modify it just to make it compact, but the original code gave me the perfect excuse to do so here. The thing is that a scripter should get to a development stage where he or she should be able to realize on his or her own that they gotta be more ways to deal with an issue than just sticking to the engine or its scripts' default features or coding style.

The usual reasons to revisit a script might be stuff like adding or removing features, fixing bugs, renaming methods because their current names are misleading or have been repurposed, adding exceptions or conditional statements to prevent happy-go-lucky aficionados or some happy-trigger apprentices from triggering events or script calls at a bad moment, etc.

One special circumstance when you might want to change your code would be to get rid of nested loops like defining a for loop inside another one. The only exception to this rule might be nesting 3 for or each loops to iterate over all tiles in the X, Y and Z layers in the RM series. Happy with a sweat You can't really find a way to avoid that process, you're simply forced to do that to get the tileset working as intended. Laughing
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply


Messages In This Thread
Ruby Scripting - by kyonides - 08-29-2019, 04:51 AM
RE: Ruby Scripting - by kyonides - 08-30-2019, 05:47 AM
RE: Ruby Scripting - by kyonides - 09-03-2019, 07:24 AM
RE: Ruby Scripting - by kyonides - 09-06-2019, 05:46 AM
RE: Ruby Scripting - by kyonides - 09-09-2019, 05:00 AM
RE: Ruby Scripting - by kyonides - 06-05-2021, 08:20 PM
RE: Ruby Scripting - by kyonides - 11-28-2021, 03:31 AM
RE: Ruby Scripting - by kyonides - 05-02-2022, 02:43 AM
RE: Ruby Scripting - by kyonides - 01-27-2023, 08:01 AM
RE: Ruby Scripting - by kyonides - 02-03-2023, 02:42 AM
RE: Ruby Scripting - by DerVVulfman - 02-03-2023, 03:52 AM
RE: Ruby Scripting - by kyonides - 02-03-2023, 04:33 AM
RE: Ruby Scripting - by kyonides - 04-19-2023, 12:47 AM
RE: Ruby Scripting - by kyonides - 04-19-2023, 01:12 AM
RE: Ruby Scripting - by kyonides - 06-08-2023, 09:24 PM
RE: Ruby Scripting - by kyonides - 06-08-2023, 09:46 PM
RE: Ruby Scripting - by kyonides - 06-12-2023, 06:29 AM
RE: Ruby Scripting - by kyonides - 07-14-2023, 10:37 PM
RE: Ruby Scripting - by kyonides - 07-15-2023, 07:32 AM
RE: Ruby Scripting - by kyonides - 07-16-2023, 06:05 AM
RE: Ruby Scripting - by kyonides - 07-17-2023, 04:01 AM
RE: Ruby Scripting - by kyonides - 08-22-2023, 08:59 AM
RE: Ruby Scripting - by kyonides - 08-28-2023, 03:34 AM
RE: Ruby Scripting - by kyonides - 11-18-2023, 09:02 AM
RE: Ruby Scripting - by kyonides - 04-16-2024, 06:57 AM
RE: Ruby Scripting - by kyonides - 12-21-2024, 09:02 PM
RE: Ruby Scripting - by kyonides - 03-24-2025, 07:50 PM
RE: Ruby Scripting - by kyonides - 03-30-2025, 02:32 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
   Ruby - Behind the Scenes DerVVulfman 0 1,645 07-15-2023, 05:52 PM
Last Post: DerVVulfman
Information  Assorted Ruby chm documents. hanetzer 10 37,583 08-17-2020, 04:19 AM
Last Post: kyonides
Brick  Learn Ruby! greenraven 2 8,399 05-16-2014, 12:25 PM
Last Post: greenraven
   Creating Your Own Scripting System DerVVulfman 3 8,225 10-12-2009, 03:37 PM
Last Post: Alpha-Mad
   How to make interesting NPC's without scripting Third333Strike 0 4,227 12-06-2008, 04:59 PM
Last Post: Third333Strike



Users browsing this thread: 3 Guest(s)