Development Best Practices for Optix

Practical development practices for FactoryTalk Optix: project organization, version control, building reusable components, performance optimization, and common pitfalls that trip up teams transitioning from ME.

Part 4 of 5: Optix Migration Planning Series

Link to Part 3: Migration Strategies

You've planned your migration, assessed your application, and chosen your strategy. Now you're actually building in Optix Studio.

Before diving into development, make sure you understand Optix's template architecture fundamentals. If you haven't read The Architecture Advantage: Why Optix Template Design Determines ROI, start there. Understanding Types, Instances, and Aliases is the foundation that makes everything in this post work.

This post covers practical development practices that apply regardless of whether you chose hybrid, redesign, or a mixed approach in Part 3. You're learning Optix Studio while implementing these practices on your first project, which means the learning curve compounds. These practices help manage that complexity and set you up for long-term success.

Project Organization

Structure Your Project for Scale

The way you organize your Optix project determines how quickly engineers find components and whether your application remains maintainable as it grows.

An organized project has clear folder structure:

Project
  ├─ UI/
  │   ├─ Screens/
  │   │   ├─ Main/
  │   │   ├─ Equipment/
  │   │   └─ Alarms/
  │   ├─ Popups/
  │   │   ├─ Main/
  │   │   ├─ Equipment/
  │   │   └─ Alarms/
  │   ├─ Templates/
  │   │   ├─ Main/
  │   │   ├─ Equipment/
  │   │   └─ Alarms/
  │   └─ Graphics/
  └─ Model/
      ├─ Main/
      ├─ Equipment/
      └─ Alarms/

Establish folder structure during architecture phase, before you start building screens.

Naming Conventions Are Critical

Consistency is critical for template-driven development.

Screens:

  • Main (not main, Menu1, menu_screen)
  • TankDetail_01 (not Tank1, tank_01_details, Tank01Screen)

Types:

  • TankType (singular, capitalized)
  • PumpType (not Pumps, pump_type, pumpType)

Variables/Aliases:

  • LevelPV (PascalCase for aliases)
  • maxSpeed (camelCase for local variables)

Establish conventions in architecture phase. Document them. Enforce them.

Version Control Best Practices

Optix Studio Makes This Easy

Good news: You don't need command-line Git knowledge.

Optix Studio built-in version control:

  • Commit button: Save changes to repository
  • Pull button: Get updates from team
  • Push button: Share changes with team
  • History button: View past commits

That's it. No terminal commands required.

See the Getting Started with Version Control in FactoryTalk Optix for more information (coming soon).

Building Reusable Components

Types Are Your Default Approach

Every repeated element should be a Type.

Candidates for Types:

  • Equipment faceplates (pump, tank, valve)
  • Navigation buttons
  • Alarm indicators
  • Status displays
  • Input forms

Example: PumpType

Create once:

PumpType
  ├─ RunIndicator (green = running)
  ├─ FaultIndicator (red = faulted)
  ├─ StartButton
  ├─ StopButton
  └─ SpeedDisplay

Use many times:

  • Pump01 (instance of PumpType)
  • Pump02 (instance of PumpType)
  • Pump03 (instance of PumpType)

Update PumpType and all pumps update automatically.

When to Create a Type:

If it varies by machine instance, make it a Type regardless of count. One screen used across 50 machines with different parameters is a better Type candidate than five identical static help screens.

Alias Strategy

Every tag binding should use aliases created at the Type. Hard-coded bindings are technical debt.

Bad:

LevelDisplay.Text ← "Tank01_Level_PV"

Good:

LevelDisplay.Text ← Alias: "LevelPV"

Tank01 screen: Alias "LevelPV" points to "Tank01_Level_PV"
Tank02 screen: Alias "LevelPV" points to "Tank02_Level_PV"

Same screen Type. Different alias values.

Alias Naming

Match alias names to purpose, not source:

