diff --git a/example/properties.txt b/example/properties.txt
index c6fc53f960f0ca0cd98c2e60d723c85d88b96e3b..e8e125759b4841d0a9d8c8774ddd0e2ed6996e91 100644
--- a/example/properties.txt
+++ b/example/properties.txt
@@ -164,8 +164,8 @@
 			}
 		},
 
-		"icon": {
-			"A0": {
+		"graphics": {
+			"icon": {
 				"overwrite_sprite_size": [16, 16],
 				"overwrite_layer_step_size": [1, 1],
 				"layers": [[10, 778]]
diff --git a/src/main.c b/src/main.c
index a6d8c51860d145c69dabfdd28497065a4ffdbf4f..b51cdc8ec6bd8c3b9966a527bad41c5e906b54cc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -33,6 +33,7 @@
 // If your sprites are bigger than 256*256, consider a different approach than this program?
 #define MAX_IMAGE_SIZE 256*256
 
+// it's only a snippet, the whole thing can't be a macro since it's variable now
 #define FOLLOWER_SOC_SNIPPET_TEMPLATE "Name = %s\nIcon = %s\nCategory = %s\nHornSound = %s\nStartColor = %d\nDefaultColor = %s\nMode = %s\nScale = %d*FRACUNIT\nBubbleScale = %d*FRACUNIT\nAtAngle = %d\nHorzLag = %d*FRACUNIT\nVertLag = %d*FRACUNIT\nAngleLag = %d*FRACUNIT\nBobSpeed = %d*FRACUNIT\nBobAmp = %d*FRACUNIT\nZOffs = %d*FRACUNIT\nDistance = %d*FRACUNIT\nHeight = %d*FRACUNIT\nHitConfirmTime = TICRATE*%d\n"
 
 #define FOLLOWERNAMESIZE 16
@@ -52,12 +53,13 @@ struct RGB_Sprite {
 	struct RGB_Sprite* next;
 };
 
+// struct for follower data included in the SOC
 struct followerstructthingwhatever {
 	char name[FOLLOWERNAMESIZE];
 	char category[FOLLOWERNAMESIZE]; // maybe follows the name size as well?
 	uint8_t startcolor;
 	char prefcolor[32];
-	uint8_t mode; // if float or ground
+	uint8_t mode; // if floating or on ground
 	char scale;
 	char scale;
 	short atangle;
@@ -141,6 +143,7 @@ void readTransparentColors(void) {
 	printf("Done.\n");
 }
 
+// sets placeholder follower values, to be replaced by the user's own input
 void SetDefaultFollowerValues(void)
 {
 	strncpy(kfollower.name, "someone", 8);
@@ -154,7 +157,7 @@ void SetDefaultFollowerValues(void)
 	strncpy(kfollower.prefcolor, "Green", 6);
 	kfollower.prefcolor[6] = '\0';
 
-	kfollower.mode = 0; //float
+	kfollower.mode = 0; // floating
 	kfollower.scale = 1;
 	kfollower.bubblescale = 0;
 	kfollower.atangle = 230;
@@ -169,13 +172,29 @@ void SetDefaultFollowerValues(void)
 	kfollower.hitconfirmtime = 1;
 }
 
-
+// processes sprites on the template, which are separated by regions (usually visualized on the template image as squares)
 void processSprites(void) {
+	// properties.txt fields, read as json
 	cJSON *item, *nesteditem, *prop;
+
+	// sprite-related
 	int spr_width, spr_height, step_width, step_height, stepw, steph;
 	struct RGB_Sprite* cursprite;
+
+	// to do with automating animation frame order indices
+	char highestanimframeletter = 0;
+	uint8_t curstate, laststate = IDLE;
+
+	// prefix for follower files
 	char prefix[5] = "____";
 
+	// set prefix
+	item = cJSON_GetObjectItem(metadata, "prefix");
+	if (item)
+		strncpy(prefix, item->valuestring, 4);
+	else
+		strncpy(prefix, defprefix, 4);
+
 	// Read sprite size
 	printf("Read sprite size... ");
 	item = cJSON_GetObjectItem(metadata, "sprite_size")->child;
@@ -197,8 +216,12 @@ void processSprites(void) {
 	item = cJSON_GetObjectItem(metadata, "sprites")->child;
 
 	while (item != NULL) {
-		printf("Reading SPR2_%s... \n", item->string);
-		strncpy(prefix, item->string, 4);
+		// keep track of follower state which sprites are being read
+		// "idle" is the first follower state, the rest of which follow it (pun unintended)
+		// the "graphics" field is for the follower's icon on the menu
+		// mainly used for ordering animation frames as seen below
+		if (item->string != "idle" && item->string != "graphics") curstate++;
+
 		nesteditem = item->child;
 
 		while (nesteditem != NULL) {
@@ -235,7 +258,19 @@ void processSprites(void) {
 				steph = step_height;
 			}
 
-			sprintf(cursprite->lumpname, "%s%s", prefix, nesteditem->string);
+			// handle automatic animation frame ordering
+			// animation frames of sprites use a letter-based ordering, from A to Z
+			// the idea is to be able to detect the highest letter used for an animation frame within a follower state and go above it upon reading sprites for the next state
+			if (item->string != "graphics")
+			{
+				if (curstate > laststate && nesteditem->string[0] != "Z") nesteditem->string[0] = highestanimframeletter + (nesteditem->string[0]+1 - "A");
+
+				// this will store how many frames of animation are in the sprite for all of the follower states
+				if (nesteditem->string[0] > highestanimframeletter) highestanimframeletter = nesteditem->string[0];
+			}
+
+			if (item->string != "graphics") sprintf(cursprite->lumpname, "%s%s", prefix, nesteditem->string);
+			else                            sprintf(cursprite->lumpname, "ICOF%s", prefix);
 
 			prop = cJSON_GetObjectItem(nesteditem, "heightfactor");
 			cursprite->heightFactor = prop != NULL ? prop->valueint : 1;
@@ -275,6 +310,7 @@ void processSprites(void) {
 			nesteditem = nesteditem->next;
 		}
 		item = item->next;
+		laststate = curstate;
 	}
 
 	printf("Reading sprites... Done.\n");