Times & Scheduling
You can define ~timer declarations and durations in your recipes using the ~ symbol.
Basic Declaration
A ~timer must specify a unit inside the braces. Fuzzy text like ~{about 10 minutes} is invalid.
Bake for ~{25min}.Supported units:
min(minutes) - Preferred standard.h(hours).d(days).s(seconds).
Note:
morminuteswill be automatically corrected tominby the compiler.
Timer Names
You can assign a specific name to a ~timer. This is especially useful for passive tasks: when multiple ~timer declarations run in parallel (like a dough resting while a sauce simmers), names allow tools and renderers to clearly identify and track them simultaneously.
Boil @eggs{2} for ~eggs{3min}.Ranges
You can specify a time range if the duration is an estimate.
Bake for ~{30-40min}.TIP
For global timeline calculations (total recipe duration), the compiler automatically uses the average of the range (here, 35 minutes).
Active vs Passive
The Gram compiler builds a complete execution timeline (similar to a Gantt chart) of your recipe. To do this accurately, it needs to know if a ~timer requires your full attention or if it runs in the background.
💡 The Golden Rule: Does this step block YOU from starting the next step?
| Your Status | Timer Type | Syntax | Examples |
|---|---|---|---|
| YES (Manual attention required) | Active | ~ | Whisking by hand, stirring a risotto |
| NO (A machine/time does the work) | Passive | ~& | Oven baking, resting, stand mixer |
Active (Default)
By default, a ~timer is active. This implies you are actively working and blocks the workflow. You must finish this before doing anything else.
Whisk the @heavy cream{} continuously for ~{5min}.⏱️ Result: Adds 5 minutes to the Active Time.
Passive (&)
Use the & modifier to make a ~timer passive. This is a background task. You start the ~timer (e.g., putting a dish in the oven) and immediately move on to the next step.
Bake in the #oven for ~&{45min}.
Meanwhile, prepare the glaze...⏱️ Result: Adds 0 minutes to the Active Time, but ensures the Cook Time is extended to cover this 45-minute wait.
How Time is Calculated
Behind the scenes, Gram computes four distinct time metrics to give you a realistic cooking schedule.
⏱️ The 4 Time Metrics
- Preparation Time (Mise-en-place): Time needed before you start step 1 (gathering ingredients, peeling, chopping).
- Active Time: Time spent actively working during the cooking steps (hands busy).
- Cook Time: The absolute time of the cooking workflow from step 1 to finish (including passive waiting).
- Total Time: The sum of Preparation Time + Cook Time. This is the realistic "time in the kitchen".
Cheat Sheet: What adds time?
Here is a concrete breakdown of how the compiler automatically calculates minutes based on your syntax:
| Syntax / Scenario | Adds to Prep Time | Adds to Active Time | Adds to Cook Time | Adds to Total Time |
|---|---|---|---|---|
New Ingredient (@flour) | + 1 min | - | - | + 1 min |
Prep shorthand (@onion(peeled)) | + 2 min | - | - | + 2 min |
Active Timer (~{10min}) | - | + 10 min | + 10 min | + 10 min |
Passive Timer (~&{1h}) | - | - | + 1 hour (in background) | + 1 hour |
| Step without any timer | - | + 2 min (default fallback) | + 2 min | + 2 min |
Smart Dependency Tracking
You don't need to do complex math! If you declare a dough that rests for ~&{1h} in the background, and a later step requires that &dough, the compiler automatically "pauses" the timeline and waits for the hour to finish before starting that step.
Error Handling
The compiler validates ~timer declarations to ensure precise scheduling and will output specific warnings for malformed data:
- Missing Unit: If you write
~{30}without specifying minutes or hours, the compiler warnsMISSING_UNIT. - Invalid Unit: If you provide a unit the compiler doesn't understand (e.g.,
~{30 lightyears}), it warnsINVALID_UNIT.