ℹ️
Goals do not gate completion. A level is completed when the player reaches the End tile, regardless of goals. Goals award stars (one per satisfied goal) shown on the world map and level-select screen.

LevelGoal

Plain C# abstract class — not a ScriptableObject. Concrete subclasses are referenced by type name inside the LevelInfo.Goal struct and instantiated on demand via reflection. No manual registration is needed: the Inspector dropdown discovers all subclasses automatically.

Abstract Members

MemberTypeDescription
displayText string (get) Human-readable label shown in the level-select UI next to the goal's star indicator. Example: "Use less loops".
Check(
  LevelData level,
  int amountRequired)
bool Returns true if the player satisfied this goal. level contains the completed run's statistics; amountRequired is the threshold set per-level in the LevelInfo Inspector.

Built-in Goals

Three concrete implementations ship with the project. Select them from the goals dropdown in any LevelInfo asset.

ClassdisplayTextWin conditionInspector name
LevelGoal_InstructionCount "Make an instruction sheet" instructionsCount ≤ amountRequired Instruction Count
LevelGoal_LoopCount "Use less loops" loops ≤ amountRequired Loop Count
LevelGoal_PlayerHealth "Finish with more health" playerHealth ≥ amountRequired Player Health

LevelData

The object passed to Check(). It is saved when the player completes a level and read back whenever goals are evaluated. Use its properties to drive custom goal logic.

PropertyTypeDescription
instructionsCountintTotal number of instructions placed on the sheet when the level was completed.
loopsintSum of all loop iteration counts across every sequence instruction in the sheet.
playerHealthintPlayer's remaining health when the level was last completed.
playerStaminaintPlayer's remaining stamina when the level was last completed.
completedbooltrue if the player has reached the End tile at least once.
instructionsSerializedInstruction[]Raw serialized instruction data from the winning solution. Use this for advanced goals that inspect the structure of the sheet.
levelIDstringID matching the LevelInfo this data belongs to.

Create a Custom Goal

  1. Create a new C# script in Assets / Scripts / Levels / Goals /.
  2. Inherit from LevelGoal and add the [TypeName] attribute with a user-friendly label — this is the name shown in the Inspector dropdown.
  3. Override displayText with the string the UI will show next to the star indicator.
  4. Override Check() with your evaluation logic. Return true if the player satisfies the goal.

No registration step is required. The Inspector dropdown uses TypeCache.GetTypesDerivedFrom<LevelGoal>() to discover all concrete subclasses at editor time.

using LoopAdventure;

[TypeName("No Loops Used")]
public class LevelGoal_NoLoops : LevelGoal
{
    public override string displayText => "Complete without loops";

    public override bool Check(LevelData level, int amountRequired)
    {
        return level.loops == 0;
    }
}
💡
amountRequired is optional. If your goal has no numeric threshold (like the example above), simply ignore the parameter. The field will still appear in the Inspector but its value will have no effect.