English
Spawn Query System
2025July

Spawn Query System is a graph-based tool that allows designers to define sophisticated randomization for spawning various things, such as loot, enemies, quest rewards, etc.

GitHub Repo | Documentation

Icon

Features

Screenshot

Design Intention

This tool allows designers to define and tweak how items are randomized without writing code or bringing the programmer team into the loop, which faciliates rapid iteration for games with heavy resource management. With great flexibility, it is especially helpful to teams which employ a playtest-centric approach to fine-tune gameplay.

To demonstrate the flexibility of this tool, let’s cover some common use cases first, and then imagine these techniques can be combined together in complex scenarios. Assume we are going to spawn loot for the player to pick up in all the cases below.

The Simplest Case

In the simplistic scenario, you want to spawn a loot from a large pool, and hope it to be true randomization, though it is not a usual case.

Create a class deriving from FSpawnEntryTableRowBase to suit your own needs. Create a DataTable asset with the class as its row. You will be able to configure each entry with a weight and you can leave the entire Influencers column blank. This is your loot table.

Create a Spawn Query Asset. Create a Pool Sampler node and connect it to the Root node. Assign the loot table to the pool sampler. Leave other options as-is.

Screenshot

Use SpawnQuery::Query() function in your Blueprints and GetSpawnEntryRow node to generate a pick.

Tetris Randomization (7-Bag)

In the former case, if you change the Random Policy into “Shuffled Sequence” and set each entry’s weight to exact 1, you will get Tetris famous 7-Bag randomization: every loot appears once in a random order before repeating.

Alternatively, if you change all the weight to 2, you will have every loot appear twice in a random order before repeating. The weight virtually represents how many times one entry appears in a randomized sequence. Decimals are also support, which have intricate effects. See the reference.

Unlock New Loot Pool in Progression

As a game progresses, it is often that the player will be provided more types of loot. Here comes the composite nodes and subgraphs.

Create two SpawnQuery assets: StarterPoolQuery and AdvancePoolQuery. For each of them, create and link a Pool Sampler to the Root. Assign the corresponding pool table to each pool sampler.

Turn off Active By Default option in the settings of AdvancePoolQuery.

In a new SpawnQuery asset (our main asset), create a Priority Selector node and link the Root node. Then create two Query Sampler nodes and link them to the Priority Selector. Assign the SpawnQuery assets we created earlier to the sampler nodes respectively. Make sure AdvancePoolQuery is on the left.

Screenshot

As the game progresses, call SpawnQuery::SetActiveState() in your Blueprint. The AdvancePool will be used in place of StarterPool in the next loot spawns.

Alternatively, if you wish to add AdvancePool to the entire pool instead of substituting, use Random Selector instead of Priority Selector. Change the Branch Weight setting according to how much the new pool is preferred.

You can also use this approach to guarantee a health pack drop when the player’s health is low or just increase the drop rate of it.

Pity System

When you want to guarantee a high-rarity drop in X drops, you could use the following steps:

Screenshot

You will get a system guaranteeing high-rarity drops with the freedom to configure how items are randomized in each respective pool.

Dynamic probability

Now here comes the Influencers. You can put comma-separated expressions in this column to control how the probability of each entry is affected by in-game variables. The grammar goes:

<Varname1>:<Factor1>,<Varname2>:<Factor2>,...

The entry’s weight will be the number in the weight column added by the sum of each variable’s value multiplied by its factor.

You can use this to implement the randomization mechanic in Diablo II, which decreases an item’s drop rate when the player acquires it.