Meters and Shared Values
Use Meter with Thresholds for a value such as health, suspicion, or heat. Its template provides a changeMeter entry point, clamps each update, and publishes Events when the value crosses a threshold. Store the value in a Data Structure field when a HUD or another Logic attachment needs to read it.
Prerequisites
Prepare a 2D Object named Boss and a Scene containing one placement. Create a Data Structure named Boss Info with a Number field hitPoints, default 3, and attach it to Boss. Save a checkpoint before adding Logic.
This guide uses the development template reviewed on October 5, 2026, at revision 53a65d8388cf. Existing projects retain their own template copies. A previously created copy can lack Meter Field even when the installed engine has the new template.
Create and Attach the Meter
- Choose Add > Objects and Logic > Logic Component.
- In Create Logic Component, name it
Boss Meterand set Starter to Meter with Thresholds in the State group. Choose Create. - Open Boss, choose Logic in Object Editor Mode, and attach Boss Meter once from Compatible Logic.
- Select that row in Attached Logic and inspect its input bindings.
- Set Meter Field to the text
hitPoints, Change Amount to-1, Minimum to0, Maximum to3, and Threshold to2. - From a discrete click or input Event on Boss, use Trigger Custom Event with the name
changeMeteron SELF. Connect the Event through the Action to End. - Run from a fresh start and trigger one change at a time.
Expected result: the Data Structure field starts at 3, then changes to 2, 1, and 0. Further negative changes leave it at 0. Each Boss instance owns its own field; another placement retains its starting value until it receives a change.
Read the field through the Object’s Data Structure slot in the debugger or another compatible Logic attachment. For a HUD, bind to that same Object and field. The Text guide covers display bindings; shared state explains ownership.
Show Player Health in a HUD or Health Bar
Player health must have one authoritative value. A health bar or numeric HUD should read the same hitPoints field that Boss Meter updates. Leaving Meter Field blank stores the value privately, which prevents an external HUD from reading it.
Start with a numeric Text display so you can compare exact values before styling a health bar. For the one-Boss check:
- Declare a Number Project Global named
bossHealth, default3. - Create a separate Logic Component named
Show Boss Healthand attach it once to Boss. In Step, connect Change Variable to End. - Set Scope to Global, Variable to bossHealth, and Operator to
=. For Value, use the field picker to select SELF’s Boss Info Data Structure and its hitPoints field. Choose the field reference rather than the literal texthitPoints. - Create a screen-space Text Object with Text
Health: {$bossHealth}. Live Text covers the template and placement. - Run with exactly one Boss. Trigger changeMeter and compare the HUD with its hitPoints field.
The field remains the authoritative health value. The Step Action copies it to a display Global each frame, so the HUD can update one frame after a change. With several Boss instances, this shared Global needs one selected target; attaching the sampler to all of them would make their writes compete. A HUD with a compatible Object reference can read that selected instance directly; see Object Parameters.
Check the initial 3, each change to 2, 1, and 0, and a loaded save. With two Boss instances, confirm which one the HUD targets. The same storage check applies to stamina, heat, and other progress bars.
Draw the Health Bar
Once the numeric display agrees with the field, add Draw GUI to Show Boss Health. Connect these Actions in order, then End:
| Action | Values |
|---|---|
| Set Draw Color | Color: #333333 |
| Draw Rectangle | X1: 20; Y1: 20; X2: 220; Y2: 32; Filled: on; Depth: blank |
| Set Draw Color | Color: #ff534f |
| Draw Rectangle | X1: 20; Y1: 20; X2: the expression below; Y2: 32; Filled: on; Depth: blank |
| Set Draw Color | Color: #000000, to restore the default for later drawing |
For the second rectangle’s X2, choose an expression and enter:
20 + 200 * min(1, max(0, $bossHealth / 3))Here 3 is the meter’s maximum. The fraction clamps the bar between empty and full. Find Set Draw Color under Advanced > Glyphs > Draw Style and Layers, and Draw Rectangle under Advanced > Glyphs > Draw Shapes and Sprites. Enable Advanced Mode if those Actions are absent.
Draw GUI uses screen pixels, with (0, 0) at the bottom-left and positive Y upward. These drawing coordinates differ from the Boss’s position in world metres. The bar starts 20 pixels from the left and bottom edges and fills 200 pixels at full health. At 2, 1, and 0, its fill should be about 133, 67, and 0 pixels wide. Put these Actions in Draw GUI so the bar is redrawn every frame.
See Draw Rectangle and Draw GUI for the current fields and Event.
Choose Storage Deliberately
| Meter Field | Where the value lives |
|---|---|
| Blank | The template attachment’s private Local Variable meter, initially 0. Other attachments and external Text bindings cannot read that private state. |
hitPoints |
The named field in the Object’s primary Data Structure. Its existing value supplies the starting meter value. |
An access name and field, such as stats.hitPoints |
The field in the additional Data Structure identified by that access name. Use the actual component access name. |
Select a declared Number field. Confirm that it exists on the attached Object before running. Keep the HUD, damage reader, and meter update pointed at one field so they agree after each update.
Changing a template input default affects attachments that inherit it. An attachment binding can override that default. Inspect the selected row before assuming all Boss placements use the same bounds or change amount.
Respond to Threshold Crossings
Add Meter Threshold Lost to a separate compatible Logic attachment on Boss. Set its meter filter to meter. For the example, the update from 3 to 2 stays at the threshold; the update from 2 to 1 crosses below it and runs Lost once.
Meter Threshold Reached handles the other direction, from below the threshold to at or above it. Test a positive change from 1 to 2. Further increases while already above the threshold shouldn’t repeat the reached response.
The filter remains meter when Meter Field is hitPoints. The storage field and the Event’s meter name have different purposes. Event context supplies event.meter, event.previousValue, event.value, and event.threshold; see the meter Events.
Change the meter through changeMeter when its threshold Events should run. A separate direct write to the Data Structure field changes the field without executing the template’s update and publication sequence.
Check a Saved Game and an Older Template
After the basic check, save with the meter at 1, change it again, and load the saved state. Inspect the field, displayed value, and the next threshold crossing. Saving and loading explains storage completion and failure handling.
If Meter Field is missing, create a fresh Logic Component with the current Starter and inspect it before replacing anything. Compare your existing template’s edits and attachment bindings. Creating a new template doesn’t update the older project’s copy automatically.
Troubleshooting
| Symptom | Check |
|---|---|
| Other Logic or Text cannot show the value | Check whether Meter Field is blank; the default Local Variable is private. |
| The wrong field changes | Check its name, the primary versus additional Data Structure, and the attachment’s binding. |
Lost never runs when the field reaches 2 |
Threshold 2 is still at the threshold; test the change from 2 to 1. |
The filter on hitPoints receives nothing |
Use the template’s Event name meter as the meter filter. |
| One input reduces the meter several times | Count attachments and discrete Event firings; inspect repeated or held input. |
| A direct field assignment produces no crossing Event | Route the intended meter change through changeMeter. |
| The saved value and HUD disagree | Check that the HUD reads the restored field on the intended live instance. |
Myth Engine Documentation
