> For the complete documentation index, see [llms.txt](https://doc.hfsm.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.hfsm.dev/user-guide/debugging-and-tools/serialization.md).

# Serialization \*

## Quick Facts

* Version: [1.3](https://github.com/andrew-gresyk/HFSM2/releases/tag/1_3)
* Enabled with `HFSM_ENABLE_SERIALIZATION`
* Test: [test\_serialization.cpp](https://github.com/andrew-gresyk/HFSM2/blob/master/test/test_serialization.cpp)

## Interface

|                                          |                                                   |
| ---------------------------------------- | ------------------------------------------------- |
| `hfsm2::Root::SerialBuffer`              | Buffer for serialization                          |
| `hfsm2::Root::save(SerialBuffer&) const` | Serialize the structural configuration            |
| `hfsm2::Root::load(const SerialBuffer&)` | De-serialize the configuration and initialize FSM |

## Example

```
// Enable serialization
#define HFSM_ENABLE_SERIALIZATION

#include <hfsm2/machine.hpp>
#include <assert.h>

using M = hfsm2::Machine;

using FSM = M::PeerRoot<
                struct State1,
                struct State2
            >;

struct State1 : FSM::State { /* .. */ };
struct State2 : FSM::State { /* .. */ };

int main() {
    // Buffer for serialization
    //  Members:
    //   bitSize - Number of payload bits used
    //   payload - Serialized data
    FSM::Instance::SerialBuffer buffer;

    {
       FSM::Instance fsm;              // Create a new FSM instance
       fsm.changeTo<State2>();         // Request a transition to 'State2'
       fsm.update();                   // Process transitions
       assert(fsm.isActive<State2>()); // Check if transition completed

       fsm.save(buffer);               // Serialize FSM configuration into 'buffer'
    }
    
    {
       FSM::Instance fsm;              // Create a fresh FSM instance
       assert(fsm.isActive<State1>()); // Initial 'State1' is activated by default

       fsm.load(buffer);               // De-serialize FSM from 'buffer'
       assert(fsm.isActive<State2>()); // Check its configuration is restored
    }
}
```

## Serialization Between Different FSMs

As demonstrated in [test\_serialization.cpp](https://github.com/andrew-gresyk/HFSM2/blob/master/test/test_serialization.cpp), it is allowed to exchange the `SerialBuffer` between **different FSMs**, so long as their hierarchical **structure** is exactly **the same**.

This can be useful for **network replication** between structurally equivalent server and client FSM instances implementing some specific logic.

## SerialBuffer Size and Compression

[HFSM2](https://hfsm.dev/) does not compress `SerialBuffer`.

However, the configuration data saved to `SerialBuffer::payload` is **tightly packed** to use the **minimal** number of **bits**.

The number of **bits used** in the payload is recorded in `SerialBuffer::bitSize`,  which could be used for example in custom network replication logic to minimize network bandwidth usage.

Compressing `SerialBuffer` can also be used to further reduce the size serialized state.
