RP and RepeatPan's mods

umm… nice! and here I am, stuck at the in laws, with no way to play with these new toys!

Eh, it seems like interest for mods has died down anyway.

nah, i think most folks just arent as bleeding edge as the few who’ve taken up the torch (and dont want to dissect code to figure out how to mod)…

once the developer tools are in place, i guarantee we’ll see a flood of new content…

1 Like

I don’t know, even with the documentation and samples in place it’s not going to lead them by the hand and tell them exactly how to realise what they do. Digging in the code right now is extremely valuable for any future modder I would say - even if the systems change, you can see them when they are still “little”, before they have grown up into a bunch of large APIs that reference fifteen other services and call a hundred events. It might also be a good source of how to design (and adapt) systems, but that’s personal.

I thought about giving this sapling-planting-mod a try, but I found out that resizing seems to… not quite do what I would expect it to.

As you can see in this example, while humans do scale… kind of, trees just stay the same. Perhaps I need to modify render_info on the client (if such a thing is even possible), perhaps the engine can’t deal with these things yet.

So without properly, dynamically growing trees (of course I could simply remove and re-place the entity for each stage of growth… but I don’t feel like this would be “right”? Especially not with the normal models) is kind of impossible at the moment, sadly.

@phoriist, a few names that caught my attention (that are clearly wrong) were “Casff Adamo” (“Adamo” is banned, Casff is OK), “Fishcher” as last name (“Fischer”?) and “Anaanne Sadman”… while the Sadman is quite hilarious, the Anaanne sounds weird.

So, I’m kind out of ideas as to what I could do (without models), except maybe try and see if I can get the drag-to-select-multiple-harvest-thingies. But as I’ve said before, it seems pretty dead around here, so folks probably wait for the next release. Oh well.

1 Like

I would be interested in dynamically growing trees. Even if they just replace the entity. I might even look better when you can define the model at a certain stage. :blush:

I agree with you on that this is the best stage to get into modding to learn the way the game is coded. It is all pretty small to overview it well. It might get overwhelming if you start when the game is finished.

I’m tempted to do a model variant approach - i.e. have multiple model variants for the different growing stages with a component that controls the growth itself. I’ll still look into render_info to see if I can’t get it working. I guess it’s possible that render_info server-sided works as long as the entity has not been sent to the client (or something similar), after that the change is not relayed to the clients - if this is really the case, changing on the client could work. The question is whether all the important events (gameloop/calendar) are available on the client too; otherwise I would need to find a way to… err… relay them. I think the only available camera is API, which kind of indicates a “no”.

But I think a mix of both could work out; have model variants (like the berry bush) and perhaps different sizes. A component would then switch between the models/sizes and in the end replace it with the final tree. This would allow it to be abstract enough so you could have any kind of tree, different growth times for different trees, …

Another question would be when chopping the tree becomes available. I thought about something à la “Every sapling has a maximum growth size and a maximum resource yield. Upon growing, it can be chopped down but will yield less wood (linear? exponential?) than when fully grown.” This would make tree farms viable, especially when players don’t know whether their tree is fully grown - or not.

i believe the game Craft the World is using a linear approach… as trees on the surface advance from saplings to fully grown (4 different sizes, i believe?), the player can harvest them at any stage, and will yield a greater return at each additional stage…

Give me some time. I have exams on the Uni in this four weeks. But I am writing all needed replacements on my PC and, after exams, it will be huge replacement update. :slight_smile:

I just imagine that this, without any indicator, could become a bit tiresome for players. I mean, if there’s only 1% missing to get 1 wood more, it’s hardly visible yet can be frustrating (to know you’ve chopped it down believing it was done when there was just another minute to go).

Perhaps we could introduce a new class that keeps track of these things, a… forester? A guy that keeps track of trees and perhaps marks them once they’re ready for chopping down. It could also automatically chop down and re-place trees (for example, if the available wood drops below a certain point). Actually, that could be cool; I’m imagining the little guy hanging a sign on the tree with an axe or something to mark it.

as long as its obvious (and it should be) that smaller trees yield smaller pieces of lumber, i think many folks would understand/accept the tradeoff (being patient enough to wait for a full grown tree, which would have to be clearly distinct from the other stages, or getting a quick amount of lumber now, and willing to take that loss in resources if you’ve misjudged stages)…

