The idea is you convert everything you want to save into a deterministic set of integers. This conversion has to be invertible to a high accuracy meaning that from a deterministic set of integers you can reconstruct the player state. You then push the integer set through the save system to produce a code string. Loading you push the code through the save system to restore the deterministic set of integers which you then push through your inverse functions to restore the state.
For hero and item types you can use an array to preform the mapping. Each loadable type is added to the array at an index. To save you linear search through the array to find the index of the certain type that makes up the player state. The inverse is simply to return the type at the loaded index. Remember to bounds check against invalid numbers (do not bother trying to restore state with a type index that is not in the array).
Keep your state simple. Saving a hero, its exp, gold, lumber, 6 items and 1-2 quest state variables is simple and will result in a nice compact code. Saving 20 such heroes or attributes like current map position, current life/mana, current movement speed, currently active summons etc is complex and will result in a very long code, be prone to hacking abuse and possibly even bug with unloadable codes due to character limit.
When using a save system remember to change things like character maps it uses from the default values. This is to make hacking the map slightly harder (they cannot just use the same save system you used to generate a valid code, they need to use the one from your map to do it as the system becomes a black box).