diff --git a/src/cats/CMakeLists.txt b/src/cats/CMakeLists.txt
index a2c84bc7ae9ebf8a4bec0c5e1bc5476fe282d7f8..f55fd2d79f16213b2789123782a9011b39211692 100644
--- a/src/cats/CMakeLists.txt
+++ b/src/cats/CMakeLists.txt
@@ -39,7 +39,7 @@ include_directories(${GDAL_INCLUDE_DIR})
 include_directories(${GSL_INCLUDE_DIR})
 include_directories(${MPI_C_INCLUDE_PATH})
 
-add_library(libcats STATIC "" stats/statistics.c stats/statistics.h data/cats_global.c ../cats_windows.h test/test_ini.c test/test_ini.h debug/debug_vital_rates.c debug/debug_vital_rates.h)
+add_library(libcats STATIC "" stats/statistics.c stats/statistics.h data/cats_global.c ../cats_windows.h test/test_ini.c test/test_ini.h debug/debug_vital_rates.c debug/debug_vital_rates.h overlays/overlay_resources.c overlays/overlay_resources.h)
 target_include_directories(libcats PUBLIC ".")
 
 target_sources(libcats PRIVATE
diff --git a/src/cats/cats_global.h b/src/cats/cats_global.h
index 1795b433c170f28a84e05a22e432899d6dabe49f..cc7a794edd752308d9cc0cce1078686bcdc1b6a4 100644
--- a/src/cats/cats_global.h
+++ b/src/cats/cats_global.h
@@ -98,6 +98,9 @@ struct cats_debug_options {
         FILE *misc_debug_file; /// @brief global variable: file handle for a debug file documenting a single cells
 };
 
-
+static void abort_implemented(const char *name) {
+        fprintf(stderr, "function '%s' is not yet implemented\n", name);
+        exit_cats(EXIT_FAILURE);
+}
 
 #endif //CATS_GLOBAL_H_
diff --git a/src/cats/configuration/configuration.c b/src/cats/configuration/configuration.c
index 899d6f9e2302479a760da94fb77369028017a6f6..f066b481b4c813b788df1290e19de52257b823ee 100644
--- a/src/cats/configuration/configuration.c
+++ b/src/cats/configuration/configuration.c
@@ -79,6 +79,10 @@ void init_cats_configuration(struct cats_configuration *conf)
         conf->performance_file = NULL;
         conf->grid_count = 1;
 
+        conf->overlays.custom_overlay_count = 0;
+        conf->overlays.custom_overlays = NULL;
+        conf->overlays.registered_custom_overlay_names = new_string_array();
+
 
 #ifdef USEMPI
         conf->mpi.world_size = 1;
diff --git a/src/cats/configuration/load_configuration_overlays.c b/src/cats/configuration/load_configuration_overlays.c
index 074c1c9e5f51cc6a8cea1d85935aaa604f67eeb2..bbacc6f7e1b1828624bd3efdbb463d9cb2e68028 100644
--- a/src/cats/configuration/load_configuration_overlays.c
+++ b/src/cats/configuration/load_configuration_overlays.c
@@ -52,25 +52,34 @@ void load_overlay_configuration(struct cats_configuration *conf, struct cats_ini
                 char *type_name = NULL;
 
                 load_conf_value(true, ini, overlay_section, "type", &type_name);
-                enum overlay_type type = get_overlay_type_from_name(type_name);
-                free(type_name);
+                enum overlay_type type = get_overlay_type_from_name(type_name, conf->overlays.registered_custom_overlay_names);
+
+                struct cats_overlay *overlay = NULL;
+
+                if (type < OL_CUSTOM && type > OL_NONE) {
+                        overlay = &conf->overlays.overlay[type];
+                } else if (type == OL_CUSTOM) {
+                        overlay = add_overlay(conf, type_name);
+                }
 
-                conf->overlays.overlay[type].enabled = true;
 
 
-                load_conf_value(true, ini, overlay_section, "filename pattern", &conf->overlays.overlay[type].filename);
-                load_conf_value(false, ini, overlay_section, "reload interval", &conf->overlays.overlay[type].reload_interval);
+                overlay->enabled = true;
 
-                if (conf->overlays.overlay[type].reload_interval > 0) {
-                        conf->overlays.overlay[type].is_static = false;
+
+                load_conf_value(true, ini, overlay_section, "filename pattern", &overlay->filename);
+                load_conf_value(false, ini, overlay_section, "reload interval", &overlay->reload_interval);
+
+                if (overlay->reload_interval > 0) {
+                        overlay->is_static = false;
                 } else {
-                        conf->overlays.overlay[type].is_static = true;
+                        overlay->is_static = true;
                 }
 
                 conf->overlays.have_overlays = true;
 
                 long double default_value = NAN;
-                conf->overlays.overlay[type].name = strdup(overlay_name);
+                overlay->name = strdup(overlay_name);
 
                 switch (type) {
                         case OL_EXCLUSION:
@@ -78,18 +87,21 @@ void load_overlay_configuration(struct cats_configuration *conf, struct cats_ini
                         case OL_HABITAT_TYPE_CC:
 
                                 load_conf_value(true, ini, overlay_section, "table filename",
-                                                &conf->overlays.overlay[type].filename_aux);
+                                                &overlay->filename_aux);
                                 load_conf_value(true, ini, overlay_section, "default value", &default_value);
-                                conf->overlays.overlay[type].aux_data = load_habitat_layer_cc_aux(
-                                        conf->overlays.overlay[type].filename_aux,
+                                overlay->aux_data = load_habitat_layer_cc_aux(
+                                        overlay->filename_aux,
                                         (double) default_value);
                                 break;
+                        case OL_RESOURCE:
+                                break;
                         case OL_NONE:
                         case OL_MAX:
-                        default:
+                        case OL_CUSTOM:
                                 log_message(LOG_ERROR, "unknown or unhandled overlay type '%s'", overlay_name);
                                 exit(EXIT_FAILURE);
                 }
+                free(type_name);
         }
 
         free_string_array(&overlay_names);
diff --git a/src/cats/overlays/overlay_resources.c b/src/cats/overlays/overlay_resources.c
new file mode 100644
index 0000000000000000000000000000000000000000..744523a07b5ef6f130e51c7eaf7b7fc9de3272db
--- /dev/null
+++ b/src/cats/overlays/overlay_resources.c
@@ -0,0 +1,34 @@
+//
+// Created by andreas on 08/02/23.
+//
+
+#include <assert.h>
+#include <math.h>
+#include "overlay_resources.h"
+#include "memory/arrays.h"
+
+
+struct cats_2d_array_double *translate_resources(const struct cats_2d_array_double *data)
+{
+        struct cats_2d_array_double *result = new_2d_array_double(data->dimension);
+
+        const cats_dt_coord rows = data->dimension.rows;
+        const cats_dt_coord cols = data->dimension.cols;
+
+        for (cats_dt_coord row = 0; row < rows; row++) {
+                for (cats_dt_coord col = 0; col < cols; col++) {
+
+                        double value = data->data[row][col];
+
+                        if (isnan(value)) {
+                                result->data[row][col] = 0.0;
+                        } else {
+
+                                if (value <0 ) value = 0;
+                                result->data[row][col] = value;
+                        }
+                }
+        }
+
+        return result;
+}
diff --git a/src/cats/overlays/overlay_resources.h b/src/cats/overlays/overlay_resources.h
new file mode 100644
index 0000000000000000000000000000000000000000..012b5acdd11a3310cad339e5a391010d71be8a93
--- /dev/null
+++ b/src/cats/overlays/overlay_resources.h
@@ -0,0 +1,8 @@
+//
+// Created by andreas on 08/02/23.
+//
+
+#ifndef CATS_OVERLAY_RESOURCES_H
+#define CATS_OVERLAY_RESOURCES_H
+struct cats_2d_array_double *translate_resources(const struct cats_2d_array_double *data);
+#endif //CATS_OVERLAY_RESOURCES_H
diff --git a/src/cats/overlays/overlays.c b/src/cats/overlays/overlays.c
index d2e035b146dc762647d91a9adfd47a9dac6882bc..cb5ef96f13088f8a46131e921e17553613793603 100644
--- a/src/cats/overlays/overlays.c
+++ b/src/cats/overlays/overlays.c
@@ -33,6 +33,7 @@
 #include "grids/cats_grid.h"
 #include "overlay_habitat_type_cc.h"
 #include "overlay_exclusion.h"
+#include "overlay_resources.h"
 
 
 const char *get_overlay_name(enum overlay_type type)
@@ -42,10 +43,12 @@ const char *get_overlay_name(enum overlay_type type)
                         return "exclusion";
                 case OL_HABITAT_TYPE_CC:
                         return "habitat_type_cc";
-
+                case OL_RESOURCE:
+                        return "resources";
+                        break;
                 case OL_NONE:
                 case OL_MAX:
-                default:
+                case OL_CUSTOM:
                         break;
         }
 
@@ -74,14 +77,30 @@ void cleanup_overlays(struct cats_overlays *overlays)
 
 }
 
+struct cats_overlay *add_overlay(struct cats_configuration *conf, const char *name)
+{
+        struct cats_overlay *overlay = NULL;
+        abort_implemented(__func__);
+        return overlay;
+
+}
+
 
-enum overlay_type get_overlay_type_from_name(const char *name)
+enum overlay_type get_overlay_type_from_name(const char *name, const struct string_array *registered_names)
 {
         if (!name) return OL_NONE;
 
         if (!strcmp(name, "exclusion")) return OL_EXCLUSION;
         if (!strcmp(name, "habitat carrying capacity")) return OL_HABITAT_TYPE_CC;
 
+        if (registered_names != NULL) {
+                for (int32_t i = 0; i < registered_names->count; i++) {
+                        if (!strcmp(name, registered_names->string[i])) {
+                                return OL_CUSTOM;
+                        }
+                }
+        }
+
         log_message(LOG_ERROR, "%s: unknown overlay type '%s'", __func__, name);
         exit(EXIT_FAILURE);
 }
@@ -138,9 +157,15 @@ void load_overlay_from_file(struct cats_configuration *conf, enum overlay_type t
                 case OL_CUSTOM:
                         log_message(LOG_ERROR, "OL_CUSTOM not implemented yet");
                         exit(EXIT_FAILURE);
+                case OL_RESOURCE:
+                        if (conf->overlays.resources) free_cats_grid(&conf->overlays.resources);
+                        conf->overlays.resources = translate_resources(raw_values);
+                        break;
+
                 case OL_NONE:
                 case OL_MAX:
                         break;
+
         }
 
         free_cats_grid(&raw_values);
diff --git a/src/cats/overlays/overlays.h b/src/cats/overlays/overlays.h
index e3dc83fb8236d51c47128606117498f7b65e19d7..cc1f4a8fffa366c36dde9395bb9a2cbf94da9ed9 100644
--- a/src/cats/overlays/overlays.h
+++ b/src/cats/overlays/overlays.h
@@ -36,7 +36,8 @@ enum overlay_type {
         OL_NONE = 0,
         OL_EXCLUSION = 1,
         OL_HABITAT_TYPE_CC = 2,
-        OL_CUSTOM = 3,
+        OL_RESOURCE = 3,
+        OL_CUSTOM = 4,
         OL_MAX
 };
 
@@ -58,8 +59,8 @@ struct cats_overlay {
     char *filename_loaded;
     void *aux_data;
 
-
-
+    struct cats_2d_array_char *data_char;
+    struct cats_2d_array_double *data_double;
 
     cats_dt_coord cols; ///< number of rows    (same as grid, for convenience only)
     cats_dt_coord rows; ///< number of columns (same as grid, for convenience only)
@@ -74,19 +75,15 @@ struct cats_overlays {
 
         bool have_overlays;                ///< do we actually have overlays? True if at least one overlay is enabled.
         struct cats_overlay overlay[OL_MAX];
-        /*
-        bool enabled[OL_MAX];              ///< which of the overlay types are enabled?
-        bool is_static[OL_MAX];            ///< do the overlays remain constant over time?
-        int32_t reload_interval[OL_MAX];  ///< how often do overlays change?
-
-        char *name[OL_MAX];                ///< overlay names (as specified in the configuration file)
-        char *filename[OL_MAX];            ///< overlay filenames or filename patterns
-        char *filename_aux[OL_MAX];
-        char *filename_loaded[OL_MAX];
-        void *aux_data[OL_MAX];
-        */
+
         struct cats_2d_array_char *exclusion;
         struct cats_2d_array_double *habitat_cc;
+        struct cats_2d_array_double *resources;
+
+        struct cast_overlay *custom_overlays;
+        int32_t custom_overlay_count;
+
+        struct string_array *registered_custom_overlay_names;
 
         cats_dt_coord cols; ///< number of rows    (same as grid, for convenience only)
         cats_dt_coord rows; ///< number of columns (same as grid, for convenience only)
@@ -97,7 +94,7 @@ void cleanup_overlays(struct cats_overlays *overlays);
 
 const char *get_overlay_name(enum overlay_type type);
 
-enum overlay_type get_overlay_type_from_name(const char *name);
+enum overlay_type get_overlay_type_from_name(const char *name, const struct string_array *registered_names);
 
 
 bool
@@ -106,5 +103,5 @@ update_overlay_if_needed(struct cats_configuration *conf, int32_t time, enum ove
 void reset_overlay(struct cats_overlays *overlay);
 
 void load_overlay_from_file(struct cats_configuration *conf, enum overlay_type type, char *filename);
-
+struct cats_overlay *add_overlay(struct cats_configuration *conf, const char *name);
 #endif
\ No newline at end of file
diff --git a/src/modules/butterflies/butterflies_inline.h b/src/modules/butterflies/butterflies_inline.h
new file mode 100644
index 0000000000000000000000000000000000000000..e13772480fe6c716b8c39e90222e699118424016
--- /dev/null
+++ b/src/modules/butterflies/butterflies_inline.h
@@ -0,0 +1,8 @@
+//
+// Created by andreas on 08/02/23.
+//
+
+#ifndef CATS_BUTTERFLIES_INLINE_H
+#define CATS_BUTTERFLIES_INLINE_H
+
+#endif //CATS_BUTTERFLIES_INLINE_H