but, i suppose that’s similar to how its done today, so sure! marking trees that would yield maximum return would be pretty cool… :smiley:

re-planting saplings would also be a welcome feature of a forrester…

Yeah. I think foresters could do the following things:

  • You could play “ghost trees” (the same way place item works) that mark locations where trees will be planted.
  • The forester has a workbench and stockpile too. You can define how many saplings are kept on storage and how much wood there should be (before the forester marks trees).
  • The wood limit works as following: If the stockpile drops below the configured amount, the forester will mark fully grown trees for chopping. He does, however, not chop himself.
  • If there’s less saplings available in his storage then defined, he’ll go out and gather saplings from trees (assuming they are a special action and not just a by-product of lumbering)
  • He will continue to plant trees on the defined ghost locations and mark them, effectively trying to keep at least the defined amount of wood in the stockpile.

However, I’m not too big on AI and with the changes that are currently undergoing (which could be useful for us too under certain circumstances…) I’m not sure if I want to start this now.

I’m going to check if I can work around render_info’s scale not working properly. If that doesn’t work then everything is lost, unless we really want that trees just “pop” to the next stage.

makes sense… as you mention, some of this will hinge on how those saplings are acquired…

you mean, a literal/gradual increase in model size … as opposed to a “pop” with the requisite smoke effects / sparkly bits?

Yepp. I mean, we can still switch the model at some stages, but I kind of dislike the idea that you just see saplings pop to the next stage over the screen. It’s a bit irritating to say at least.

I don’t know how well effects would work with something that grows. I mean sure, sheep have a fursplosion, but…

well, given that virtually everything else in the game transitions from one size to another with a magical :dash: (which i quite like), it wouldnt be out of the ordinary for a tree to go from wee sapling to a “stage 1 tree” with the same “poof” effect…

but if you can pull off the gradual increase, go for it! :+1:

To be fair, I think there’s a lot going to be changed in that aspect too. The timing system is rather rough with a lot of things relying on the hourly callback.

I guess I’ll start work on a non-growing approach then; seeing as that is likely much easier anyway. Plus I already have the necessary tree models, three stages at least…

Start of edits: I thought perhaps I can do some kind of step-by-step thing on how I approach things with this example. I’m not going into details, just general successes/failures.

09:15: I’ve checked; render_info is completely ignored on both server and client - at least for objects without animation. Objects that are animated are simply torn apart. Therefore, I suppose this isn’t possible yet.

09:23: As I thought, file() is simply a helper which defines a file relative to the current position. My sapling can easily include the normal qb files using /stonehearth/entities/trees/.... On top of that, rp_spawn_stuff detects it. Sweet.

09:38: The model_variants component seems to be pretty sweet. I was confused about models at first, but seeing as one entity can consist of multiple models (see humans for an example where models contains strings and objects) that seems to be okay. Might allows fancy stuff for us, too.

My saplings now have a weirdo button which turns them from oak- into juniper trees. A great success for science.

09:45: Components are weird. Also, I’m experience this really weird bug where the world generation seems to do nothing at all - yet there’s nothing showing up in any log file. Is that one of my mods gone haywire or a general problem? Anybody else experiences this?

09:54: So I have to debug that while we’re at it. I highly suspect that something in the new JS is breaking in some way. lua finishes the world generation, but JS is somehow not informed. sigh

10:00: So every second start up works as expected, the others are deadlocking. Well, throwing in debugging prints here and there to see where we’ll end up. Meanwhile, Component:extend is called too late. At this point, re-sizing the entity seems to be impossible.

Testing shows that this might be due to this being called too early instead of too late. Uhhh…

10:07: Wish I had simple fire-and-forget timers like the ones in GMod. Although that isn’t necessarily going to solve problems here. Hmpf. What functions does render_info even have?

10:15: The infrequent loading bug is really odd. It jumps into the shell view but then it seems to die for some reason. Tracking progress now. But have some details about render_info:

