Model Variants for Decorations

Oh no, I was not referring to your English, pingu - it’s just my brain that’s a bit slow and I have an easier time to follow along when presented something graphically :slight_smile:

It sounds like you have a “pick a random model” option set on the ghost entity itself - and of course this is the case; this is where you (and I) were suggested to put it! :smiley:
The current issue is that this “random selection” occurs upon the creation of the ghost item; it has to “remember” it’s already picked state (which it already should).

I have not started working with these “random selections” myself yet; but I’ll try to get to it as soon as I can in order to see if I can recreate your issue and hopefully find a solution :slight_smile:

1 Like

yes exactly! :smiley:

you have to insert a “remember-code” for the ghost item. It’s not so a big deal to see every time another model but it would be nice to see the right one :wink:

let me know when you find a solutions. i tried it myself and tell you too if i find one

1 Like

Sounds great! I’ve been able to get some modding-time on my hands; and, I’ve been able to reproduce your issue! I may also know how to fix it… sort of.

An entity like a berry bush has two modes: default and depleated. Likewise, your models could have default and defined. I’m asuming/guessing that for a berry bush the switch between depleated and default is handled by the harvest-command itself; in your case, you would have to switch the mode to defined once the ghost-entity has been created.

I’m a complete json-beginner, and thus I do not know yet how to set up the switch between states.

EDIT: Oh, and of course we also need to store variables that holds the models selected upon the creation of the very ghost-entity!
These variables should then be used instead of “file()”-calls found in the default-branch.

Ohh ok sounds really complicate :open_mouth:
Maybe your knowledge is mor advanced than mine to solve it. I can take a look how the berry bushes handle it :frowning:

Don’t get discouraged - I’m sure it’s not as complicated as I make it sound; all we have to do is practice and I’m sure it will be done in a jiffy :wink:

I have no more time to put into this today; but I shall contine tomorrow or the day after that (unless a solution has already been found by then). Best of luck until then! :slight_smile:

1 Like

never give up hhhh ^^

We will find a solution for this :wink:

Yes, the ghost is a random, and the placed can be another random. And the iconic can be another one too.
I have this problem with my starfish. They have 3 random colors, sometimes the iconic is blue, the ghost is pink and the placed is yellow :stuck_out_tongue:
The game remembers which model it used (so if you change its place it is still the same), but it does not necessarily matches with other modes like the ghost version.

Bruno, am I understanding it correctly if I read your reply as “the ghost model will always be e.g. red for one specific entity”?
Or, will the ghost model always be randomized? (For one specific entity, the ghost model is blue one time but red the next)

If the latter is the case, I feel like there really should be a work-around to this issue :slight_smile:
If no one can prove me wrong until the next time I got more spare-time on my hands, I shall continue my quest to find a solution ^^

1 Like

Uhm sorry.
I tested on my starfish and the same object had a different random ghost everytime I moved it. The main placed item maintain the same color, but I guess the ghost is newly created when you move it.

I talked about this issue with one of the developer a few months ago, but she is not on the team anymore. In my case it didn’t matter so I never bothered. I’m not sure if there is a way to fix this.

1 Like

A solution for the furniture, could be for the ghost to always use a single default variant, while the actual item could be any of the combinations.

Also, in regards to the chairs all being different colours, as I believe Bruno suggested here…

… then you could always just use the same colours or quite similar colours, while altering the models. This way there’d still be some sense of uniformity and reliability in what product you get, but it’d not feel like clinical repetition.

Unfortunately i think it’s not so easy to make this. My tentatives failed :smiley:

I was able to have a 2nd go at implementing this code myself. Prior to this, I had a bit of thinking on the problem itself.
I assume/guess that my previous suggestion (store model-info in the Ghost Entity) is simply not possible. The Ghost Entity is always created and destroyed upon moving items around - so even if you provide memory, this memory will be cleared out.

Instead, I figured that it’s better to put the randomization in the Entity itself, and a specific model for the Ghost Entity. (similar to how ST34LTH suggested, really).
Now:

  • Each Entity model is randomized upon its creation, and the selected model will remain after being replaced somewhere else.
  • All Ghost Entities use the “standard model”.

I hope the users don’t mind it too much - at least it’s better than having the Ghost Entity looking random each time, too.

1 Like

Sounds interesting. You already tried if it works?

Oh sorry! Yes, indeed I have :slight_smile:
I will provide code example below.

Ghost Entity

Under model_variants, put only “standard models” in the json-file of the Ghost Entity.

      "model_variants": {
         "default": {
            "models": [
               "file(model1_left.qb)",
	           "file(model1_center.qb)",
		       "file(model1_right.qb)"
            ]
         }
      },

