Tutorial for adding new class

Starting to figure on my own but before I begin wondering if anyone has a tutorial on adding new jobs with all the new graphics that are in place? (As in carpenter, ect.)

Thanks

2 Likes

I’d be glad to join you, I haven’t done it either, but it can’t be that hard. I tend to take my time writing tutorials, I’ll gladly pm something if I get it working, then post here for anyone else. If you’d like to pm me any points of interest you have come across so far that’d be helpful.

1 Like

As far as I can see, adding a new class will also require you to think of the way the promotion screen is working. The positions (x/y/icons) are currently hardcoded, though there are some hints towards some research with graph libraries to make this more dynamical.

To add a new class, you’ll either need to JS your class into that tree or write your own tree and add a tab of some sorts (like Minecraft’s achievements for example). I would not overwrite the html/js just because it makes your mod unusable with others that might also add classes.

4 Likes

Honestly I’ll held off on looking this over mainly becuase of my lack in knowledge of html/js. I’ve done somethings with other people in the meantime, this gave me an opportunity to get some experience. Here are my thoughts regarding the process.

A new class can added by just a copying and pasting an existing class, renaming a few things, optionally change somethings, and adding some manifest info.

Next would be promoting to your class.

The promotion screen works like so

  1. sits and waits for “radiant_promote_to_job” event to triggered, this event seems to come from clicking the “Change Jobs” button in the in-game ui.

  2. the promotion ui is added

  3. a trace is done to stonehearth:jobs:index, this is the master list of classes, our new class is mixed into this list, so it’s returned in the trace.

  4. next some data is pulled about the current citizen we have selected, like their current job

  5. next _buildTree is called to generate all the clickable classes to promote to

  6. finally radiant.call('stonehearth:get_talismans_in_explored_region') is called to find available talisman’s in the area and enable the player’s ability to promote to classes if they’ve met the requirments.

Now in order to add our class into the promotion screen we just need to append

self._layout = {
     'stonehearth:jobs:worker' : {x: 372 , y: 244},
     'stonehearth:jobs:carpenter' : {x: 542 , y: 159},
     'stonehearth:jobs:mason' : {x: 542 , y: 244},
     'stonehearth:jobs:blacksmith' : {x: 542 , y: 329},
     'stonehearth:jobs:weaponsmith' : {x: 542 , y: 414},
     ... ect

     'mymod:jobs:mynewclass' : { x : whatever value , y : whatever value },
  }

From here the promotion icon will appear, and we can promote to our class as long as we meet the requirements.

The issue lies though in how self._layout is re-declared each time the view is opened. Even if we added to it, it will just get reset. Another problem I see is that all the steps I wrote about above happen upon adding the view to the game. Meaning even if we listen to radiant_promote_to_job, we wouldn’t be able to inject our class into self_layout before _buildTree is called.

It’s looking like there are a few options.

  1. do as @RepeatPan suggested and add a tab group for your mod. Which is more than reasonable approach.

  2. override the default files, breaking compatibility with other mods that add classes.

  3. this is more of a theory, think of when outfits are made, hearthlings quickly run over to them and put them on. Perhaps the same could be done for our custom talisman, but instead they are promoted to the class upon picking it up.

  4. write a mod that changes the behavior of the promotion screen allow other modders to hook into it. From here mod’s that add new classes would require that mod in order to function.

  5. endless other ideas, like listening on the crafting item event, checking to see if it’s a talisman and just promoting someone to that class, by-passing the need for the promotion screen.

Again excuse me if I missed something html/js is very new to me, I took one web tech course 6 years ago and never really touched it since then… :unamused:.

I think listening in on “radiant_promote_to_job” and opening a new view, or just appending to the promotion view seems like the best idea.

That’s it, I’m off for tonight. Happy New Years Everyone :slight_smile: .

2 Likes

If there is any serious interest in adding custom classes, I can add some Jelly magic to it, including “Build your own tab” and making the whole promotion thing easier. Because I’m already messing around with the files (and got pretty good at it, I would say) it wouldn’t make too much of a difference - plus there would be a neutral base for mods to use.

2 Likes

I’d still like to see DF / Gnomoria style classes - ie you create them all from scratch and assign jobs to the class (eg the carpenter would have woodcutting, carpentry, and hauling).

