End Of Simulation Customization Point

Sample customization that occurs at the end of an action or transmission that can trigger other actions.

This guide will explain what the EndOfSimulation customization is as well as how it can be changed and used for different samples. If you are just getting started, view the following articles for more information on the basics: getting started with customizations.


The EndOfSimulation customization that causes user defined actions after a simulation has been ran. It has two main functions with the first being SimulationInitialization. In this function any previous transmissions are cleaned up to be able to start the next action with a clean slate. In the second main function, EndOfSimulationCleanup, is run at the end of the EndOfSimulation customization and is responsible for everything that is triggered after the simulation.


This customization has been used in many different samples. One example is in the MRP NoImpact sample, if you want a step by step guide to how that sample works you can find it here. By default when MRP is used it runs an optimize and automatically schedules the orders afterwards. The EndOfSimulationCleanup function in the NoImpact sample allows the user to run MRP and not automatically schedule the orders after the optimize. 

protected override void SimulationInitialization(ScenarioDetail a_sd, SimulationType a_simulationType, ScenarioBaseT a_transmission)

if (!m_initialized)
using (var seoa = a_sd.Scenario.ScenarioEventsLock.EnterWrite())
seoa.Instance.MRPStatusUpdateEvent += MRPStatusUpdateEventHandler;

m_initialized = true;
protected override void EndOfSimulationCleanup(SimulationType a_simType, ScenarioBaseT a_t, ScenarioDetail a_sd)
if (a_t is ScenarioDetailOptimizeT mrpT && mrpT.RunMRP && m_mrpFinalOptimize)
m_mrpFinalOptimize = false;
JobKeyList jobsList = new JobKeyList();

//Gather new MRP jobs
foreach (Job job in a_sd.JobManager)
if (job.Template)
foreach (InternalOperation op in job.GetOperations())
if (op.Locked != lockTypes.Locked)

//Mark new MRP jobs as Do Not Schedule
ScenarioDetailSetJobCommitmentsAndPrioritiesT bulkUpdateT = new ScenarioDetailSetJobCommitmentsAndPrioritiesT(a_sd.Scenario.Id, jobsList);
bulkUpdateT.DoNotSchedule = true;
AddTransmissionsToProcess(0, bulkUpdateT);

//Send optimize to reschedule original jobs
ScenarioDetailOptimizeT optimizeT = new ScenarioDetailOptimizeT(a_sd.Scenario.Id, true, false);
AddTransmissionsToProcess(1, optimizeT);

//Remove the Do Not Schedule flag from new MRP jobs
bulkUpdateT = new ScenarioDetailSetJobCommitmentsAndPrioritiesT(a_sd.Scenario.Id, jobsList);
bulkUpdateT.DoNotSchedule = false;
AddTransmissionsToProcess(2, bulkUpdateT);


Without the customization

Without the customization the MRP would run the optimize then automatically schedule the orders. As shown in the picture below after the MRP runs optimization all unscheduled jobs are then scheduled.    


With the customization

With the customization the MRP runs an optimization and at the end of the simulation any order that was not scheduled already gets held and remains unscheduled. 



Download Visual Studio project.

Download customization file for version 11.37.11.

Rename the sample scenario file to scenarios.dat when loading in PlanetTogether.

Download sample scenario.dat for version 11.39.