Skip to content

State Management

Vadim Gromov edited this page Mar 5, 2021 · 7 revisions

Zara supports saving and restoring engine state. It will restore all its internal nodes, but some, more abstract entities, you must save and load yourself. Zara supports saving and loading of these nodes without any additional actions:

Game time
Player state
Weather state
Health vitals
Clothes
Body appliances
Weight of the inventory
Medical agents

Zara will not save inventory items.
Basically, to save the whole state, you need to:

  • Get the core Zara state
  • Save your inventory items separately
  • Save active diseases and injuries separately (see below)
  • Save your disease monitors, inventory monitors and side effects monitors separately (see below)

Saving and restoring core Zara state

To get the core state, call

let state = person.get_state();

This will return ZaraControllerStateContract.
To restore this state, call

person.restore_state(state);

Saving and restoring diseases and injuries

These objects must be stored separately. To save the state of active diseases, you should do something like

for (key, disease) in person.health.diseases.borrow().iter() {
    self.diseases.insert(key.clone(), disease.get_state());
}

Where self.diseases is a collection that will hold these states (ActiveDiseaseStateContract).
Same with injuries:

for (key, injury) in person.health.injuries.borrow().iter() {
    self.injuries.insert(key.clone(), injury.get_state());
}

In order to restore diseases and injuries, you may want to first clear the current ones

// Clear diseases
person.health.clear_diseases();

// Clear injuries
person.health.clear_injuries();

And then restore them one by one. Here you need to provide state you captured before, and disease/injury instance associated with this state. Your disease/injury instance can hold some internal fields, or your custom treatment state data, so here you need to save and load your disease/injury objects according to your needs.

// Restore diseases
for (_, state) in &self.diseases {
    // ... get the associated disease instance, then restore the state:
    person.health.restore_disease(state, disease);
}

// Restore injuries
for (_, state) in &self.injuries {
    // ... get the associated injury instance, then restore the state:
    person.health.restore_injury(state, injury);
}

If your disease/injury struct not holding any crucial data that needs to be saved, you can pass a new disease/injury instance here.

Saving and restoring everything else

Every disease, injury, disease monitor, inventory monitor, inventory item and side effects monitor has as_any function that allows you to downcast their instances from traits to their actual types, so you can access their custom methods to get and restore their state.

All built-in side effects for example have those methods, and can be easily saved and loaded:

let monitors = person.health.side_effects.borrow();

// Get monitor state
self.monitor_fatigue_state = match &self.monitor_fatigue {
    Some(mid) => match monitors.get(mid) {
        Some(m) => match m.as_any().downcast_ref::<FatigueSideEffects>() {
            Some(o) => Some(o.get_state()),
            None => None
        }
        None => None
    },
    None => None
};

// Restore monitor state
if let Some(st) = &self.monitor_fatigue_state {
    if let Some(mid) = &self.monitor_fatigue {
        if let Some(m) = monitors.get(mid) {
            if let Some(o) = m.as_any().downcast_ref::<FatigueSideEffects>() {
                o.restore_state(st)
            }
        }
    }    
}

Where mid is an id of the registered monitor instance.