1 Like

That would be great, thanks :slight_smile:

I didn’t realize this before, but it’s looking like we will have to override the promotion screen anyway as _layout is indexed for our new classes alias. Which will return null, and would later cause the JS to error. So even if we were to create a separate tab the normal promotion screen would error anyway.

We’re going to need a base mod that will make some changes to have compatibility. Jelly is a very fitting solution.

I’ve gone ahead and sent you a pull request on Github. I’ve simply added an event that is trigger during the promotion screens _buildTree function. The current _layout object is passed with the event.

Modders would only have to include a .js file listening in on the event

$(top).on('jelly.PromotionTreeLayout', function (e, layout) {
    layout['mymod:jobs:myclass'] = {
	    x:375, y: 500
    };
});

and

"ui" : {
    "js" : [
         "file(ui/add_to_promotion_tree.js)"
     ]
}

In their manifest.json, in order to add to their class to the promotion_tree’s layout. :wink:

1 Like

Thanks! I’ve commented on a few things before I can pull it.


Overall, the design of jelly is to be data-driven, i.e. while it offers script hooks and extended events, it should mainly offer JSONs that can be mixinto’d. For example, for professions, the current idea haunting my mind would be something like

{
    "stonehearth" : {
            "stonehearth:jobs:carpenter" : {
                "x" : 12,
                "y" : 14
            },
            "stonehearth:jobs:mason" : {
                "x" : 14,
                "y" : 15
            }
    }
}

where changes/modifications can be easily made. Each node in the main object represents a tab, adding a new node would therefore create a new tab. Therefore, adding a class to the game into the existing tree would be as simple as having a mixinto defined like

{
    "stonehearth" : {
            "my_mod:rocket_scientist" : {
                "x" : 0,
                "y" : -3500
            }
    }
}

That’s the approach that I’m aiming at. This would require minor changes in the JavaScript and the HTML, but allow for a very easy solution that would be close to what Radiant likely will employ.

2 Likes

Here’s a working sample on how to add a custom class to r188.

To do this we had to make some changes to the base game, @RepeatPan’s Jelly handles these changes for us. So mods looking to load custom classes would have Jelly as a dependency.

Here’s a sample. :slight_smile:

Jelly - Download

Feel free to leave any question’s you have

2 Likes

I wouldn’t include jelly itself in this download (and especially not including the git folder). In case there’s any change, or bug fix, people might be running around with older versions - which could be especially troublesome because Jelly doesn’t have any sort of version system attached to it (yet). Linking to the zip file on GitHub is okay, but I wouldn’t bundle it.

2 Likes

I feel like I ought to write a little follow-up after this thread got a little spotlight in the last stream by @Tom

Re: “Tabs are kinda bad, mods should integrate seemlessly with Stonehearth”

I agree wholeheartedly, but there’s exceptions. Let’s assume the following:

  • We have a mod that bases on science and adds a bunch (5-10) new scientist-related classes
  • They all inherit from a base-scientist, which is a successor of the engineer
  • For the sake of the idea, the engineer is a 2nd or 3rd level profession

If we added all these new professions to the default screen, the graph would get bloaty and would have to adjust (by becoming smaller for example) so it can fit all icons. Instead, the graph would merely display the scientist class as some sort of special “hyperlink” icon. By clicking on it (or the tab), you would be guided to an entirely new plane where the centre wouldn’t be the worker but the scientist, effectively showing just classes that are related to science.

We’re basically doing domain separation. Instead of cluttering the main screen with classes, we separate them into fitting categories. Of course, if somebody added just one class that was very close to the vanilla game, it can be added to the existing default tab/plane.

Re: The graph thingy will be gone soon(ish)

I’m for and against that to be honest. Yes, it’s a bit odd to get into, but once you are, just clicking on an icon is much faster than finding the class in a table/something similar. Because the classes are a tree (in the end), I think tables don’t make too much sense either. For new players, I think clicking around to figure out what’s there is a nice way of getting the hang of it. Of course, too many classes will be confusing - but that might be solved with some sort of “fog of war” for classes.

But trees might. Trees should be easy to generate dynamically, too. Maybe worth an investigation.

2 Likes

i think we need a update please