Why is the plane the wrong way round!?
That’s not how you land your planes?
Never mind that it just melts into the ground…
The first thing that came to my mind was “Quantum-Phasing Molecular Mechanics”.
…so as not to interrupt the flying experience, of course.
As if that’s difficult.
Meanwhile, I’m thinking of ways to add stuff to Zulser that really matters. Things that change the world. Things you cannot live without (and the only reason you can right now is because you don’t know that you need them yet).
I think rp_pony_train might get a revival of some sort.
For those who don’t remember rp_pony_train because well, it has been well over a year:
In related news, someone dared to downvote the video.
Sheep turret / trebusheep
Clearly one of the other hearthlings, miffed in that they themselves were denied their own pony to ride.
And I am also well aware of the legendary Hype Train. I was unsure whether @chessmaster42 would be making his own or calling upon your creation in the realization of the Phantasmagorical Colossus I suggested…
Blast To The Past
Because it pops up now and then and some folks might be interested in how modding “grew” since “the days old”, I’ve decided to release almost all of sheep_rave WIP3. In case you don’t know, or don’t remember, this is what I’m talking about:
Let’s enter the abyss of my mind for a little tour by asking important questions.
Sheep Rave History 101
There was this post that got me thinking, made by the one and only @SteveAdamo on March 21st:
To which there was only one logical answer, or rather, question:
There’s a little bit of other conversation going on too, but the important bit is that I’ve still had my graphic tablet plugged into my computer at the time, it resulted in this post whose highlight was this drawing:
Of course, people made fun of me, as they often do.
Anyway, one thing led to another and on March 24th, a mere three days after Steve’s “idea”, the first commit to sheep_rave was done. There’s been 22 revisions over a week that led to the “mod” I’m providing you with today, the version that (probably) made it into the video.
A few selected commit messages:
- Added sound. In stereo.
- Added wiggle animation
- Awww yiiss
- Tweaked wroom and added wibbly effect
Sheep Rave History 101 (cont.): Coding Point of View
Getting the sheep rave to work was a challenge. Mixintos were somewhat recently introduced, as were overrides. They’ve added a whole lot of possibilities; while it was possible to override lua services and controllers (I’ve done that with the old RP mod loader to add some more functionality to the world generator/citizen generator), it wasn’t possible to modify data itself in any way. Mixintos and overrides changed that.
The mod is not too complex but for the sake of modularity and simplicity is split up into three parts:
- sheep_rave was the main mod and dealt with almost everything.
- sheep_rave_data was the mod that contained a copy of the horde folder back then. It was possible (and necessary for sheep_rave to work) to set another directory as “horde” folder (instead of the default of mods/stonehearth/data/horde), but it wasn’t possible to “add” things (like it is nowadays, I think). At least, back then, I didn’t find a way. Because this is some sort of “artifact”, I didn’t remove the other files, so it’s less obvious as to what I did. What I’ve added was a bunch of lights, along with a new thought material so the sheep can think “oooh, rave”.
- sheep_rave_third_party was originally part of sheep_rave, but because I don’t own the rights to either the wroom sound nor the music, I can’t distribute those. So I’ve split it in a mod; I can use the “real” files locally but release empty files to the public.
The basic idea was “Let’s have a party with sheep”. One thing that is kind of stuck in my head is Spongebob’s Jelly Jam. For those who don’t know the episode, it can be summarised as “Spongebob parties with a Jellyfish, which annoys Squidward and soon gets out of control”.
One of the sources of all this madness.
The soundtrack is called Stadium Rave A, composed by Mark Governor and Glenn Nishida. It’s probably been made to sound similar to Get Ready For This by 2 Unlimited which can often be heard in sport events. Or so the Spongebob wiki tells me.
At this point I’ll probably have to admit that I have absolutely no idea how raves or parties work. But not knowing something never stopped people from doing it anyway. If anything at all, it was an incentive to do it.
The Mashup (and Animations, of course)
Right, so we have this song, we have “rave with sheep” and we need to mash that together somehow. So the first task was to figure out what sheep would do during a rave. With the help of @voxel_pirate and his Blender plugin I’ve managed to put together a few animations. You can look at them in the Kitchen viewer, a little experiment I’ve done around the same time. I’ve decided that sheep should wiggle (which has been dubbed as “laundry machine animation” by some…), backflip (two iterations, I was unhappy with the first one because it looked so odd. The second one was much more sophisticated, with moving feet and all), jump around, wobble (note the ears, tail and leg movement) and headbang (including the tail).
I’ve really OCD’d hard on the animations (… actually, the whole thing in general) though. By counting the beats per minute of the song, I’ve got the frames I had with each animation (based on the fact that the game had 30 FPS in animations and the assumption that there was no desynchronisation between audio and gameplay, i.e. no significant lag). So each animation was a multiple of one beat, which was around 1/120 second I think. That meant that, roughly, the sheep would always perform their actions in the same timespan: If a sheep did three backflips and wobbled then, it should line up as well as possible with a sheep that only wobbled. The overall effect is that it looks like the sheep act like a “crowd” - like in real life. Or so I think. Would make sense, wouldn’t it?
My Triggers: Bread, Salami, Blue Skies
So there should be a sheep party, but what actually triggers it? I’ve gone and created a subwoofer, a dead simple one using Panicle (my Minecraft-to-Qubicle converter). It’s the “totem” of the whole thing, so to say.
But how would the sheep commence to dance? They could be all around the map, so something needs to attract them. So to do that, I’ve opted for an antenna, like some sort of mind control device in a cartoon. In good old movie fashion, the antenna was to ascend, do its evil deed and lure the sheep.
Basically, a command triggered the subwoofer to extend its antenna. Once extended, the sheep would come. To have this acoustically accompanied, I’ve “borrowed” the sound effects from The Final Countdown by Europe.
The (not so) nAIce Part
So when the animations were done (I think I’ve started just with wobble and later on added a random one), they needed to be played somehow. This was way before I knew how the AI worked, it was my first AI experiment and until the recent train/Zulser things also my only. I’ve more or less copied another AI action, but I can’t remember what anymore.
Basically, it was just an action that ran at the top of the sheep priorities and played a random animation of those available (at the beginning, just one, but later more).
Once that worked, I’ve expanded the whole thing. I’ve written a rave service that dealt with it. You could tell it “Hey, let’s start a rave” and it took care of everything else.
So there was an AI action that blocked until the rave began. There was one that made it think something (which was outsourced in Jelly and has since disappeared), there was a simple “go to the subwoofer”, then “wait for the music”, “stop thinking about the subwoofer” and last but not least, “rave”. Then there’s a compound action that tied it nicely together.
Course of Events
So what happened was as following:
- The player clicks on the button on the subwoofer, triggering a command in the rave controller.
- The rave controller tells the rave service to start a rave at this subwoofer.
- The rave service creates an antenna, places it at the subwoofer and sets the status to “calling”. It’s creating a task in the background that moves the antenna slowly upwards.
- As soon as the movement task has finished, it’s triggering an event and calls for the sheep. This task is executed every two seconds, i.e. it’s woken up every two seconds (until it has finished).
- Play the wrooom sound.
- The event will cause the action in the AI to trigger; it will become active (and dominant), forcing the sheep to go to the subwoofer and wait there for further instructions.
- This task is continuing to call sheepies until at least 2/3 of all available sheep have arrived at our raving location.
- It’s also wobbling the antenna by changing its position in yet another task.
- Once a good majority of the sheepies has arrived, the antenna is retracted.
- If the antenna is hidden again, we’re ready to rave!
- Send another event. This will cause the sheep to face the subwoofer and wait for the party, which is about to get started.
- Two seconds later, the rave is prepared.
- All sheep should be facing the subwoofer by now.
- I’m speeding up the time in case it isn’t night (between 22:00 and 4:00), until sunset has been achieved. Actually, I’m not really speeding up time, as that wasn’t possible, not in the sense we have. I’m simply telling the calendar that one in-game second is now much, much shorter. Until we hit sunset.
- Once it’s dark, the rave starts.
- The time is slowed down; the night shall last forever.
- I’m adding a play effect to the subwoofer. As with the animations, this one was trimmed to the song. You can see it in the video, each beat makes the subwoofer grow. The effect was written by me and isn’t an effect in the normal sense (it was not really possible to have custom coded effects, still isn’t), it’s just a background task that adjusts the size the whole time using some sinus magic.
- All sheep start their dancing loop. They’ll pick a random animation and play it, again and again.
- Create 5x5 lights on the ground. Because of the way that the light system works (each lamp is actually just changing colors to some neon colors… which are actually Crayola colors. I can’t recall which ones though, but you could surely look them up based on what I’ve used in the light JSON), I need to place them at different times to have different colors at the same time. So I’m delaying the placing (you can see that at the start, as the floor slowly “builds up”). The right formula leads to the effect here. I’ve also tried to have different things, such as having shapes… But it would have required too many different scripted lights to be worth it. Maybe one day when we have access to changing light colors via lua.
- Play the music. Because this was delayed by ~300ms (due to polling and server<->client delay), I’ve had to put everything else in this step 300ms in the future. I’ve basically told it to play the music and approximately waited until it did so in order to sync it up again.
Disclaimer: This mod was developed for Alpha 2, over a year ago. It won’t even remotely work and while it’s somewhat feasible to make it work again (I guess), it’s not really worth the effort for me.
It was never intended for release, but I suppose if you’re interested in the modding history of Stonehearth, this is as good as it gets. As said above, I don’t include the audio (which is sad, because the whole thing was really built around it… and it fits so well), but you can easily download/buy/whatever the snippets yourself and get your own copy of a sheep mod. Or something.
The subwoofer has no recipe or anything, so it effectively needs to be placed by script (or cheated in). Like I’ve said, the whole purpose of the mod was that one video. I think it went well.
So if you’re interested in that kind of thing, enjoy my Blast to the Past.
Overly Excited Sheep
Ah, so my wildest dreams are theoretically possible… now, if only I could actually get focused enough to actually mod someday instead of just talking about it.
story of my life…
used to be easier.
He’s a little short, isn’t he.
Are you absolutely sure that that is neither a bush nor ornamental shrubbery?
It’s been almost a month since I’ve written about how the current stockpile system works, and how an improved system might look like. This was the post that I wrote back then:
Usually, when I make such statements, I gave them some thought and think that they are possible. Being a pessimist, that means that, unless there’s some very unforeseen stuff going on, it’s very possible to do and unless I say it’s painfully difficult, it’s somewhat easy to medium. Therefore, I’ll rank this task a 12.5 on the coding scale.
By messing around with some voodoo dolls, 250cc of chocolate ice cream, some candles, a crystal ball and other stuff, I’ve come to the belief that, with all the features that have been announced for Alpha 10, 10.5, and Tom’s streams, we might not see any drastic inventory change in Alpha 10, probably 11, likely even further down the road.
That means that, if we were to mess around with inventory stuff today, it could survive for the next two months! That… actually sounds somewhat depressing. But it’s take it or leave it, so we’ll take it.
During my next few posts, I’ll walk you through in the process of reverse engineering, and building, some quite odd things that are abstract and not really necessary to understand from a player point of view. If you’re interested in modding, however, you probably going to like this part or that other part because it could be useful. I guess. Sharing is caring.
So, during the next few RepeatFeeds, where you can ask questions and I’ll answer them for once, I’ll be
Building a better inventory system: Part 0, Requirements
The current inventory system in Stonehearth is not scalable, and not very modding friendly. Stockpiles act autonomous, which is kind of nice from an objective programming point of view, but very unhandy if you want to mod it. It can also be somewhat demanding on the performance because it performs constant checks for items that it could gobble up - in each citizen. So we strive for better performance, scalability and modding support. Somewhere on the way we might be able to get some gameplay improvements, too, who knows.
The next post will be the first in the series, where I’ll take a look at the files currently involved, some basic processes and where we will stand to move the world. Or, at the very least, the inventory system.
The current progress can also be seen on the GitHub repository.
when i see how some items work, i think that there should be a function that would put together items that have less than full stack size, like wood and stone that goes like crazy when building. (sorry if you can’t understand, bad english, trying to polish it a little)
I was actually writing walls of text here before Discourse seemingly decided that, for once, it doesn’t want to save the text. Oh well, bummer. I’ll not document the parts then in detail, just brief:
Building a better inventory system: Part 1, current status
There’s a few components involved:
stonehearth:stockpileentity is, well, a stockpile. It’s raison d’être is, by and large, to hold the
stonehearth:stockpilecomponent does most of the job: Managing what can be stocked into a stockpile, creating the tasks that force workers to restock stockpiles, what items are in which stockpile and a bit more.
- The AI actions regarding stockpiles (see an earlier post) that are responsible for the restocking. Note that additional actions are involved, such as the backpack stuff.
- The inventory service of Stonehearth (or rather, one of its instances) that keeps track of player items.
What we need to do now, basically, is finding something that can replace the
stonehearth:stockpile component with something a little more generic. In addition, stockpiles ought to be harmless, i.e. we’ll make sure that they won’t launch any more worker tasks (our inventory service will take care of that). To do that, the inventory service needs to be extended.
So, first task: Creating
outvetory:storage, a component that is (generally) responsible for holding some stuff, but abstract. This can be a stockpile, or a barrel (in Minecraft sense: One entity holding a lot of the same entities), or a chest. It’s the idea of a stockpile, an idea that can be expanded.
Continuing from Part 1 (which got submitted way too early).
Well, there’s the first step:
- Right from the start, a somewhat boring
outvert:storagecomponent has been created. Its purpose, right now, is to simply exist. It will be expanded later on with functions that are required for its task, such as adding items, removing items, finding an item, getting a list of items inside… But for now, it has a few, very necessary functions which are all not implemented.
- I’ve added the normal stockpile code (washed with my custom lunadry) with one major change: The stockpile does not plan tasks anymore. This leads to stockpiles, for the time being, effectively useless… Unless you happen to place them right where the items are.
- A little server init file patches the “normal” stockpile component with my new one. We’ll have lots of fun with that function, I can already see it, I’m afraid.
Continuing from Part 1, still:
This is a rather huge commit, but there’s lots to it.
On one hand, I’ve documented the entire stockpile component (which at this point, is still mostly the vanilla one). On the other, I’ve fixed (by discovering it by accident) a bug that may cause stockpiles to “forget” a slot. Lastly, I’ve refactored some code to what I consider “cleaner” code, such as taking shortcuts where possible (i.e.
if something then --[[ huge block ]] end to
if not something then return end --[[ huge block ]]), including a little fix that should make creating stockpiles a lot faster if on a map with lots of entities. Hopefully, at least!
Let’s talk a bit about the structure of things. Ideally, I would define an interface and stockpiles would just inherit it, but Stonehearth doesn’t support interfaces, so we have to work around that a bit.
The storage component has grown a little bit and can now redirect calls to another component, in this case, the (“vanilla”) stockpile component. The idea is that the inventory service, and the AI to some extent, can simply interact with the storage component, which will then delegate stuff to the “sub component”, or implementation component. So basically, we will have a hierarchy; a stockpile will delegate its calls to a stockpile component, while a chest might delegate it to a chest component. Portals will delegate it to the portal component, which will just accept any item and swoosh it around a bit.
However, it’s impossible to redirect everything, so I’ll have to mess around with the stockpile functionality a bit too. That’s not too bad, because I’m overriding it anyway. The kind of deal breaker is the dependency that’s going on: Lots of places require stuff from stockpiles specifically, starting with every single AI action there ever was (approximately).
So there will be lots of refactoring, probably in lots of different places. In the best case, I can somehow redirect the current calls to the new inventory manager, or just replace the places where it’s used.
But I think I’m on a good path so far.
The next step would be to modify how restocking works.
The very simple version of the current implementation is that stockpiles schedule a task whenever they have free slots. This task searches for available items, reserves a slot, and then takes the item to said slot. When the stockpile is full, the task is destroyed - and as soon as there’s space again, the task is re-created.
The new implementation would work the opposite way (the one that is more “logical” for us). Whenever an item is dropped, all storages (for now, only stockpiles) are checked if they can stock this item. For the first iteration, if there is a stockpile, a new task is arranged that takes the entity to the storage. So we don’t have to look for anything really, we know the stockpile and the entity.
Sounds simple enough, but not quite. I’m currently a bit too distracted to do proper research on the AI and task system…
That being said, I’ve pushed a new change that changes the way the AI works. The inventory service now sends workers to pick up item X and put it into stockpile Y. There’s no advanced heuristics yet and the task isn’t cancelled, so the item will be placed again and again and again…
But it kind of “proves” that the concept could work. The inventory service now successfully dispatches workers and routes items, even though it’s only after a fashion.
It’s been some time and I’m sure Discourse will tell you that too by inserting a snarky “1 MONTH LATER” comment right above this post.
Let’s get back on track. hohoho.
I’ve been paged to this little thread and I’ll write an answer over there as soon as this post is done, because I want to link to this post. Being prepared is everything.
Right, so how feasible are locomotives? Pretty. You’ve seen the (Unity3D-made) trailers and some obscure screens. What I haven’t posted up until now was the original video that I’ve sent to Tom the same day I’ve opened this thread, in fact. So here it is, For Tom With Love:
It’s a simple video showing three stages: Arrival, unloading, departure. The train arrives, is unloaded by workers, and then departs again. Both arrival and departure are currently triggered by console commands, but are also wired to (daily) timers. Let’s talk about structure.
The core of the whole operation is the railroad service, responsible for about everything. At the beginning, only straight lines will be possible. Tunnels and bridges are supposed to be there, but curves are a bit difficult. The main issue with curves is, well, there’s no “round” thing, so trains themselves can’t really go around curves. It would look odd. Of course, this can be avoided by having huge curve radii, but that’s also odd. Plus, having a single, straight line makes things much easier.
Building the tracks
You can tell him “Build me a railroad starting at (X, Y, Z)” and it will build tracks properly until it runs out of map. In this example map, I’ve artificially added “more” to the map to get a better view of the arrival/departure process.
In the future, the service would also build bridges and dig tunnels. In an even further future, it wouldn’t just do it, but rather hand out tasks to an AI to do it.
Managing the trains
Trains are spawned by the service, currently one at a time. Trains can spawn at any side of the railway driving towards the opposite end. They’re spawned properly (i.e. no cart is “off the rails”) and they’re despawned properly (upon reaching the edge) so it doesn’t look “odd”.
Each train consists of one locomotive, one tender cart and a random amount of other carts. In the video above, only one type of cart is used, the open goods cart - there are multiple, including the passenger cart seen in the previous videos. This cart is special as it has goods loaded that can be unloaded. These can be locked however, so only certain goods can be unloaded - the others are only decoration (as of now).
Once the train has been created, it’s schedule is set (see below). This is adjusted so the locomotive precisely always stops at the same location.
The train component
The heart of the whole deal, the train component is stuck to an invisible entity that represents the train. This component is responsible for moving it and therefore keeps track of direction, velocity and acceleration. It also has a schedule, which contains orders in the form of “X meters into the track, do Y” - for example, “break with 1 m/s after 150m”. The schedule is usually set by the railroad service. The train component itself does nothing except respawning, all input comes from the outside.
The cart component
A rather simple component whose only real purpose is to tag along and make some neat collision boxes.
The goods cart component
More interesting, the goods cart component can load goods. The railroad service (or whatever is “filling” them) tells them what they should load (and where) and they’ll make sure the entity is kept there. Currently, this means they’re just creating the entity at said location.
Entities can then be unlocked after the train has stopped, becoming available to the player. In this case, the cart acts pretty much like a stockpile. So it’s possible to say “I want log #3 on cart #5 to become available to the player” over the API.
Tie that up with some AI tasks and that’s what you get. It’s not that difficult because trains themselves aren’t too complicated (at least, in theory). There’s some issues unsolved however:
- Putting items on a cart is a bit more complicated than putting them on. Because that’s tied to the inventory stuff and they’re doing a rewrite of that just now, I’ve put that on hold.
- Animations are a pain. Especially because there is currently little to no API available, all animations need to be synchronised with the velocity/acceleration the train is currently going at. It’s not (really) possible to just say “Alright, move the animation to frame X”. At least, I didn’t stumble across a way to do that.
- Stonehearth, in its current state, is not big enough to warrant more than one train station, so the only real train destinations are all fictive (or “AI”, depending on your point of view).
- The whole thing still has a few concept flaws.
Locomotive implementation feasibility
Awesome train! Love that they pick it up when arriving at the station.