Skip to main content

Overview

An Entity is an item that flows through a simulation — a work order, a finished good, a pallet, a batch, a patient, a truck. Every simulation revolves around entities being created, routed, processed, and terminated. What makes entities powerful in ProDex isn’t the concept of “things flowing through a graph” — it’s that entities carry typed attributes with them, and expressions across the model can read and act on those attributes. An entity isn’t just an anonymous token; it’s a bundle of typed data that components inspect, route on, time-process differently, and aggregate. This is the mechanism that turns a static flow diagram into a model that responds to the specific work being done.

Attribute Types

Each entity type defines a set of named attributes. The schema has five canonical types; the UI splits Number into Integer and Real, so the attribute-type dropdown shows six options.
Schema typeUI label(s)DescriptionExample
BooleanBooleanTrue/false flagis_rush, qc_passed, requires_rework
NumberNumber (Integer), Number (Real)Integer or decimal; optional lower_bound, upper_bound, and exclude_zero constraintsweight, priority, complexity_factor
TextTextFree-form string; optional max lengthAny text value
Text ListText ListConstrained choice from a fixed set of strings (enum)product_class where choices are "A", "B", "C"
Number ListNumber ListConstrained choice from a fixed set of numbers (enum)size_tier where choices are 1.0, 2.5, 5.0
The List types are enums, not lists. A Text List attribute doesn’t hold multiple strings — it holds one string, picked from a fixed set of allowed values declared on the entity type. Same for Number List: the attribute’s value is one number chosen from a predefined set. Think of them as constrained categorical values, not arrays. Use Text List or Number List when you want an attribute to be categorical and you want the platform to enforce valid values. Use Text or Number when the attribute is open-ended. Attribute types are fixed on the entity type — you can’t store a number in a Text attribute. The expression language respects these types when you reference attributes by name.

How Attributes Flow

Attributes set on an entity persist with it through the entire flow. Once assigned, downstream components can read them without any explicit propagation.
  • Create / assign — attributes are assigned any time a component produces a new entity. That’s on Sources (creating initial entities), Combiners (output entity of a batch), Separators (output entities of a split), Transformers (output entity of a type change), and material releases on either a Source or a Buffer in a schedule.
  • Read — any downstream expression in a single-entity context can reference the attribute by bare name (priority, weight).
  • Change identity — a Transformer produces a new entity of a different type with its own attribute assignments. It doesn’t mutate the input entity’s attributes in place — it emits a different entity, typed differently, with its own attribute values.
  • Aggregate — when entities are combined, the output entity’s attributes are computed from the set of inputs using aggregation functions like SUM(weight) or MAX(priority) in the Combiner’s multi-entity context.
Transformer attribute carryover is not automatic. When a Transformer emits an output entity, none of the input entity’s attributes are copied across by default. Every attribute you want on the output must be explicitly assigned, most commonly as dsl_expr referencing the input attribute by bare name. If you skip an assignment, the output entity’s attribute receives the type-default value (0, "", or FALSE) — silent data loss. Separator outputs behave the same way.
The DSL doesn’t require a prefix to read attributes — just use the bare name. priority and product_class are valid identifiers in any expression that has an entity in scope.

Assignment Strategies

Whenever a component assigns an attribute on a new entity — on a Source, Combiner, Separator, Transformer, or schedule material release — it uses one of six strategies. Not all six are valid for every attribute type; the dropdown filters to the strategies that work for the attribute you’re configuring.
StrategyPurposeValid attribute types
FixedAssigns the same literal value to every entityAll types
DSL ExpressionEvaluates a DSL expression at assignment timeBoolean, Number, Text (not list types)
Round RobinCycles deterministically through the entity type’s declared choicesBoolean, Text List, Number List
Random ChoicePicks uniformly at random from the entity type’s declared choicesBoolean, Text List, Number List
RandomSamples from a probability distributionNumber only
WeightedPicks from the entity type’s choices with per-choice weightsBoolean, Text List, Number List
Random Choice and Random are different strategies. Random Choice picks uniformly from a categorical choices array (boolean / text list / number list). Random samples from a probability distribution (number only). The dropdown filters them out based on attribute type, so you’ll only see the ones that apply.

Strategy Details

Fixed — Same value on every entity. Useful for attributes that don’t vary across items, or as a placeholder before you wire in real variability. DSL Expression — The value is the result of a DSL expression evaluated when the entity is created. Use when the value depends on simulation state, other attributes, or the current time: IF(SIM_TIME < SHIFT_1_END, "day", "night") or LOOKUP(priority_by_class, product_class). Not valid for Text List or Number List — for dynamic categorical selection use Weighted with DSL-expression weights, or restructure to Random Choice. Round Robin — The first entity gets value 1, second gets value 2, third gets value 3, fourth cycles back to value 1. Useful for evenly distributing entities across categories without randomness. Random Choice — Uniform random pick from the entity type’s choices array. Every choice has equal probability. For Boolean attributes the choice set is {true, false}. Random — Samples from a distribution (normal, exponential, triangular, etc.). Useful for natural variability — entity weights drawn from a normal, service-time requirements drawn from triangular, or arrival intervals drawn from exponential. Weighted — Pick from the entity type’s choices with per-choice weights. Specify a weight for each option; relative weights determine selection probability. Weights can themselves be DSL expressions for dynamic distributions.

Defining an Entity Type

Entity types are managed via the Entities button at the bottom of the Modeler’s Library panel — opens a modal listing every entity type in the factory with Name, Description, Unit, and Attrs columns. Each type has:
  • A name and description
  • A set of typed attributes (with choices arrays declared on Text List and Number List attributes, optional lower_bound/upper_bound/exclude_zero on Number attributes, and optional length on Text)
Once defined, an entity type is available to every model in the factory. Sources, Transformers, BOM nodes, Combiners, and Separators that produce entities of that type share the same attribute schema — if you add an attribute to the type, every place that creates or modifies the entity can now set it. Entity types live in entities/{slug}.json in the factory’s data tree.

Patterns

Classification attribute driving routing. A product_class Text List attribute set at the Source (one of "rush" or "standard") drives a Router that sends rush items to the express line. Numeric attribute driving processing time. A complexity_factor Number attribute (drawn from a distribution via the Random strategy) multiplies the base processing time on each Process. Type change in a Transformer. A Transformer reassigns the entity to a new type painted_part (from raw_part), with explicit DSL-expression assignments that carry forward every attribute the downstream model cares about. Aggregation in a Combiner. When three components are combined into an assembly, the output entity’s total_weight is SUM(weight), priority is MAX(priority), and qc_passed is ALL(qc_passed).

Tips

  • Model the attributes you’ll query. If you care about “cycle time by product class” in your results, product_class has to be an attribute on the entity — otherwise the join isn’t available in the simulation dataframes.
  • Use Text List or Number List for categorical constraints. They’re enums — the platform enforces that the value is one of the declared choices. Prefer these over free-form Text when the attribute has a known finite set of valid values.
  • Prefer entity attributes over state variables for per-entity data. State variables are for facts about the system. Attributes are for facts about a specific entity.
  • For dynamic categorical selection, use Weighted with DSL-expression weights. That’s the only way to drive list-type attributes from expressions, since DSL Expression isn’t valid for list types.
  • Explicit attribute carryover — every output attribute on a Transformer or Separator must be assigned. There’s no auto-copy from the input.