Bad: PV_1, Tag_Level, Input_A
Good: LevelPV, TempPV, RunCommand

Why: Alias names are visible in Studio. Clear names = easier maintenance.

For a complete worked example, see Building Reusable Popup Templates with Alias Passing. This demonstrates how to build a single parameter editing popup that works for unlimited parameters using Types, Instances, and Aliases. Exactly the pattern you'll use throughout your Optix application.

Configuration Object Pattern

For complex machines, create MachineConfig object:

MachineConfig
  ├─ NetworkSettings
  │   ├─ PLCIP (string)
  │   └─ PanelName (string)
  ├─ ProcessLimits
  │   ├─ MaxSpeed (float)
  │   ├─ MinSpeed (float)
  │   └─ AlarmThreshold (float)
  └─ EnabledFeatures
      ├─ BadgeLogin (bool)
      ├─ MultiLanguage (bool)
      └─ RecipeManagement (bool)

Use this object to drive entire application:

  • Alias values
  • Screen visibility
  • Feature enable/disable

This pattern scales. Simple machines might have five properties in MachineConfig. Complex machines might have twenty. The principle remains: centralize configuration in one location rather than scattering it across fifty screens. When commissioning Machine #47, you change MachineConfig values, not hunt through the entire application.

NetLogic Best Practices

When to Use NetLogic (and When Not To)

Use NetLogic for:

  • Complex calculations (beyond dynamic links)
  • External system integration (databases, REST APIs)
  • Custom data processing
  • Advanced UI interactions

Don't use NetLogic for:

  • Simple math (use dynamic links with expressions)
  • Visibility changes (use converters)
  • Tag manipulation (use built-in methods)

Most OEM applications need little to no NetLogic. If Optix has a built-in feature, use that. NetLogic is for gaps in functionality.

The distinction: if Optix has a built-in feature or converter for your need, use that. NetLogic is for gaps in built-in functionality, not for reimplementing features that already exist.

Design-Time vs. Runtime NetLogic

Design-Time NetLogic:

  • Automates project creation
  • Bulk tag import
  • Screen generation from templates
  • Runs in Studio during development
  • Use for: Speeding up repetitive development tasks

Runtime NetLogic:

  • Custom behavior when application runs
  • UI interactions
  • Calculations
  • Data processing
  • Use for: Features Optix doesn't handle natively

Code Quality When You Do Write NetLogic

If you do write NetLogic:

Follow C# best practices:

  • Clear variable names
  • Comments for complex logic
  • Error handling (try/catch)
  • Logging for debugging

Keep it simple:

  • Short methods (< 50 lines)
  • Single responsibility
  • Testable

Document:

  • Why this NetLogic exists
  • What problem it solves
  • How to test it

Performance Optimization

Keep Applications Responsive

Target: Screen load < 1 second, smooth interactions.

Note: Emulator performance differs from panel deployment. Always test on target hardware.

Avoid:

  • Polling hundreds of tags unnecessarily
  • Complex animations on every element
  • Massive trend datasets on startup
  • Unoptimized graphics (huge PNG files)

Tag polling strategy: Configure in tag importer:

  • Static values: Read once on startup
  • Fast-changing process values: Higher poll rate
  • Moderate updates (alarms): Medium poll rate