render_info:extend
render_info:__tojson
render_info:get_type_name
render_info:get_id
render_info:is_valid
render_info:get_animation_table
render_info:set_animation_table
render_info:get_material
render_info:set_material
render_info:get_model_mode
render_info:set_model_mode
render_info:get_model_variant
render_info:set_model_variant
render_info:get_scale
render_info:set_scale
render_info:each_attached_entity
render_info:num_attached_entities
render_info:trace_animation_table
render_info:trace_attached_entities
render_info:trace_material
render_info:trace_model_mode
render_info:trace_model_variant
render_info:trace_scale
render_info:attach_entity
render_info:remove_entity
render_info:__tostring

“trace_scale” sounds weird.
custom [class std::shared_ptr<class radiant::lua::BoxedTraceWrapper<class radiant::dm::BoxedTrace<class radiant::dm::Boxed<float,5> > > >] trace_scale(custom [class std::weak_ptr<class radiant::om::RenderInfo>],char const*)

So trace_scale takes one argument, a string (not counting the self reference). I think this is more logging related than a callback though. Not that it would matter a lot.

10:25: A-ha! Defining render_info just above the component seems to do the trick. We can re-scale the sapling in our sapling component now. Very nice. That doesn’t allow us to re-scale them at runtime by chance…? (Nope.)

10:51: For some reason the render_info itself is ignored though. Huh.

10:54: model_variants is not exactly helpful either.

model_variants:extend
model_variants:__tojson
model_variants:get_type_name
model_variants:get_id
model_variants:is_valid
model_variants:add_model_variant
model_variants:remove_model_variant
model_variants:num_model_variants
model_variants:trace_model_variants
model_variants:__tostring

Hm. On the bright side, I’ve discovered entity_data. I have absolutely no idea what it’s for though. An extra hashtable for entities to store data that is not in a component?

render_info remains mysterious.

11:00: Mystery solved. I hope that they change the way mixins behave. Instead of having the object extend on the mixin, the mixin extends on the object. This means that mixins override entity definitions - which should be the other way around. I guess I’ll get rid of the tree mixin from Stonehearth then, it’s not like we’re a real tree after all.

11:17: There you are, you bastard.

[01/21/14 11:16:50] Update world progress: 100
[01/21/14 11:16:50] Update world progress: 0
[01/21/14 11:16:50] [JS] tracer complained: [progress] = 0

So the issue is that WorldGenerationCallHandler:update_progress(e) is called although the world generation is already over and this happens right in-between two polls (this wouldn’t have happened if :update could enforce a poll). So I need to see how this can happen… And why the heck this function is called with zeros all the time.

11:20: Alright, the issue is that there are two world generators because of RP’s newly introduced propose_world_generator. Sadly, they both listen to the slow poll event and therefore generator “pollutes” it with zeroes, effectively creating a racing condition. I suppose I could simply have RP remove this callback from __init and have it attached back once create_world is called - but since mods might override create_world, this is kind of a bad idea.

The whole “propose” approach doesn’t seem to work out. Hm.

11:28: And there we go. It just took me two hours of kind-of-asynchronous-passive-debugging to find that one and the solution isn’t the prettiest, but it will hold for now. Preferably WorldGenerator would not subscribe to the event until create_world is called, but that’s not really possible for me to achieve.

Back to saplings we go now that the map loads every time. Right now, saplings have three hard-coded growth stages that simply use the “normal” models (small, medium and large). I’m not 100% sure I could handle growth that changes the model size - as mentioned before, I would likely have to re-create the entity. Is there a way to scale these things in Qubicle, or are those all standardised?

But anyway, now that there’s a working proof of concept, we move on to the next stage, which would be to get this whole thing a bit… cleaner.

11:55: I present you the first WIP video. Minus the odd alignment it actually works pretty well I guess.

The component used looks a bit like this (spoilers):

	"rp_diy_trees:sapling_component" : {
		"stages" : [
			{
				"duration" : 10
			},
			
			{
				"duration" : 10,
				"model_variant" : "medium",
				"stonehearth:resource_node" : {
					"durability" : 3,
					"resource" : "stonehearth:oak_log"
				}
			},
			
			{
				"duration" : 20,
				"model_variant" : "large",
				"stonehearth:resource_node" : {
					"durability" : 5,
					"resource" : "stonehearth:oak_log"
				}
			},
			
			{
				"model_variant" : "sheep",
				"stonehearth:resource_node" : {
					"durability" : "100",
					"resource" : "stonehearth:sheep"
				}
			}
		]
	},