I don’t expect you to have to change anything else in your Ghost Entity .json-file.

Regular Entity

In the .json-file of your Entity, however, more changes are required.
First, remove your “mixins” of the ghost .json-file; also add all your model variations here.

"type": "entity",
   "mixins": "stonehearth:mixins:placed_object",
   "components": {
      "model_variants": {
         "default": {
            "models": [
			   {
			   "type": "one_of",
			   "items": [
                  "file(model1_left.qb)",
				  "file(model2_left.qb)"
			   ]
			   },
			   {
			   "type": "one_of",
			   "items": [
                  "file(model1_center.qb)",
				  "file(model2_center.qb)"
			   ]
			   },
			   {
			   "type": "one_of",
			   "items": [
                  "file(model1_right.qb)",
				  "file(model2_right.qb)"
			   ]
			   },
            ]
         }
	   },
	  "stonehearth:entity_forms": {
         "iconic_form": "file(iconic.json)",
         "ghost_form": "file(ghost.json)",
         "placeable_on_ground": true
      },

Now, also add your information for the following sections (some example data are provided, too):

 "render_info": {
    				"scale": YOUR_SCALE
          },
    	  "mob": {
             "model_origin": { "x": X, "y": Y, "z": Z },
             "region_origin": { "x": X, "y": Y, "z": Z }
          },
          "region_collision_shape": {
             "region": [
                {
                   "min": { "x": X, "y": Y, "z": Z },
                   "max": { "x": X, "y": Y, "z": Z }
                }
             ]
          }
       },
       "entity_data": {
          "stonehearth:catalog": {
             "display_name": "Displayed Name of Entity",
             "description": "Description of Entity",
             "icon": "file(icon.png)",
             "category": "furniture",
             "material_tags": "stone furniture stockpile_decoration"
          },
          "stonehearth:net_worth": {
             "value_in_gold": 0,
             "rarity": "common",
             "shop_info": {
                "buyable": false,
                "sellable": false
             }
          },
          "stonehearth:item": {
             "clearable": true
          }
       }
    }

A lot of the data in this section is “copy-paste” data from data already stored in your Ghost Entity .json-file.
Seeing how we removed the mixin of the ghost data, we will have to enter it in this file, too.

This is what I did, and it works great for me. If anything is unclear, feel free to ask :slight_smile:

1 Like

Ohh wow i’m just excited to see how it works!!!
Can’t wait to try it at home. You are the best @Hamnisu :grimacing:

1 Like

Any time, @pingu! I hope it works well for you, too.
Get back to me later regarding your progress :slight_smile:

I tried to make a single ghost file for one of my models (herbalist library) but it seems there is a big bug. And i really can’t understand where is this error. Also validate the json file and everything seems ok. But when im starting the game this error message appears

release-753 (x64)[M]
c++ exception: Error reading file homesweethome/entities/furniture/shelf_herbalist_library/shelf_herbalist_library.json: Unterminated quote Source: {
 "type": "entity",
 "mixins": "stonehearth:mixins:placed_object",
 "components": {
 
 "model_variants": {
 "default": {
 "models": [
 "file(../shelf/shelf.qb)"
 {
 "type": "one_of",
 "items": [
 "file(shelf_herbalist_library1.qb)",
 "file(shelf_herbalist_library2.qb)",
 "file(shelf_herbalist_library3.qb)",
 "file(shelf_herbalist_library4.qb)",
 "file(shelf_herbalist_library5.qb)"
 ]
 }
 ]
 }
 },
 
 "stonehearth:entity_forms": {
 "iconic_form": "file(shelf_herbalist_library_iconic.json)",
 "ghost_form": "file(shelf_herbalist_library_ghost.json)",
 "placeable_on_ground": true
 },
 
 "render_info": {
 "mob": {
 "model_origin": { "x": -0.5, "y": 0, "z": 0.3 },
 "region_origin": { "x": 0.05, "y": 0, "z": 0.05 }
 },
 "region_collision_shape": {
 "region": [
 {
 "min": { "x": -1, "y": 0, "z": -0.6 },
 "max": { "x": 3, "y": 5, "z": 1 }
 }
 ]
 }
 }
 },
 "entity_data": {
 "stonehearth:catalog": {
 "display_name": "i18n(homesweethome:entities.furniture.shelf_herbalist_library_ghost.display_name)",
 "description": "i18n(homesweethome:entities.furniture.shelf_herbalist_library_ghost.description)",
 "icon": "file(shelf_herbalist_library.png)",
 "category": "furniture",
 "material_tags": "wood furniture crafted crate stockpile_furniture"
 },
 
 "stonehearth:net_worth": {
 "value_in_gold": 14,
 "rarity": "common",
 "shop_info": {
 "buyable": false,
 "sellable": true,
 "shopkeeper_level": 1,
 "shopkeeper_type": "caravan"
 }
 }
 }
 }
