DarkPlasmaBall

Veteran
Veteran
Joined
Apr 29, 2020
Messages
175
Reaction score
6
First Language
English
Primarily Uses
RMMV
Hi everyone, quick question:

When setting up the encounter rate in map properties / general settings based on Region ID, I know that the Encounter Step # is an approximate average for how many steps inside a given Region ID will be walked before/at the moment of encountering a monster... but is the "counter" for this number completely reset to 0 if the player temporarily walks out of that region (into either a no-monster region or a different region that has different monsters) after taking a few steps inside the region, or is the counter paused and then resumed when the player walks back into the region?

As an example: Let's suppose that the Encounter Step is something high, like 100, and that there are two regions with different monsters: Region 1 has Monster 1, and Region 2 has Monster 2. If I walk 20 steps in Region 1, it's unlikely that I'll encounter Monster 1 just yet (let's assume I don't encounter Monster 1). If I then leave Region 1 and walk onto either Region 2 or a blank (no-encounter) area of the map, what happens to the progress of the 20 steps inside Region 1 that I've already taken? If I walk back into Region 1 a little while later, is the counter for Region 1 restarted at 0 steps, or is it resumed at 20 steps? Because if it's completely reset, then I'd imagine that alternating between stepping inside and then stepping outside a region would pretty much ensure that you never encounter a monster inside that region, as opposed to gradually progressing towards that Encounter Step average, right? Thanks!
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,707
Reaction score
2,808
First Language
English
Primarily Uses
RMMZ
So there are a number of moving parts involved in encounters, obviously ,which are:

JavaScript:
Game_Map.prototype.encounterList = function() {
    return $dataMap.encounterList;
};

Game_Map.prototype.encounterStep = function() {
    return $dataMap.encounterStep;
};

Game_Player.prototype.makeEncounterCount = function() {
    var n = $gameMap.encounterStep();
    this._encounterCount = Math.randomInt(n) + Math.randomInt(n) + 1;
};

Game_Player.prototype.makeEncounterTroopId = function() {
    var encounterList = [];
    var weightSum = 0;
    $gameMap.encounterList().forEach(function(encounter) {
        if (this.meetsEncounterConditions(encounter)) {
            encounterList.push(encounter);
            weightSum += encounter.weight;
        }
    }, this);
    if (weightSum > 0) {
        var value = Math.randomInt(weightSum);
        for (var i = 0; i < encounterList.length; i++) {
            value -= encounterList[i].weight;
            if (value < 0) {
                return encounterList[i].troopId;
            }
        }
    }
    return 0;
};

Game_Player.prototype.meetsEncounterConditions = function(encounter) {
    return (encounter.regionSet.length === 0 ||
            encounter.regionSet.contains(this.regionId()));
};

