Combat or events are triggered probabilistically during world traversal rather than by scripted enemy placement.
Combat is rolled per step while walking, not from placed enemies: a low roll flashes into a battle with a monster, then back to the field.
Encounters are rolled during traversal, not placed in the world. Each step has a probability of triggering; an encounter table decides what shows up.
Roll on movement. A simple threshold on randf() per step gives the classic “wander and suddenly: battle” cadence.
func on_step():
if rng.randf() < encounter_rate:
trigger(pick_encounter())A weighted encounter table as data — which enemy groups, how likely, in which region. The roll picks from this table.
class_name EncounterTable extends Resource
@export var entries: Array # [{ group, weight }]Triggering swaps to a battle scene (or pushes one on top), then returns to the overworld at the same spot afterward.
func trigger(group):
get_tree().change_scene_to_packed(BATTLE)
Battle.setup(group)In short: on_step_taken(): if randf() < encounter_rate: trigger_encounter(); encounter table determines which enemies appear
15 catalogued game(s) use this mechanic, spanning 1981–1995.
▶ Explore Random Encounter interactively — see every game + the Godot system