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. There are five types:
TypeDescriptionExample
booleanTrue/false flagis_rush, qc_passed, requires_rework
numberInteger or decimalweight, priority, complexity_factor
textFree-form string labelAny text value
text_listConstrained choice from a fixed set of strings (enum)product_class where choices are "A", "B", "C"
number_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 / 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 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).
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. All six strategies are available in all six places.

fixed

Assigns the same value to every entity the component creates. Use for attributes that are the same across all items: a flag that’s always true, a classification that’s always "standard".

dsl_expr

Assigns the result of a DSL expression evaluated at assignment time. Use when the value depends on simulation state, other attributes being assigned, or the current time: IF(SIM_TIME < SHIFT_1_END, "day", "night") for shift-stamped entities, or LOOKUP(priority_by_class, product_class) to derive one attribute from another.

round_robin

Cycles through a list of values in order. The first entity gets value 1, second gets value 2, third gets value 3, fourth cycles back to value 1. Use for evenly distributing entities across categories without randomness — e.g., spreading work across product lines in a deterministic sequence.

random_choice

Picks uniformly at random from a list of values. Every value has equal probability. Use when entities come from an unordered categorical mix and you just need variety: random product types, random colors, random regions.

random

Samples from a probability distribution (normal, exponential, triangular, etc.). Applies to number attributes. Use for natural variability: entity weights drawn from a normal distribution, service time requirements drawn from triangular, arrival interval drawn from exponential.

weighted

Picks from a list of values with different probabilities per value. Specify a weight for each option; the relative weights determine selection probability. Use for non-uniform categorical distributions: 70% Product A, 20% Product B, 10% Product C.

Defining an Entity Type

Entity types are defined in the factory’s entities panel — where you view and edit every entity type available in the active factory and toggle through each one’s attributes. Each type has:
  • A name and description
  • A set of typed attributes (with choice sets declared for text_list and number_list attributes)
  • Optional default assignment strategies per attribute (used by components that don’t override them)
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.

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) 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), setting new attributes on the output that are meaningful for the next stage. 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 / 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.
  • Assignment strategies work everywhere. Don’t duplicate the logic of a dsl_expr assignment on a Source and a schedule — define the strategy once and reuse it wherever the attribute is assigned.