Game_Player.prototype.executeEncounter = function() {
    if (!$gameMap.isEventRunning() && this._encounterCount <= 0) {
        this.makeEncounterCount();
        var troopId = this.makeEncounterTroopId();
        if ($dataTroops[troopId]) {
            BattleManager.setup(troopId, true, false);
            BattleManager.onEncounter();
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
};

Game_Player.prototype.updateNonmoving = function(wasMoving) {
    if (!$gameMap.isEventRunning()) {
        if (wasMoving) {
            $gameParty.onPlayerWalk();
            this.checkEventTriggerHere([1,2]);
            if ($gameMap.setupStartingEvent()) {
                return;
            }
        }
        if (this.triggerAction()) {
            return;
        }
        if (wasMoving) {
            this.updateEncounterCount();
        } else {
            $gameTemp.clearDestination();
        }
    }
};

Game_Player.prototype.updateEncounterCount = function() {
    if (this.canEncounter()) {
        this._encounterCount -= this.encounterProgressValue();
    }
};

Game_Player.prototype.canEncounter = function() {
    return (!$gameParty.hasEncounterNone() && $gameSystem.isEncounterEnabled() &&
            !this.isInAirship() && !this.isMoveRouteForcing() && !this.isDebugThrough());
};

Game_Player.prototype.encounterProgressValue = function() {
    var value = $gameMap.isBush(this.x, this.y) ? 2 : 1;
    if ($gameParty.hasEncounterHalf()) {
        value *= 0.5;
    }
    if (this.isInShip()) {
        value *= 0.5;
    }
    return value;
};

Once we break this down, we'll see that makeEncounterCount is called when getting off a vehicle, enabling or disabling encounters via event command, processing a battle, or moving the player to a new location. It is *not* called in relation to changing regions.

What this function does is takes the value you entered as the "encounter steps" (n) on the map edit dialog and then sets _encounterCount to a random number from 0 to n + a random number from 0 to n + 1. This is exclusive, so if your encounter steps is 30 each random number will be 0-29.

That means that with an encounter steps setting of 30, your _encounterCount could be anything from 1 (if both n are 0) to 59 (if both are 29)

When updating the player, we update encounter count, but only under certain conditions, defined by canEncounter. This function checks whether the party has a "no encounters" trait on any of its members, that encounters are actually enabled, the player isn't on an airship, the move route isn't forced and the player isn't holding ctrl for the debug through mode.

Assuming canEncounter is true, we decrement _encounterCount by 2 if the player is on a "bush" tile, and 1 otherwise. This is reduced to 1 or 0.5 if the party has "encounter half" or the player is on a ship.

As you can see, the region only comes into play when actually executing an encounter, and the region setting is used to either include or exclude that troop from the ones the player will encounter.

What this means is that the step count is what's important, not the region. There is no reset involved; the player will encounter a troop when the count is 0, and at that point the player can encounter the region troop if they're on that region, and if they're not that troop won't be considered.

This does mean that you could arguably "cheese" the system by staying in the region until you're fairly sure an encounter is about to happen, then going into a no encounter area until you think the count has gone to 0, then going back into the region.
 

DarkPlasmaBall

Veteran
Veteran
Joined
Apr 29, 2020
Messages
175
Reaction score
6
First Language
English
Primarily Uses
RMMV
Oh wow, that's a lot more complicated than I thought it would be, but that makes sense, thank you!
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,707
Reaction score
2,808
First Language
English
Primarily Uses
RMMZ
Oh wow, that's a lot more complicated than I thought it would be, but that makes sense, thank you!
I honestly don't like how encounters in MV/MZ work by default, so I'm going to modify them in my game to have a minimum number of steps as well.
 

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
1,282
Reaction score
682
First Language
English
Primarily Uses
RMMV
I honestly don't like how encounters in MV/MZ work by default, so I'm going to modify them in my game to have a minimum number of steps as well.
Yeah, I like putting in a minimum of half of the encounter steps.

I never noticed it doubles your steps in bushes...random Pokémon mechanic!
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,707
Reaction score
2,808
First Language
English
Primarily Uses
RMMZ
Yeah, I like putting in a minimum of half of the encounter steps.

I never noticed it doubles your steps in bushes...random Pokémon mechanic!
Yeah, that and the encounter rate in ships being halved were two little surprises when I first started delving into the code of the newer RMs.
 

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
1,282
Reaction score
682
First Language
English
Primarily Uses
RMMV
Just in case anyone comes across this and wants to implement the minimum steps, copy this and save it as a .js that you include as a plugin:
Code:
Game_Player.prototype.makeEncounterCount = function() {
    var n = $gameMap.encounterStep();
    this._encounterCount = Math.max(n/2, Math.randomInt(n) + Math.randomInt(n) + 1);
};
The first number after "Math.max" is the minimum value, so in this case I said it has to be at least half the specified number of steps.
 

Latest Threads

Latest Posts

Latest Profile Posts

I got the pause Icon to use 6 frames instead of 4, PLUS it goes: top 1-2-3, bottom 1-2-3. And everything just by playing around with the code & i think i've figured the important parts out now <3
eUuH09A.gif

ps. the animation isn't as "wonky" in RL, stupid recording -.-
Friendly reminder: Make a back up of your project! ;3 I just did one and recognized I would have lost a week worth of work.
Why is there undo but not a redo like every other software in existence? :blink:
Chili: Evolved to taste spicy so no animal would eat them.

Humans: "Jokes on you ..."

Forum statistics

Threads
113,717
Messages
1,076,892
Members
147,746
Latest member
Sattakingcompany
Top