So what this actually has become is some sort of growing tree, not just a sapling per se. Let’s see what I can do about the odd offset.

12:01: I don’t think I can do anything about it. At least, not about the default trees. They’re just asymmetrical. Therefore, a proper growing is kind of impossible. Since I don’t own Qubicle (and don’t plan on buying it since, well, I’d use it three times a year and ragequit it twice in the same period) I can’t really test it with “proper” models but will just go ahead and claim that this is the case.

In other news, I just found out that model variants can have a scale.

12:09: See, this is what happens when you trust people and get your hopes up. scale does nothing. large_juniper_tree.json is a lie. Well, alright, I guess scale does something but since the engine doesn’t react to re-scaling at runtime, nothing happens. It’s about the same! Really!

12:14: On the bright side, I just happened to cross the animation system which seems to confirm what I thought. So, @voxel_pirate, I guess it’s possible to have left-handed workers just by lua magic. Actually, let’s see what we can do with our newly acquired render_info:get_animation_table and render_info:set_animation_table.

12:18: Well, that was quick. Since every animation is loading its json (or rather, fetches it from the cache) there’s no “real” way to man-in-the-middle these. Overloading radiant.resources.load_animation is possible, but would do this to every entity. Since EffectTracks has a nasty constructor we cannot really intercept that one either. There’s no clean way to achieve this currently. Hmpf.

Back to the roots. hhhehehe.

12:43: After a short reddit break back to work. Added the command in theory. Let’s see if we can get a settler to come over to the tree, do a fumbly animation and then spawn a resource node thingy.

12:57: Well, why re-invent the wheel right. By declaring trees a renewable resource (namely sprouts), we can simply rely on Stonehearth doing all the evil AI magic for us. The downside would be that we have this odd “harvest” icon above the tree (if rp_click_and_gone has been installed) but I guess we can say that’s the “collect something” icon or something.

Besides that, planting a tree with a hammer doesn’t seem to be very effective. But then again @SteveAdamo said he likes the pop animations Stonehearth has, so I hereby declare that every item has to be placed with a hammer. We already see this with furniture and walls, so it’s clearly a law of the game.

Next step, using my amazing skills to draw an icon for the shoot gathering.

13:15: Gentlemen:

Next: Check why the cooldown timer somehow doesn’t work as expected.

13:30: Tried to figure out in the last 15min why I could still harvest shoots from a item sapling (i.e. sapling proxy). Tried blocking growable trees to be harvested. I didn’t find out what was wrong until… too late.

I’m not sure if it is really a bright idea to use the place item system. It’s handy and all, but you can move trees after they have been planted. That sounds… err… I don’t know.

13:36: I start to dislike the AI very much. I can imagine what conversations they must have, it goes along the lines of “Hey, can anyone of you guys over there come here and pick this sapling up? It’s kind of blocking my view of the landscape while I stand here and do nothing.”

Meanwhile, the move command is added after we run, so we can’t simply add it. Hmpf… Maybe I can use the place item and move API without the re-moving part one.

Hey. The carpenter workbench. No wait, that thing isn’t placeable. Grah.

4 Likes

I love that you kept a running log of your progress… and being stuck on mass transit, this provided a nice diversion from the … “scenery”

as for the hammer/plant/poof process, you hereby have my blessing to continue down this path…

Nice progress. Re-alligning the trees is no problem. I could do that if the code is functioning.

The code does work, the videos should show that. Since I’ve set the delay extremely low however (currently 10/20 ticks, which is 2/4 seconds) it’s not visible. If you cut down the three, you would get 0//3/5 wood (or 100 sheep…) so that part is working already.

The only things that I really miss is the ability to re-scale entities once they have been created. Also, it would be nice if I had mixintos for mixins already, but RP’s events work too.

The only thing really bothering me is the place item thing, which I hope to eradicate now.

14:02: To demonstrate my issue, have a demonstration.

14:17: I think it’s kind of fair to say that removing the move command proves to be… difficult.

2 Likes

i realize you are striving for perfection (and thats why we :heart: you!), but i love the current implementation… wee sapling that is “hammer planted”, and poof… now, about that sheep… :smile:

1 Like

Ok nice. :thumbsup:
Looking forward to play with it.