# .do_save is set on handler by Quest if it wants to save progress
self._save()
```
The handler is just a normal Python class and has no database-storage on its own. But it has a link
to `.obj`, which is assumed to be a full typeclased entity, on which we can create
persistent [Attributes](../Components/Attributes.md) to store things however we like!
We make two helper methods `_load` and
`_save` that handles local fetches and saves `storage` to an Attribute on the object. To avoid
saving more than necessary, we have a property `do_save`. This we will set in `Quest` below.
> Note that once we `_save` the data, we need to call `_load` again. This is to make sure the version we store on the handler is properly de-serialized. If you get an error about data being `bytes`, you probably missed this step.
### Make quests storable
The handler will save all `Quest` objects as a `dict` in an Attribute on `obj`. We are not done yet
though, the `Quest` object needs access to the `obj` too - not only will this is important to figure
out if the quest is complete (the `Quest` must be able to check the quester's inventory to see if
they have the red key, for example), it also allows the `Quest` to tell the handler when its state
changed and it should be saved.
We change the `Quest` such:
```python
from evennia.utils import dbserialize
class Quest:
def __init__(self, obj):
self.obj = obj
self._current_step = "start"
def __serialize_dbobjs__(self):
self.obj = dbserialize.dbserialize(self.obj)
def __deserialize_dbobjs__(self):
if isinstance(self.obj, bytes):
self.obj = dbserialize.dbunserialize(self.obj)
@property
def questhandler(self):
return self.obj.quests
@property
def current_step(self):
return self._current_step
@current_step.setter
def current_step(self, value):
self._current_step = value
self.questhandler.do_save = True # this triggers save in handler!
# [same as before]
```
The `Quest.__init__` now takes `obj` as argument, to match what we pass to it in
`QuestHandler.add`. We want to monitor the changing of `current_step`, so we
make it into a `property`. When we edit that value, we set the `do_save` flag on
the handler, which means it will save the status to database once it has checked
progress on all its quests. The `Quest.questhandler` property allows to easily
get back to the handler (and the object on which it sits).
The `__serialize__dbobjs__` and `__deserialize_dbobjs__` methods are needed
because `Attributes` can't store 'hidden' database objects (the `Quest.obj`
property. The methods help Evennia serialize/deserialize `Quest` propertly when
the handler saves it. For more information, see [Storing Single
objects](../Components/Attributes.md#storing-single-objects) in the Attributes
### Tying it all together
The final thing we need to do is to add the quest-handler to the character:
```python
# in mygame/typeclasses/characters.py
from evennia import DefaultCharacter
from evennia.utils.utils import lazy_property
from .world.quests import QuestHandler # as an example
class Character(DefaultCharacter):
# ...
@lazy_property
def quests(self):
return QuestHandler(self)
```
You can now make your Quest classes to describe your quests and add them to
characters with
```python
character.quests.add(FindTheRedKey)
```
and can later do
```python
character.quests.check_progress()
```
and be sure that quest data is not lost between reloads.
You can find a full-fledged quest-handler example as [EvAdventure
quests](evennia.contrib.tutorials.evadventure.quests) contrib in the Evennia