Best practices:

  • Read tags only when needed
  • Optimize graphics (use SVG when possible)
  • Lazy-load trend data (on screen open, not startup)
  • Use dynamic visibility (don't render hidden elements)

Documentation During Development

Document As You Build

For each Type:

  • Purpose and usage
  • Required aliases
  • Configuration parameters
  • Known limitations

For complex NetLogic:

  • What it does
  • Why it exists
  • How to modify safely

For navigation:

  • Screen hierarchy
  • How to add screens
  • Popup conventions

Good documentation facilitates commissioning. Field technicians need to know which aliases need values, valid parameter ranges, and optional features. Document for deployers and maintainers, not just developers.

Iterative Development Approach

Don't Build Everything at Once

Teams transitioning from ME often build the entire application before testing. This compounds risk. In Optix, you're learning while building templates. Test continuously.

Structured Approach

Define phases explicitly:

  • Phase 1: Core navigation, 2-3 key screens, basic Types. Test and validate.
  • Phase 2: 5-10 more screens, refine Types, implement first optional feature. Test.
  • Phase 3: Complete screens, add features, polish, full testing.

Works well for teams wanting clear milestones.

Organic Approach

Build features as they become clear:

  • Start with critical screens (equipment details)
  • Build supporting Types as needed
  • Add navigation when you have screens to navigate
  • Test constantly in emulator
  • Refactor when patterns emerge

Works well for experienced developers comfortable with emergent design.

Balanced Approach

Combine structure with flexibility:

  • Identify must-have features
  • Build those with proper architecture
  • Add nice-to-have features iteratively
  • Test with operators for validation
  • Iterate based on feedback

Reference Migration Execution Guide for timeline planning.

Key principle: Deliver incrementally, test continuously, course-correct early.

Common Development Pitfalls

Pitfall 1: Not Using Types

Every screen built from scratch, changes require touching multiple screens. You're missing Optix's core value.

Fix: Identify repeated elements early, convert to Types, resist copy-paste.

Pitfall 2: Hard-Coded Values Everywhere

Motor faceplate instantiated throughout project. Marketing wants font change. You're manually updating dozens of screens.

Fix: Build MotorType properly. Update Type once, all instances update automatically.

Pitfall 3: Inconsistent Naming

Tank01, tank_02, Tnk3, Tank 04 scattered through project. Confusion, hard to find components, looks unprofessional.

Fix: Document conventions before building, enforce during development, refactor immediately.

Pitfall 4: No Version Control Discipline

"It worked yesterday, what changed?" Nobody knows. Can't roll back.

Fix: Commit frequently with clear messages, pull before work, push when done.

Pitfall 5: Building Before Designing Architecture

Halfway through, architecture doesn't support needed functionality. Major rework required.

Fix: Complete architecture design first (see Architecture Advantage post), validate with pilots.

Pitfall 6: Skipping Emulator Testing

"We'll test on hardware." Issues found late, expensive to fix.

Fix: Test in emulator continuously. Validate each Type before creating many instances.

Pitfall 7: Copy-Paste Development

Engineers copy Tank01 for Tank02, manually change bindings. Fixing bug means touching dozens of screens.

Fix: Use Types and Instances. All Tanks are instances of TankType.

Conclusion

Development best practices are force multipliers:

Good practices:

  • Organized project structure
  • Consistent naming conventions
  • Version control discipline
  • Reusable Types and aliases
  • Continuous testing
  • Iterative development

Result: Faster development, fewer bugs, maintainable applications

Bad practices:

  • Chaotic organization
  • Hard-coded everything
  • No version control
  • Copy-paste development
  • Test at the end

Result: Slow, buggy, unmaintainable

The difference isn't talent. It's discipline.

By your tenth machine, you're building faster than you ever did in ME. By your fiftieth machine, you're building at a fraction of the time. Establish practices early. Maintain them consistently. The upfront investment pays off forever.

Need Development Support?

ASQI offers hands-on development support, code reviews, and best practices training for Optix teams.

Services include:

  • Architecture review and optimization
  • Code review and refactoring guidance
  • Team training on development best practices
  • On-site implementation support

Contact ASQI →


Next in Series: Part 5 - Testing & Go-Live: Final Validation and Deployment



Optix Tips and Tricks — Quick wins and common gotchas that complement these best practices.

Optix Layout & Positioning — Deep dive into the layout and positioning challenges mentioned here.

The Architecture Advantage — The strategic case for the template patterns described in this guide.

Legacy Application Modernization: A Case Study — How careful planning transformed a legacy .NET resource management system.