stack traceback:
	[C]: in function 'load_json'
	radiant/modules/resources.lua:33: in function 'load_json'
	...nehearth/services/server/catalog/catalog_service.lua:130: in function '_load_json'
	...nehearth/services/server/catalog/catalog_service.lua:136: in function '_load_entity_json'
	...nehearth/services/server/catalog/catalog_service.lua:111: in function '_load_catalog'
	...nehearth/services/server/catalog/catalog_service.lua:37: in function 'initialize'
	stonehearth/stonehearth_server.lua:76: in function 'create_service'
	stonehearth/stonehearth_server.lua:130: in function 'instance'
	radiant/modules/events.lua:291: in function <radiant/modules/events.lua:285>
	[C]: in function 'xpcall'
	radiant/modules/common.lua:265: in function 'xpcall'
	radiant/modules/events.lua:285: in function <radiant/modules/events.lua:251>

I think you are missing a comma at the end of
"file(…/shelf/shelf.qb)",

Just check with https://jsonlint.com/

Hello pingu!

I think Bruno is on to something when saying this:

Other than that, it all looks good to me.
Please get back to me (us? ^^) if you still run into problems after adding the comma :slight_smile:

Mah maybe i do something wrong. i validate the json and everything seems working right. Now it’s working. Or let me say its working a little bit better but it seems there are problems with the ghost and normal entities.

I put the code of the two files here maybe you have better eyes than me :confused:

JSON file

{
   "type": "entity",
   "mixins": "stonehearth:mixins:placed_object",
   "components": {
      "stonehearth:entity_forms": {
         "iconic_form": "file(shelf_herbalist_library_iconic.json)",
         "ghost_form": "file(shelf_herbalist_library_ghost.json)",
         "placeable_on_ground": true
      },

      "model_variants": {
  			 "default": {
  					"models": [
  						"file(../shelf/shelf.qb)",
  						 {
  								"type": "one_of",
  								"items": [
  									 "file(/shelf_herbalist_library1.qb)",
  									 "file(shelf_herbalist_library2.qb)",
  									 "file(shelf_herbalist_library3.qb)",
  									 "file(shelf_herbalist_library4.qb)",
  									 "file(shelf_herbalist_library5.qb)"
  								]
  						 }
  					]
  			 }
  		},

      "mob": {
         "model_origin": { "x": -0.5, "y": 0, "z": 0.3 },
         "region_origin": { "x": 0.05, "y": 0, "z": 0.05 }
			},

     "region_collision_shape": {
        "region": [
           {
              "min": { "x": -1, "y": 0, "z": -0.6 },
              "max": { "x": 3, "y": 5, "z": 1 }
           }
        ]
      }
   },

   "entity_data": {

     "stonehearth:catalog": {
       "display_name": "i18n(homesweethome:entities.furniture.shelf_herbalist_library_ghost.display_name)",
       "description": "i18n(homesweethome:entities.furniture.shelf_herbalist_library_ghost.description)",
       "icon": "file(shelf_herbalist_library.png)",
       "category": "furniture",
       "material_tags": "wood furniture crafted crate stockpile_furniture"
   },

      "stonehearth:net_worth": {
         "value_in_gold": 14,
         "rarity": "common",
         "shop_info": {
            "buyable": false,
            "sellable": true,
            "shopkeeper_level": 1,
            "shopkeeper_type": "caravan"
         }
      }
   }
}

GHOST file

{
	"mixins": "stonehearth:mixins:placed_object",
	"components": {
		"model_variants": {
			 "default": {
					"models": [
						"file(../shelf/shelf.qb)",
						"file(shelf_herbalist_library1.qb)"
					]
			 }
		},

      "mob": {
         "model_origin": { "x": -0.5, "y": 0, "z": 0.3 },
         "region_origin": { "x": 0.05, "y": 0, "z": 0.05 }
			}
		},

		"entity_data": {
			"stonehearth:catalog": {
				"display_name": "i18n(homesweethome:entities.furniture.shelf_herbalist_library_ghost.display_name)",
				"description": "i18n(homesweethome:entities.furniture.shelf_herbalist_library_ghost.description)",
				"icon": "file(shelf_herbalist_library.png)",
				"category": "furniture",
				"material_tags": "wood furniture crafted crate stockpile_furniture"
		}
	}
}