Skip to content

Counter

namespace Griff.Scenes;
public sealed class Counter : Component

Keeps count and shows it in its entity’s Text: a score, coins, kills. Every Message sent adds to it (the number sent along, or 1; or just 1 with OnePerMessage), so it adds up Pickups with no code; scripts can call Add. It can count anything’s output instead (a board’s score, the dungeon floor, a faction’s gold: see Output). When it Reaches a value it sends its ReachMessage and its own output Reached turns on. With SaveBestAs it remembers the highest count ever, between runs.

This is a component: its saved properties are on its component page.

public int Best { get; }

The best count, from SaveBestAs (or this run’s, without it).

public int BestToBeat { get; set; }

The best kept under SaveBestAs as this scene started: what the count has to beat to be a new best. -1 until the game has read it. Set by the game.

public string? Format { get; set; }

How the text reads: {0} is the count and {1} the best, e.g. “Score: {0}”, “Best: {1}” or “{0:000000}” (and {2} what it’s out of and {3} how many are left, e.g. with the Output “Goals Covered” how many goals there are and how many are still uncovered). Empty shows just the number.

public string? Item { get; set; }

An item to count instead of a message, e.g. “Key”: it shows how many the first Inventory in the scene (usually the player’s) holds.

public int Left { get; }

How far the count is from Total, never below 0 ({3} in Format): goals left, moves left.

public bool Loaded { get; set; }

Set by the game once it has taken its count from the save data, so a rewind doesn’t do it again. Leave it be.

public int Max { get; set; }

The most the count goes up to: adding past it stops there, e.g. 5 for a multiplier up to 5x. 0 has no limit.

public string? Message { get; set; }

The message that adds to it, e.g. “Score” for Game.Send("Score", 10). Empty only counts Add.

public string? MultiplyBy { get; set; }

Another counter, by name, whose count multiplies what each Message (and the Add action) adds to this one: a score counted double, triple and so on while a “Multiplier” counter says so. Empty multiplies by nothing.

public bool NewBest { get; }

True once the count has beaten the best kept under SaveBestAs as the scene started: a new best.

public string? NewBestMessage { get; set; }

A message sent as the count first beats the best kept under SaveBestAs while it’s being played (a new best), with the count as its data, e.g. “New Best”: a sound player plays a sting on it. Not sent while nothing’s been kept yet.

public bool OnePerMessage { get; set; }

Add 1 for each Message, whatever number it sends: a beat clock’s Beat sends the beat’s number (0, 1, 2…), so a counter of beats adds one a beat with this, rather than adding the numbers up.

public string? Output { get; set; }

Count an output instead of a message: whatever it gives, now (see component_describe’s Outputs), e.g. a board’s “Score” or “Moves Left”, a dungeon’s “Floor”, a turn order’s “Round”, a beat clock’s “Beat”, a faction’s “Amount:Gold” or “Units”, another counter’s “Count”. What it’s out of, if it says, is {2} in Format.

public float Pop { get; set; }

How big the text pops when the count changes, springing back: 1.3 is a little pop, 1 none.

public int Reach { get; set; }

The count it reaches, e.g. 10 coins, or 0 moves left.

public string? ReachMessage { get; set; }

A message sent as the count reaches Reach, with the count as its data: a trigger opens a door or a panel on it. Sent again if the count leaves it and comes back.

public bool Reached { get; }

True while the count is at (or past) Reach, the way Reaches says.

public CounterReach Reaches { get; set; }

Do something as the count reaches Reach: once it’s at least that (counting up) or at most that (counting down). It sends ReachMessage each time it gets there, and its output Reached is on while it’s there, for a wire into a door’s Power.

public string? SaveAs { get; set; }

Keeps the count itself in the game’s save data under this name, e.g. “Coins”, so a counter saved as the same name in the next scene (or a minigame) carries on from it, and so does the next run: coins or a score kept from level to level. Empty keeps nothing.

public string? SaveBestAs { get; set; }

A name to keep the best count under in Game.SaveData, e.g. “best”. Whenever the count beats it, it’s saved, so another counter (on a menu, with Format “Best: {1}”) can show it.

public int Total { get; }

What the count is out of, for a counter that counts goals, a match board’s moves, score or gems ({2} in Format); 0 otherwise.

public string? Track { get; set; }

An entity whose Output it counts, by name, e.g. “Board”. Empty is this entity, or the nearest one it’s inside with that output; “*” is the first entity in the scene that has it, wherever it is (a HUD’s counter of the board’s score, the goals covered, the moves taken or the dungeon’s floor).

public int Value { get; set; }

The count now. Set it to start from something other than 0.

public void Add(int amount = 1)

Adds amount (take some away with a negative amount), times the count of the counter it’s multiplied by (see MultiplyBy), never past its Max.

public string Display()

The text to show: Format filled in, or just the number if it can’t be.

public override string? LinkLabel(string property)
public string ReadsAs(string? format)

What its text says with format as its Format, as the count is now.

public void Reset()

Starts the count again from 0.

public void Set(int amount = 0)

Sets the count to amount, e.g. a multiplier back to 1 as the ball drains.

public override bool Uses(string property)
public event Action<Counter>? Changed

Raised when the count changes.