Skip to content
Bit Quirky Round Trip
Visual Scripting

Search documentation

All topics and APIs

Close returns focus to Search.

What are you looking for?

Try a common topic or enter a complete API identifier.

Browse the reference instead

Esc closes · Tab reaches results · Enter opens the focused link

v0.89.0
Menu

Platformer graph tour

Trace four real Platformer methods from their graph shape to the exact C# statements that drive the game.

Four methods tell most of the game’s story. Read the exec wire first, then compare each card with the source statement below it. The snippets preserve the real statements; source comments are omitted so the control flow stays visible.

The CollectCoin method graph
Figure 1. Two guards protect the four calls that collect, score, refresh, and play audio.

The first branch refuses a null or already collected coin. The second refuses to proceed without the score counter and HUD. The successful path then crosses three kinds of boundary: a local collision object, scene references, and an optional composed service.

C#
public void CollectCoin(Coin coin)
{
if (coin == null || coin.IsCollected)
{
return;
}
if (_scoreCounter == null || _hud == null)
{
_logger?.LogWarning(
"player controller cannot collect a coin; its score counter or HUD reference is " +
"unassigned. wire both on the player to enable coin collection.");
return;
}
coin.Collect();
_scoreCounter.AddCoins(CoinsPerPickup);
_hud.RefreshCoins(_scoreCounter.Coins, _scoreCounter.Score);
_audio?.PlayCoin();
}

Read the calls left to right. coin.Collect() makes the pickup idempotent at the coin. AddCoins changes shared progress. RefreshCoins presents the new values. _audio?.PlayCoin() runs only when the optional service exists.

The StompEnemy method graph
Figure 2. The stomp changes enemy state and bounces before its optional scoring branches.

The opening guard makes a second stomp a no-op. State and movement happen before scoring, so the enemy still falls and the player still bounces when the scoring scene reference is absent.

C#
public void StompEnemy(Enemy enemy)
{
if (enemy == null || enemy.CurrentState == EnemyState.Defeated)
{
return;
}
enemy.ChangeState(EnemyState.Defeated);
_motor.Bounce();
if (_scoreCounter != null)
{
_scoreCounter.AddScore(_rules.stompScoreValue);
if (_hud != null)
{
_hud.RefreshCoins(_scoreCounter.Coins, _scoreCounter.Score);
}
else
{
_logger?.LogWarning(
"player stomped an enemy and awarded score, but cannot refresh the HUD; the " +
"HUD reference is unassigned. wire it on the player to show stomp scoring.");
}
}
else
{
_logger?.LogWarning(
"player stomped an enemy but cannot award score; the score counter reference is " +
"unassigned. wire it on the player to enable stomp scoring.");
}
}

The _rules.stompScoreValue GET pill is the useful data trail. Follow it into AddScore to see that the amount comes from the LevelRules asset, not a hidden literal on the graph.

The coin threshold branch
Figure 3. The score counter guards its collaborators, evaluates the threshold, and opens the goal when ready.

This method is called once during configuration and after every coin change. Missing references keep the goal closed in the HUD. With both references present, a pure rule calculates the threshold answer.

C#
public void OnCoinCountChanged()
{
if (_rules == null || _door == null)
{
_hud?.RefreshStatus(isGoalUnlocked: false);
return;
}
var shouldUnlock = CoinUnlockRule.ShouldUnlock(Coins, _rules.coinUnlockThreshold);
_hud?.RefreshStatus(shouldUnlock || _door.IsUnlocked);
if (shouldUnlock)
{
_door.Unlock();
}
}

The local shouldUnlock feeds both presentation and behavior. The HUD stays open after the door opens because its condition also reads _door.IsUnlocked. The final branch calls Door.Unlock only when the rule returns true, and CoinUnlockRule.ShouldUnlock is one line: coinCount >= threshold. Change coinUnlockThreshold on the LevelRules asset and the same graph opens the goal after a different number of coins.

The ApplyState switch graph
Figure 4. Each enemy state enters one switch arm with its own helper calls.

ApplyState turns an enum into behavior. Patrolling enables movement and collision. Stunned stops movement while leaving the body present. Defeated stops movement, disables the body collider, and swaps the visual.

C#
private void ApplyState()
{
switch (CurrentState)
{
case EnemyState.Patrolling:
SetPatrolEnabled(true);
SetBodyColliderEnabled(true);
break;
case EnemyState.Stunned:
SetPatrolEnabled(false);
break;
case EnemyState.Defeated:
SetPatrolEnabled(false);
SetBodyColliderEnabled(false);
ApplyDefeatedVisual();
break;
}
}

The switch node is the map. Each arm names a state, and the helper calls keep the cards readable without hiding the exact method sequence.

  1. Add Assets/Platformer/Runtime with Assets > Round Trip > Add Folder to Round Trip.
  2. Open each method in the order on this page.
  3. For every branch or switch, say which data pin chooses the path before reading the source.
  4. Double-click the active method title to open the same method in your code editor and check the statement order.
Full-size image