Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Starsector 0.97a is out! (02/02/24); In-development patch notes for Starsector 0.98a (2/8/25)

Author Topic: Commodity's and you: a basic tutorial on the complete commodity experience  (Read 2059 times)

alaricdragon

  • Commander
  • ***
  • Posts: 190
    • View Profile

so you want to add a item or commodity to the game, but don't know were to begin, or simply cant understand one small step of the process?
well, don't worry! I am here to guid you though this task.
in this tutorials, we will cover the following:
1) how to add a item to the game
    -what the requirements are for a items sprite
    -how the CSV file works, and what every variable in it means, and how to set yours up.
    -how to give your item a description
2) multiple methods of how to make a item show up in game
    -adding a item to the in game economy, and how that effects were the item is sold in markets
    -how to add items to the players inventory with code
3) how to change your items description dynamically (based on how literally anything you could think of)
    -adding text to a items description
    -adding 'F1 to show more' text to your items description
4) how to dynamically change the way your commodity looks
    -how to change the 'icon' your commodity uses
    -how to add a 'rank' icon onto your commodity.
5) and maybe latter, we can talk about 'special items' but not now sorry

sprites:
Spoiler
# requirements for a sprite:
Spoiler
so, the requirements are as follows:
1) *the image size should be 100 by 100 pixels or less.*
although you can have images larger then this, it will be larger then the 'box' that you can put a given commodity in and will look weired.
also, feel free to have images smaller then this. the game seems to handle even weird height/width ratios well enough in my experience
2) *the image should have a transparent background.*
although you can neglect this rule if you want, It will result in your item being very obviously different from the rest of the game. especially whenever you try to pick the image up.

besides the 2 rules both, there are not 'requirements' for a sprite. although even the 2 rules I describe can be broken, if you really really want to.

I am not a spiriting expert, so if you don't know how to resize a given image, or how to make a background transparent, i found 2 tutorials for gimp here:
cropping(1:44) and resizing(4:00) a image: https://www.youtube.com/watch?v=dQSlqcMCKx0&t=253s&ab_channel=DoiT8
adding a transparent background: https://www.youtube.com/watch?v=nl2uqKqbryo&ab_channel=EZTutorials
[close]
# were to put your sprite
Spoiler
now that you have a sprite, you need to put it somewhere the game can access.
enter your mod folder, and create a folder named 'graphics'. inside that folder, create another folder named 'icons'. and inside that, create yet another folder named 'cargo'
(please note: you can put your images anywhere in your mods folder, but this is the way most mods are structured, and the base game is structured. so it can help to organize yourself using others organization technics if you plan on your mod having a lot of things in it.)
from there, put the sprite you intend to use in the newly created 'cargo' folder. your setup should look something like this:

please take note of the name given to my sprite. most mods structure there sprites and other not player visible names to have a name like 'myModsName_WhatThisImageRepresentsName'. (were 'myModName' is the name of your mod, and 'WhatThisImageRepresentsName' is the in game name of whatever this image is suppose to be)
you can use always use a different naming structure of course. but if by chance another mod happens to add a image of the same name, at the same location, Weather your mod or theres might end up using the wrong image, and that can be... uncomfortable.
now that you have a image set up in your mod, we can move onto the interesting parts:
[close]
[close]
# the commodities.csv file
Spoiler
so the first thing we need to do is set up the location were the commodities.csv file will go. unlike were your image goes, this is extremely important. if you put this file in the wrong location, starsector will not read it.
enter your mod folder, and create a folder named 'data'. inside that folder, create another folder named 'campaign'.
now, we are going to get a commodity.csv file. because building one ourself is frustrating, im just going to go into the starsector-core and copy theres.
so in the 'starsector\starsector-core\data\campaign folder, and find the file called commodities.csv

now copy and past it into your own mods data\campaign folder

now we need to open it. i use a editor called 'Rons CSV Editor' to open such files, but you might have your own way of opening them.

wow. there is a lot of junk here. feel free to look around at everything, if you want, and try to guess what all the different stats do. I will of corse exsplain them all later.
what i want to do right now, is delete every line below 'supply'. to clean it up a little.
(in Rons CSV Editor, I don't know about others) you can do this by clicking on the numbers on the right, then dragging your mouse down to select multiple lines. then pressing the backspace button

mush more clean!
now, we are going to edit the 'Supplies' name and add a # in front of it. this will make the code ignore that inter commodity, so we don't mess with the base games supply somehow by mistake.
next, we are going to insert a new line both the supply (in Rons CSV Editor) this can be done by right clicking anywhere on the line were the supply's are, and pressing the 'insert row(s) above' option
your CSV file should look like this:

so, now we can start to fill out all the boxes so we can have our commodity
as we do, i am going to talk about what each and every box does, and what you mgiht want to put into it
Spoiler
1) name: the name of your commodity is the name that it will be referred to in game.
    -im going to write: 'Combat Lobster' because: that's what i want this to be called.

2) id: the id is how the game will remember your commodity. -not- to be confused with the 'name' of your commodity
    also note: if your save game has a item of this ID, and you change it (and no other mod or the base game has a commodity of this ID), your game will crash. so please remember that.
    -im going to write: 'LobsterCombatant_CombatLobster' because: I want to follow this equation: modName_commodityName, to avoid other mods from having the same commodityID as me (wish would cause my lobster to override theres, or theres to override mine)

3) demand class: is what the economy will see this commodity as. this should always be equal to a commodity 'id', unless you want the game to pretend its a different commodity (for the sake of economy simulation) (example: 'Volturnian Lobster' is in the 'luxury_goods' demand class, so it acts like a 'luxury_goods' for the sake of economy simulation)
    -im going to write: 'LobsterCombatant_CombatLobster' because: I want my commodity to act as its own thing

4) base price: this is how mush it generally costs to buy this item from markets (before tariffs)
    -im going to write: '250' because: that's how many credits i want one to cost

5) export value: this is how many credits a single unit of demand (on a colony) adds to the global market share for this commodity
    -im going to write: '500' because: I want my lobsters to be somewhat valuable.

6) price variability: this is how mush the price of this commodity in markets can vary depending on demand. so setting it to 3 means the commodity can be 3X the price, or 1/3 the price. at the most extreme.
    note: im not 100% sure on my equation there, but i do know that this is what this does
    -im going to write: '3' because: that's what every other commodity in the game has (that can be brought or sold), and i see no reason to have this cost a different amount

7) utility: How much demand one unit of the commodity satisfies. it is recommended to keep this at 1 most of the time.
    -im going to write: '1' because: I see no point in setting it to anything else

8) origin: probably does nothing, but at some point there was an idea for having exotic commodities that cost more further away from their "origin", still, it might do nothing
    -im going to leave this blank because I see no reason to use this

9) tags: a 'tag' is something that can be attached to a commodity, and can be read by the game or mods. you can add as many tags to a given commodity as you like, but a tag can change a lot of things, so make sure you know what your doing first
    -im going to write: 'military' because: a combat lobster should be 'military'.
    tags that exsist, and there functions, but only as far as i can tell. I miss things sometimes:
Spoiler
    1) military
        the military tag does a few things:
        1) it makes the commodity show up in the military market
        2) it prevents you from trading it in the milatary sub market unless your relations are at least 'FAVORABLE'
        3) makes it so selling this commodity on a market has a increased 'impact' (although, im unsure of what this means)
    2) expensive
        -some commodity based missions will prefer to give you missions based around commodity's with this tag
    3) crew
        -excludes this commodity from participating in procurement missions.
        might be used latter for something else, but its not yet.
    4) personnel
        governs if a commodity uses personnel slots, but only in NPC trade fleets??? (so it effectively does nothing)
    5) marines
        -excludes this commodity from participating in procurement missions.
        might be used latter for something else, but its not yet.
    6) food
        -probably unused for now. might be used latter
    7) medical
        -this is used in getting who you contact in a trade mission. (CITIZEN, or POST_MEDICAL_SUPPLIER. depending on i dont know.)
    8) luxury
        -this is used in getting who you contact in a trade mission. (civ or pirate, depending on if this commodity is legal or not)
    9) exotic
        -probably unused for now. might be used latter
    10) meta
        -prevents you from raiding this item from markets?
    11) nonecon
        -prevents you from raiding this item from markets?
        -excludes this commodity from participating in procurement missions.
        -prevents you from putting this item into your personal stockpile on your own markets.
    12) ai_core
        -lets you assing this item to the AI core sloot at a market
    13) no_loss_from_combat
        -prevents the player from losing this item
    14)no_drop
        -I think this prevents you from getting this item? I don't know though, because i could not find the code for it.
    15)nosell
        -this tag exists in the code, but i cant find were its used. It might be unused
[close]
10) stack size: does nothing anymore. used to determine stack size
    -im going to write: '0' because: it is no longer used

11) cargo space: the amount of cargo space each item takes in your cargo bay.
    -im going to write: '1' because: I think that's fine (you can set it to any number you like though. like 0.01. or 9001 or 0. whatever you think will be fun)

12) icon: the path to the sprite that this commodity uses.
    -im going to write: 'graphics/icons/cargo/LobsterCombatant_LobsterFighter.png' because: that's the path to my file (and the name of my image)
    -if you put your file somewhere else in your mods folder, you will need to write a path to it. and if your image has a different name then mine (and it should) you will need to write that name instead of my images name

13) sound id: the sound this commodity plays when you pick it up
    -im going to write: 'ui_cargo_volturn_lobster because': that's the lobster sound, and i want to use it (feel free to copy any sound from the commodities.csv file)

14) sound id drop: the sound this commodity plays when you put it down.
    -im going to write: 'ui_cargo_volturn_lobster_drop' because: that's the lobster sound, and i want to use it (feel free to copy any sound from the commodities.csv file)

15) order: the order this item will try to be sorted into when you sort your cargo bay. lower numbers means it will be more towards the top right, lower numbers mean it will be more towards the bottom left.
    -im going to write: '3' because: I felt like that was a good number? you can mess with this and see were you want your item to end up in your lists

16) economyTier: The order in which the economy simulation runs. Stuff lower on the production ladder (e.g. ore) needs to have a lower tier than the stuff that's made from it (i.e. metals) to have the simulation stabilize more quickly.
    -im going to write: '1' because: I plan to have this commodity require nothing to be produce

17) econUnitOrigUnused: this does nothing right now
    -im going to write: '0' because: this does nothing

18) econUnit: effects how many units of this commodity are available at a market (per output)
    -im going to write: '150' because: I like the number

19) baseRaidDanger: how mush more dangerous this commodity is to raid compared to others. can be left blank for LOW danger, i think.
    the accepted values of this are:
       MEDIUM
       HIGH
       EXTREME
    -im going to write: 'MEDIUM' because: the lobsters might fight back. (for most things, you should leave this blank.)

20) eU * base value: this is quite literally, what you put in the 'econUnit' slot * by what you put in the 'base price' slot
    -im going to write: '37500' because: 150 * 250 = 37500 (and 150 and 250 is what i put in the 'econUnit' and 'base price' slot, respectively)

21) iconWidthMulti: how close together your icons are on the market screen. smaller values are good for icons that are more tall then wide. higher values can sometimes be useful for wider commodity.
    -im going to write: '1' because: I copied the 'Volturnian Lobster' stats for this.

22) plugin: this does nothing, as far as i can tell.
    -im going to leave this blank because: this does nothing

23) desc: this does nothing. a forgotten bit of data from a lost age. if you want to add descriptions to your items, i will show you soon.
    -im going to leave this blank because: this does nothing
[close]
now after setting up all the varubles there (or just copying something from the base games commodity.csv file, and changing the id to something different) your commodities.CSV file should look something like this:


FAQ:
    Q: how do i make my commodity take crew space, or space in my fuel tanks
    A: as far as i can tell, there is no way to do so. maybe someday we will find a way.

    Q: I want to make my commodity make a custom sound when you pick it up / drop it
    A: I dont know how sounds work, to my shame. however, what i do know is:
        1) there is a sounds.json in the config folder of starsector-core that you could look at
            -the sound ID that you input into the 'sound id' and 'sound id drop' are found here, and link to a file in the 'sounds' folder found in starsector core.
        2) there is a sounds folder in the starsector-core that you could look at.
            -the sounds themselfs are found here.
        if you want to structure your mod like the main starsector (don't know if its important or not) create a sound folder in your mod folder, and create a sounds.json in your /data/config folder.
        if you look at the sounds.json structure, you should be able to understand it (although it might be easier to learn from mods with less sounds)


we are now going to check out our commodity in game. so lets save and close the CSV file
i advice you to download and install the 'console commands' mod (https://fractalsoftworks.com/forum/index.php?topic=4106.0) for this part, so you can test out your commodity
enable the game, and press 'CTRL' + 'SHIFT' + 'BACKSPACE' to open the console commands
then type in the following command:
'addItem commodityID'
were 'commodityID' is replaced with the ID of your new commodity you added to your CSV file
and if all went well, there it is!

but wait, if we move our mouse over the commodity, as some of you may have expected...

there is no description!
[close]
# the descriptions.csv file
Spoiler
now we need to add a description to our commodity. and there are a few ways to do this. we will be starting with the descriptions.csv file.
first, go into your mods data folder, and create a new folder named 'strings'
from there, we are going to go into starsector\starsector-core\data\strings and copy and past its own 'descriptions.csv' file into our newly created string folder
your new strings folder should now look something like this:

now we are going to open the newly copied CSV file. and then we are going to delete every line but the one at the top, and the category line
your CSV file should now look like this:

now, we are going to start to change this to match out own commodity.
first, change the id section to say your commodity id (so i would change 'lightmg' to say 'LobsterCombatant_CombatLobster')
second, change the type section to say 'RESOURCE' (so i would change 'WEAPON' to say 'RESOURCE') (also, the reason for this is to let the game know that this is looking for a commodity. it -will not- work if it says anything else, because you have a commodity that you want to have a description)
lastly, change the text1 section to say.. whatever you want your description to be (so i would change... i bunch of text to say 'mean, lean, fighting lobster')
and that's it! your new description is completed. here what mine looks like for reference:

also, ignore all the other sections (text2,text3,text4,notes) they are not needed here
if you start up the game, and give yourself one of your commodity again, it should look like this

and that's all for the basic of descriptions.
[close]
# advanced descriptions
Spoiler
in this section, we are going to cover something slightly more advanced for the first time.
if all you want to do is make a commodity and have it in game, skip this section.
if you for some reason want the following:
1) highlights in your description
2) the ability to change your description with code
3) the ability to change what is displayed when your press f1
then please read this section

so for advanced descriptions we are going to need 3 things:
1) create a new class and name it 'modName_CommodityTooltipModifier' were 'modName' is the name of your mod.
   next, make the new class 'implements CommodityTooltipModifier'
   your new class should look like this:
   
2) in your main java class (the one your mod_info says is your 'modPlugin')
   add the following function:
   @Override
   public void onGameLoad(boolean newGame) {
       super.onGameLoad(newGame);
   }
   your modPlugin should look something like this:
   
3) add your newly created 'modName_CommodityTooltipModifier' class as a transient listener. (note, you can make it none transient if you want it to rembmer data, but if you do, I advice you to make sure you dont add one if the listiner is already present (make it so it only adds if new game is true or something maybe?))
    you can use the following function to add such a listiner:
    Global.getSector().getListenerManager().addListener(new modName_CommodityTooltipModifier(),true);
    now your modPlugin should look something like this:
   

and that it! the hard part is done.
now its time to write your description. i will show you a simple example, but for more advanced things (like images, or crazy things) you will need to look up how to use the 'TooltipMakerAPI' on your own.

so, i would like to explain a few things about this.
1) line 15 is so this code will only effect the one commodity. if i didn't have that if statement, this would effect every stack of items in the game.
2) line 17 and 18 show how to create and highlight text. the text i want to highlight will always replace the %s in the first inputted text. this lets you have things like variables, instead of just static strings be added to your descriptions
3) line 21-23 show how to display text only when the text is 'expanded'.
now for showing it in game:
not expanded:

expanded:

and that's all for 'advanced' descriptions. simple i hope.
[close]
# Implementation
Spoiler
so you made it. and now we are here.
the question that must be asked, the one you have felt, silently at the back of your mind:
'how do i actually see this in game without commands'
and oh boy.. im glad you asked.
there are 3 ways to see a commodity in game without commands:
1) by making it so the item can be found and looted on things like ruins, salvage stations, and random kites outside the core worlds:
   https://fractalsoftworks.com/forum/index.php?topic=15244.0
2) by adding it to the players cargo with code:
    Global.getSector().getPlayerFleet().getCargo().addCommodity("LobsterCombatant_CombatLobster",100);
    you can replace the "LobsterCombatant_CombatLobster" with the ID of the commodity you want to add, and the 100 with how many of said item you want to add
    this can be useful when giving rewards for quests and, or other events.
    you can also use the addCommodity("LobsterCombatant_CombatLobster",100); function on any cargo in existence, if you so desire.
3) by adding it to a markets supply and/or demand (and therefore, a markets sub markets).
    with this, there are a few ways to go about it:
        1) adding your commodity to a industry supply / demand remotely
        2) replacing a industry so it makes your commodity.
        3) creating a new industry that makes your commodity.
    I will go over each of the options here in soon, but i will focus on number 1. the others will only get a quick description, or we will be here all day.

    1) adding supply and demand without overriding or creating industry:
Spoiler
        this is... different. it can cause lag, but it allows for the ability to add supply and demand without worrying about your code being overridden.
        also, normally when doing something like this, i use the marketRetrofits library, as it has a lot of things to help me run code more efficiently, but im not ready to create even a basic tutorial on how to use that yet, so here we are.
        so, lets get started! I will try to explain what we are doing as we move along:
        1) create a new class, and make sure it 'implements EconomyAPI.EconomyUpdateListener'. also, add the functions it wants you to.
           
        2) now add this newly created class as a 'UpdateListener' using the following command in your modplugin:
            Global.getSector().getEconomy().addUpdateListener(new modName_BaseCampaignEventListener());
            now your modplugin should look something like this:
           
        3) and now for the fun part! adding supply or demand to a industry. for this, go back to the class you made (the one that implements the 'EconomyAPI.EconomyUpdateListener' class).
            so, what you need to do here can vary a lot depending on what you are going to do, so my first example is going to be extremely basic, but the example is going to increase in complexity as we move on.
            so for the first example:
           
            so in this example, im adding 'Combat Lobster' as supply on lions guard HQ's, and im adding 'Combat Lobster' as demand on heavy battery's. there are a few parts to this that i would like to point out
            lines 17-20 are variables. i didn't need to make everything a variable, but it makes it easier to read and modify, so i did so.
            on line 22 we have a for loop. it loops over every market in the game. all of them. you don't need to do this, unless you want to check every world and apply demand or supply changes to industry's on every one, wish i do, so i have.
            on line 24 - 27, we see how to add supply. I would like to explain this in detail, line by line. so please read this if you want to fully understand whats going on here.
            line 24: this if statement prevents us from trying to run functions on a industry that does not exist, and crashing the game.
            line 26: this is a important line, the line that actually lets us add supply to a industry (and by extension a market) remotely. a few things to note however:
                market.getIndustry(supplyIndustry).getSupply(commodity).getQuantity().modifyFlat(source, market.getSize()-1);
                'supplyIndustry' needs to be the ID of a industry.
                'commodity' represents the ID of the commodity you want to add.
                'source' this is the 'source' of this modification. don't leave this blank please, as if anyone else try's to modify said supply or demand on the same markets industry's commodity, they might overwrite yours (or you might overwrite theres) because if the source is the same, the game assumes you mean to overwrite anything else with the same source. so be careful.
                'market.getSize()-1' is the quantity of commodity this industry should produce. it can be any integer, but most commodity have an equation using 'market.getSize()', so the market can have more commodity demand / supply when it gets larger.
            on lines 28 - 31, we see how to add demand. the function is exactly the same as lines 24 - 27, but we run 'getDemand' instead of 'getSupply'.

            we can also look and see how this looks in game
           
           
            as you can see, the lions guard is now producing lobster, and the heavy battery's are demanding it...
           
            across the inter sector!
            so you will see 'combat lobster' in trade fleets, in markets were it is demanded / supplied. everywhere. you can even get missions for combat lobster delivers.
            your commodity is completely implemented into the economy. congratulations

            ok, some design pacific issues that i would like to mention:
                1) my lobsters are only being built at the lions guard HQ. and not at worlds that have lobster.
                2) my lobsters are only being demanded at heavy battery's, and not at ground defences?
            so lets fix that:
            fair waring: this code is more complicated then the last, because i like this idea and want something good. also, i am terrible at explaining complicated things.
Spoiler
           
            so, if you look at this and think 'what?' don't worry, understanding something like this is not required. this is more of a bonus section for my own peace of mind then anything.
            so, lets go over the changes:
            lines 16 - 22 have changed in 3 ways:
                1) a new string called 'condition'. this references the market condition that will be required to add lobsters to the world.
                2) both 'supplyIndustry' and 'demandIndustry' are now arrays. this is for letting me have multiple industry have as supply or demand easier
                3) the new arrays called 'supplyValue' and 'demandValue'. this represents supply and demand + marketSize values of each industry (in supplyIndustry and demandIndustry respectively).
            lines 26 - 35 have changed in 3 ways.
                1) a new if statment stops supply from being added to markets if the 'volturnian_lobster_pens' is not present.
                2) i now run a for loop, going through all items in supplyIndustry and adding supply to them.
                3) i now run a a equation, involving supplyValue[a] to determin the amount of supply on this industry.
            lines 36 - 41 have changed, the same as lines 26 - 35, but without the if statement.
            things to note:
                if you wanted to modify this for your own needs, make sure 'supplyValue' and 'demandValue' are at least as long as 'supplyIndustry' and 'demandIndustry' respectively, or you will get a crash.

            if you don't understand this, please don't be afraid. this was something i needed to add because it was bugging me that if you played a mod that let you get lobster on one of your worlds, you would not beable to train combat lobster.
[close]
[close]
    2) replacing a industry:
Spoiler
        if you want to know how to replace a industry...
        1) copy the industry.csv file (placing it in the data\campaign folder of your mod folder),
        2) delete everything but the industry you want to replace,
        3) change the plugin to something in your own mod, that extends the previous plugin (if you dont know what the previus plugin was, its in the plugin section. it should be after the last '.' in the line),
        4) then in the apply() function (that you should override) run both super.apply(); the following command:
           supply("LobsterCombatant_CombatLobster",5);
            you can replace the "LobsterCombatant_CombatLobster" with the ID of your commodity.
            you can replace the '5' with the amount of this commodity you want this market to produce.
            please keep in mind: most commodity output increases with market size. so its wise to use an equation like:
            supply("LobsterCombatant_CombatLobster",market.getSize() - 1);
            (so the industry will produce '2' at size '3', '3' at size '4', '5' at size '6', and so on)
            (you can also do the same thing for the demand a industry has with the 'demand("LobsterCombatant_CombatLobster",5)' function)
        here's what your CSV could looks like (I overrode the lionsguard industry)
       
        please pay attention to the plugin section. its the only section i changed, and the only one you need to change with this method.
        here's what your code should look like
       
        this is what your code should look like, although what 'supply' you are adding, and what class you are 'extend' might be different
        we can even see the changes in game!
       
       
        please note this method has some issues:
        1) if anyone else try's to do the same thing to the same industry, one of your plugins is going to be overwritten, wish can cause issues
[close]
    3) creating your own industry
Spoiler
        if you want to create your own industry for your commodity.. it has less isuees, but can be a pain.
        1) copy the industry.csv file (placing it in the data\campaign folder of your mod folder),
        2) delete everything but the industry you want that you think costs an OK amount,
        3) change the plugin to something in your own mod, that extends BaseIndustry,
        4) then in the apply() function (that you should override) run the following command:
           supply("LobsterCombatant_CombatLobster",5);
            you can replace the "LobsterCombatant_CombatLobster" with the ID of your commodity.
            you can replace the '5' with the amount of this commodity you want this market to produce.
            please keep in mind: most commodity output increases with market size. so its wise to use an equation like:
            supply("LobsterCombatant_CombatLobster",market.getSize() - 1);
            (so the industry will produce '2' at size '3', '3' at size '4', '5' at size '6', and so on)
            (you can also do the same thing for the demand a industry has with the 'demand("LobsterCombatant_CombatLobster",5)' function)
        here's what your CSV could looks like (I used the lions guard industry as my base)
       
        this time, instead of only changeing the plugin, i also changed the id,name, and description
        although, you technically only need to change the plugin and id for this to work, it can get confusing for players if you don't at least also change the name.
        here's what your code should look like
       
        this is what your code should look like, although what 'supply' you are adding, and your classname might be different
        we can even see the changes in game!
       
       
[close]
    and that's all i will be talking about, in relation to creating and modifying industry in this tutorial.
    if i find/create some good tutorials on how to do this, i will likely put them -->here<--
[close]
#changing the image of your commodity
Spoiler
so this is something i have always wanted to do, but never figured it out. turns out, its relatively simple.
but before we can talk about how this works, we need to set up the listiner.
setting up the CommodityIconProvider
so first we set up a new class that implements blank. it should look like this:
Code
public class LobsterCombatant_Commodity_iconAndImageChanger implements CommodityIconProvider{
    @Override
    public int getHandlingPriority(Object params) {
            return 0;
        }
    @Override
    public String getIconName(CargoStackAPI stack) {
        return null;
    }

    @Override
    public String getRankIconName(CargoStackAPI stack) {
        return null;
    }
}
next, you are going to want to add this class as a plugin in your 'onGameLoad' function in your mod plugin. your mod plugin should now look like this:
Code
public class LobsterCombatant_startup extends BaseModPlugin {
    @Override
    public void onGameLoad(boolean newGame) {
        super.onGameLoad(newGame);
        Global.getSector().getListenerManager().addListener(new LobsterCombatant_CommodityTooltipModifier(),true);
        Global.getSector().getEconomy().addUpdateListener(new LobsterCombatant_BaseCampaignEventListener());
        Global.getSector().getGenericPlugins().addPlugin(new LobsterCombatant_Commodity_iconAndImageChanger(),true);
    }
}
(keep in mind: I left the 2 other listeners active. only the 3rd one is new, and required)
now that that's set up, we can go onto doing something more interesting.
[close]
getting a custom image for your commodity's sprite or 'rank icon'
so, im putting this here so i don't need to repetitively explain this.
first, you are going to want an image. if you are creating a sprite for your icon, see section one for how to add a sprite to your game. if you are creating an icon, do the same thing. but keep in mind the size of your icon, as icons in general are mush smaller then commodity images
secondly you are going to need to put this image somewhere. most images go into the graphics folder of your mod. but it does not matter so long as the image is in your mod folder. i would recommend keeping said folder organized though.
lastly, there is the part we have not yet talked about. the setting.json file. this can be done in _ steps
1) go into your mod folder and create or navatage to the data/config folder.

2) create a new text file and name it 'settings.json'.
    -if you are unable to change file extensions, go into your main starsector folder, then go into starsector-core/data/config and copy the setting.json file into your data/config. then remove all the files within your newly copied settings.json.
the resulting folder should look like this:

3)now you are going to want to open your settings.json folder, and add the following lines
Code
{
  "graphics": {
    "misc": {
      "LobsterCombatant_ExstraLobsters": "graphics/icons/cargo/LobsterCombatant_LobsterFighter.png"
    }
  }
}
of course, you should not use the name 'LobsterCombatant_ExstraLobsters' instead, use something like "youModName_whatThisIs"
also, the second part 'graphics/icons/cargo/LobsterCombatant_LobsterFighter.png' should be the path to the image you want to act as an 'rank icon' or 'sprite'.
lastly 'misc' is only one of many category's you can use when adding graphics to starsector. I dont know what all of them do, so i just tend to use 'misc'

4) lastly, when you use this type of code, you should use a line like 'Global.getSettings().getSpriteName("misc","LobsterCombatant_ExstraLobsters");' to get the sprites 'name' (aka, what the game uses to get sprites from its index)
-also, the "misc" should be whatever catagory you put your sprite in (mine is misc)
-also, your "LobsterCombatant_ExstraLobsters" should be the name you gave your json variable. not something like the image name.

[close]
changing your commodity's 'sprite'
so, what is this?
simply put, its a way to change that image represents your commodity in your inventory (or in other innovators, like in the open market).
as for why? its useful if you want to dynamically change the image of an commodity. like what crew and marines do, depending on the number of them in your inventory.
so lets give an example:
Code
@Override
public String getIconName(CargoStackAPI stack) {
    if(stack == null) return null;
    if (!stack.getCommodityId().equals("LobsterCombatant_CombatLobster")) return null;
    if (stack.getSize() < 150) return null;
    return Global.getSettings().getSpriteName("systemMap","icon_jump_point");
}
in this example, the sprite of my Combat Lobster remains normal, until there is more then 150 in a stack. then it gets turned into a vortex. like normal lobsters do.
so some things to note here:
1) anytime this function runs 'return null' it basically just exits the function. that's to say, when you return null here its just saying you don't want to change the sprite of this image.
2) 'if (!stack.getCommodityId().equals("LobsterCombatant_CombatLobster"))'. this is important, because without a line exiting this code when the commodity we want is not present, this icon would be added to all commodity's. something that might be useful to someone, but not me right now.
3) the returned value, 'Global.getSettings().getSpriteName("systemMap","icon_jump_point")' is a value gotten from the base games settings.json file. the "systemMap","icon_jump_point" is just the icon used to represent jump points on the map in game? maybe i don't remember..

note: both inventory spaces have combat lobsters in them. but one has enough lobsters to create a lobster vertex.
[close]
changing your commodity's 'rank' icon
so first thing first: what does this even mean?
its relatively simple. a commodity rank icon is the thing you see on, for example, marines in the top right conner. although saying that is a rather limited interpretation.
a rank icon is a image that goes on top of your commodity. this images top right conner is always at the top right conner of your commodity. this image can be as large and as small as you like. so let your imagination go wild with that.
and yet. this does work in congregation with changing your commodity's sprite.
so, let me give you an example of this in practice.

basic example
Code
@Override
public String getRankIconName(CargoStackAPI stack) {
    if(stack == null) return null;
    if (!stack.getCommodityId().equals("LobsterCombatant_CombatLobster")) return null;
    return Global.getSettings().getSpriteName("ui","icon_crew_elite");
}
so a few things to note about this function:
1) anytime this function runs 'return null' it basically just exits the function. that's to say, when you return null here its just saying you don't want to add a icon to this image.
2) 'if (!stack.getCommodityId().equals("LobsterCombatant_CombatLobster"))'. this is important, because without a line exiting this code when the commodity we want is not present, this icon would be added to all commodity's. something that might be useful to someone, but not me right now.
3) the returned value, 'Global.getSettings().getSpriteName("ui","icon_crew_elite")' is a value gotten from the base games settings.json file. the "ui","icon_crew_elite" is just the icon used to represent max level marines in the base game.

lastly, although im not going to show it in this example: this does allow for dynamic commodity 'rank icons'. just gotta use some if statments.
and here's what this would look like in game:

[close]
second example
you can use any sprite from any category you want. just remember: the sprites top right conner will always match up with your commodity top right conner. so make sure your sprites are organized properly to avoid any issues.
as an example: changing the icon to something that's not meant to be a RankIcon:
Code
@Override
public String getRankIconName(CargoStackAPI stack) {
    if(stack == null) return null;
    return Global.getSettings().getSpriteName("systemMap","icon_jump_point");
}
results in:

something you might notice, this is effecting all commodity in my inventory (but not special items, like the blueprint package that's present). this is because i removed the line that filters out all other commoditys. just to show you that you can.
[close]
[close]
[close]
lastly, i would like to link my little mod i mad for this tutorial, so you may look at it for examples, if you so wish: https://github.com/Alaricdragon/LobsterCombatant/tree/basic_Commoditys
« Last Edit: May 23, 2024, 01:08:31 PM by alaricdragon »
Logged

Akarthus

  • Ensign
  • *
  • Posts: 8
    • View Profile

How would I make a NPC market have an industry I just created?
« Last Edit: April 01, 2024, 01:41:43 AM by Akarthus »
Logged

Akarthus

  • Ensign
  • *
  • Posts: 8
    • View Profile

nvm I figure it out, for 3 hours I realized I was building project instead of building artifact

and for another 2 I had the names in all lower case since with Cap didn't work (didn't work since I didn't build it)

I want to bang my head on a wall.
Logged

alaricdragon

  • Commander
  • ***
  • Posts: 190
    • View Profile

nvm I figure it out, for 3 hours I realized I was building project instead of building artifact

and for another 2 I had the names in all lower case since with Cap didn't work (didn't work since I didn't build it)

I want to bang my head on a wall.
Well, I'm glad you figured it out.
I tbh forgot that adding a industry to one of the starting markets was a thing. That's something to keep in mind if I ever end up creating a full tutorial on how industry's work, although that's outside of the range of this simple commodity tutorial. Also, it's not something I have ever done.
Anyhow good luck on your endeavors!
Logged

alaricdragon

  • Commander
  • ***
  • Posts: 190
    • View Profile

ok, so i added a section i forgot to make when i was first building this. this new section covers how to make a commodity change its image dynamically, or how to add / change a commodity's 'rank icon' dynamically.
enjoy
Logged

Zloysvin

  • Ensign
  • *
  • Posts: 1
    • View Profile

I just wanted to say "Thanks" for this amazing guide. Honestly. it's the best guide on programming that I was able to find, lol. At least you show what need to be done for things to work. And even tho, my idea for a mod doesn't require adding comoddites, this guide still halped me understand so much more.

My main issue with the Starsector modding community, that everyone does all of those cool stuff, but when you try to learn, there's literally no info on that. Programming starter guides, that are there, just tell you how to set up IDE (it's still important, don't get me wrong), but no ones explains even the basics and what to do. API, unfortunately, doesn't have any description, of what is responsible for what. Like, here, for example, I want to create a tab on intel screen - where the hell should I even start?

On the other hand, you can just see how other people made their mods and learn from them. It's okay, but still, confusing, because you need to spend time and understand what the hell they even made, and how it all works, lol.

Anyways, thanks for amazing guide!
Logged

alaricdragon

  • Commander
  • ***
  • Posts: 190
    • View Profile

I just wanted to say "Thanks" for this amazing guide. Honestly. it's the best guide on programming that I was able to find, lol. At least you show what need to be done for things to work. And even tho, my idea for a mod doesn't require adding comoddites, this guide still halped me understand so much more.
thank you very mush for the complement. I am quite happy to help = )

My main issue with the Starsector modding community, that everyone does all of those cool stuff, but when you try to learn, there's literally no info on that. Programming starter guides, that are there, just tell you how to set up IDE (it's still important, don't get me wrong), but no ones explains even the basics and what to do. API, unfortunately, doesn't have any description, of what is responsible for what. Like, here, for example, I want to create a tab on intel screen - where the hell should I even start?

On the other hand, you can just see how other people made their mods and learn from them. It's okay, but still, confusing, because you need to spend time and understand what the hell they even made, and how it all works, lol.

Anyways, thanks for amazing guide!
I hear you. its quite a struggle. it can be a lot of work to even explain things properly to people, so I can see why there are so few guides that go into detail like this one. I find myself linking people to Misc modding questions that are too minor to warrant their own thread a lot when they ask me questions, but I can understand that's just not enough sometimes.
I wish you luck on adding a new intel tab. I know its possible to do with code (What we left behind does it with every single overgrown nanoforge you find, for example. star lords also does it with lords and politics. nexerlin does it with a lot of things but good luck reading that mod) but I don't know anything else about it, so good luck with that.

anyways, I know its a lot of work to understand how on earth starsector even works (and I do agree, we need more tutorials.), but I do wish you luck in your modding adventures regardless. and thanks for the thanks = )
Logged

EliasBailey

  • Ensign
  • *
  • Posts: 1
    • View Profile

so you want to add a item or commodity to the game, but don't know were to begin, or simply cant understand one small step of the process?
well, don't worry! I am here to guid you though this task.
in this tutorials, we will cover the following:
1) how to add a item to the game
    -what the requirements are for a items sprite
    -how the CSV file works, and what every variable in it means, and how to set yours up.
    -how to give your item a description
2) multiple methods of how to make a item show up in game
    -adding a item to the in game economy, and how that effects were the item is sold in markets
    -how to add items to the players inventory with code
3) how to change your items description dynamically (based on how literally anything you could think of)
    -adding text to a items description
    -adding 'F1 to show more' text to your items description
4) how to dynamically change the way your commodity looks
    -how to change the 'icon' your commodity uses
    -how to add a 'rank' icon onto your commodity.
5) and maybe latter, we can talk about 'special items' but not now sorry

sprites:
Spoiler
# requirements for a sprite:
Spoiler
so, the requirements are as follows:
1) *the image size should be 100 by 100 pixels or less.*
although you can have images larger then this, it will be larger then the 'box' that you can put a given commodity in and will look weired.
also, feel free to have images smaller then this. the game seems to handle even weird height/width ratios well enough in my experience
2) *the image should have a transparent background.*
although you can neglect this rule if you want, It will result in your item being very obviously different from the rest of the game. especially whenever you try to pick the image up.

besides the 2 rules both, there are not 'requirements' for a sprite. although even the 2 rules I describe can be broken, if you really really want to.

I am not a spiriting expert, so if you don't know how to resize a given image, or how to make a background transparent, i found 2 tutorials for gimp here:
cropping(1:44) and resizing(4:00) a image: https://www.youtube.com/watch?v=dQSlqcMCKx0&t=253s&ab_channel=DoiT8
adding a transparent background: https://www.youtube.com/watch?v=nl2uqKqbryo&ab_channel=EZTutorials
Self-discovery is a journey, whether through personal reflection or engaging in strategic games like Starsector. Just as players refine their tactics and fleet compositions, individuals refine their goals, strengths, and aspirations over time. A well-structured personal statement can help articulate this journey in a way that resonates with admissions officers or hiring managers. If you're struggling to put your thoughts into words, like who am i essay, to solve it ademized offers professional writing assistance to create compelling narratives. Has anyone here ever used professional help for personal or academic writing?
[close]
# were to put your sprite
Spoiler
now that you have a sprite, you need to put it somewhere the game can access.
enter your mod folder, and create a folder named 'graphics'. inside that folder, create another folder named 'icons'. and inside that, create yet another folder named 'cargo'
(please note: you can put your images anywhere in your mods folder, but this is the way most mods are structured, and the base game is structured. so it can help to organize yourself using others organization technics if you plan on your mod having a lot of things in it.)
from there, put the sprite you intend to use in the newly created 'cargo' folder. your setup should look something like this:

please take note of the name given to my sprite. most mods structure there sprites and other not player visible names to have a name like 'myModsName_WhatThisImageRepresentsName'. (were 'myModName' is the name of your mod, and 'WhatThisImageRepresentsName' is the in game name of whatever this image is suppose to be)
you can use always use a different naming structure of course. but if by chance another mod happens to add a image of the same name, at the same location, Weather your mod or theres might end up using the wrong image, and that can be... uncomfortable.
now that you have a image set up in your mod, we can move onto the interesting parts:
[close]
[close]
# the commodities.csv file
Spoiler
so the first thing we need to do is set up the location were the commodities.csv file will go. unlike were your image goes, this is extremely important. if you put this file in the wrong location, starsector will not read it.
enter your mod folder, and create a folder named 'data'. inside that folder, create another folder named 'campaign'.
now, we are going to get a commodity.csv file. because building one ourself is frustrating, im just going to go into the starsector-core and copy theres.
so in the 'starsector\starsector-core\data\campaign folder, and find the file called commodities.csv

now copy and past it into your own mods data\campaign folder

now we need to open it. i use a editor called 'Rons CSV Editor' to open such files, but you might have your own way of opening them.

wow. there is a lot of junk here. feel free to look around at everything, if you want, and try to guess what all the different stats do. I will of corse exsplain them all later.
what i want to do right now, is delete every line below 'supply'. to clean it up a little.
(in Rons CSV Editor, I don't know about others) you can do this by clicking on the numbers on the right, then dragging your mouse down to select multiple lines. then pressing the backspace button

mush more clean!
now, we are going to edit the 'Supplies' name and add a # in front of it. this will make the code ignore that inter commodity, so we don't mess with the base games supply somehow by mistake.
next, we are going to insert a new line both the supply (in Rons CSV Editor) this can be done by right clicking anywhere on the line were the supply's are, and pressing the 'insert row(s) above' option
your CSV file should look like this:

so, now we can start to fill out all the boxes so we can have our commodity
as we do, i am going to talk about what each and every box does, and what you mgiht want to put into it
Spoiler
1) name: the name of your commodity is the name that it will be referred to in game.
    -im going to write: 'Combat Lobster' because: that's what i want this to be called.

2) id: the id is how the game will remember your commodity. -not- to be confused with the 'name' of your commodity
    also note: if your save game has a item of this ID, and you change it (and no other mod or the base game has a commodity of this ID), your game will crash. so please remember that.
    -im going to write: 'LobsterCombatant_CombatLobster' because: I want to follow this equation: modName_commodityName, to avoid other mods from having the same commodityID as me (wish would cause my lobster to override theres, or theres to override mine)

3) demand class: is what the economy will see this commodity as. this should always be equal to a commodity 'id', unless you want the game to pretend its a different commodity (for the sake of economy simulation) (example: 'Volturnian Lobster' is in the 'luxury_goods' demand class, so it acts like a 'luxury_goods' for the sake of economy simulation)
    -im going to write: 'LobsterCombatant_CombatLobster' because: I want my commodity to act as its own thing

4) base price: this is how mush it generally costs to buy this item from markets (before tariffs)
    -im going to write: '250' because: that's how many credits i want one to cost

5) export value: this is how many credits a single unit of demand (on a colony) adds to the global market share for this commodity
    -im going to write: '500' because: I want my lobsters to be somewhat valuable.

6) price variability: this is how mush the price of this commodity in markets can vary depending on demand. so setting it to 3 means the commodity can be 3X the price, or 1/3 the price. at the most extreme.
    note: im not 100% sure on my equation there, but i do know that this is what this does
    -im going to write: '3' because: that's what every other commodity in the game has (that can be brought or sold), and i see no reason to have this cost a different amount

7) utility: How much demand one unit of the commodity satisfies. it is recommended to keep this at 1 most of the time.
    -im going to write: '1' because: I see no point in setting it to anything else

8) origin: probably does nothing, but at some point there was an idea for having exotic commodities that cost more further away from their "origin", still, it might do nothing
    -im going to leave this blank because I see no reason to use this

9) tags: a 'tag' is something that can be attached to a commodity, and can be read by the game or mods. you can add as many tags to a given commodity as you like, but a tag can change a lot of things, so make sure you know what your doing first
    -im going to write: 'military' because: a combat lobster should be 'military'.
    tags that exsist, and there functions, but only as far as i can tell. I miss things sometimes:
Spoiler
    1) military
        the military tag does a few things:
        1) it makes the commodity show up in the military market
        2) it prevents you from trading it in the milatary sub market unless your relations are at least 'FAVORABLE'
        3) makes it so selling this commodity on a market has a increased 'impact' (although, im unsure of what this means)
    2) expensive
        -some commodity based missions will prefer to give you missions based around commodity's with this tag
    3) crew
        -excludes this commodity from participating in procurement missions.
        might be used latter for something else, but its not yet.
    4) personnel
        governs if a commodity uses personnel slots, but only in NPC trade fleets??? (so it effectively does nothing)
    5) marines
        -excludes this commodity from participating in procurement missions.
        might be used latter for something else, but its not yet.
    6) food
        -probably unused for now. might be used latter
    7) medical
        -this is used in getting who you contact in a trade mission. (CITIZEN, or POST_MEDICAL_SUPPLIER. depending on i dont know.)
    8) luxury
        -this is used in getting who you contact in a trade mission. (civ or pirate, depending on if this commodity is legal or not)
    9) exotic
        -probably unused for now. might be used latter
    10) meta
        -prevents you from raiding this item from markets?
    11) nonecon
        -prevents you from raiding this item from markets?
        -excludes this commodity from participating in procurement missions.
        -prevents you from putting this item into your personal stockpile on your own markets.
    12) ai_core
        -lets you assing this item to the AI core sloot at a market
    13) no_loss_from_combat
        -prevents the player from losing this item
    14)no_drop
        -I think this prevents you from getting this item? I don't know though, because i could not find the code for it.
    15)nosell
        -this tag exists in the code, but i cant find were its used. It might be unused
[close]
10) stack size: does nothing anymore. used to determine stack size
    -im going to write: '0' because: it is no longer used

11) cargo space: the amount of cargo space each item takes in your cargo bay.
    -im going to write: '1' because: I think that's fine (you can set it to any number you like though. like 0.01. or 9001 or 0. whatever you think will be fun)

12) icon: the path to the sprite that this commodity uses.
    -im going to write: 'graphics/icons/cargo/LobsterCombatant_LobsterFighter.png' because: that's the path to my file (and the name of my image)
    -if you put your file somewhere else in your mods folder, you will need to write a path to it. and if your image has a different name then mine (and it should) you will need to write that name instead of my images name

13) sound id: the sound this commodity plays when you pick it up
    -im going to write: 'ui_cargo_volturn_lobster because': that's the lobster sound, and i want to use it (feel free to copy any sound from the commodities.csv file)

14) sound id drop: the sound this commodity plays when you put it down.
    -im going to write: 'ui_cargo_volturn_lobster_drop' because: that's the lobster sound, and i want to use it (feel free to copy any sound from the commodities.csv file)

15) order: the order this item will try to be sorted into when you sort your cargo bay. lower numbers means it will be more towards the top right, lower numbers mean it will be more towards the bottom left.
    -im going to write: '3' because: I felt like that was a good number? you can mess with this and see were you want your item to end up in your lists

16) economyTier: The order in which the economy simulation runs. Stuff lower on the production ladder (e.g. ore) needs to have a lower tier than the stuff that's made from it (i.e. metals) to have the simulation stabilize more quickly.
    -im going to write: '1' because: I plan to have this commodity require nothing to be produce

17) econUnitOrigUnused: this does nothing right now
    -im going to write: '0' because: this does nothing

18) econUnit: effects how many units of this commodity are available at a market (per output)
    -im going to write: '150' because: I like the number

19) baseRaidDanger: how mush more dangerous this commodity is to raid compared to others. can be left blank for LOW danger, i think.
    the accepted values of this are:
       MEDIUM
       HIGH
       EXTREME
    -im going to write: 'MEDIUM' because: the lobsters might fight back. (for most things, you should leave this blank.)

20) eU * base value: this is quite literally, what you put in the 'econUnit' slot * by what you put in the 'base price' slot
    -im going to write: '37500' because: 150 * 250 = 37500 (and 150 and 250 is what i put in the 'econUnit' and 'base price' slot, respectively)

21) iconWidthMulti: how close together your icons are on the market screen. smaller values are good for icons that are more tall then wide. higher values can sometimes be useful for wider commodity.
    -im going to write: '1' because: I copied the 'Volturnian Lobster' stats for this.

22) plugin: this does nothing, as far as i can tell.
    -im going to leave this blank because: this does nothing

23) desc: this does nothing. a forgotten bit of data from a lost age. if you want to add descriptions to your items, i will show you soon.
    -im going to leave this blank because: this does nothing
[close]
now after setting up all the varubles there (or just copying something from the base games commodity.csv file, and changing the id to something different) your commodities.CSV file should look something like this:


FAQ:
    Q: how do i make my commodity take crew space, or space in my fuel tanks
    A: as far as i can tell, there is no way to do so. maybe someday we will find a way.

    Q: I want to make my commodity make a custom sound when you pick it up / drop it
    A: I dont know how sounds work, to my shame. however, what i do know is:
        1) there is a sounds.json in the config folder of starsector-core that you could look at
            -the sound ID that you input into the 'sound id' and 'sound id drop' are found here, and link to a file in the 'sounds' folder found in starsector core.
        2) there is a sounds folder in the starsector-core that you could look at.
            -the sounds themselfs are found here.
        if you want to structure your mod like the main starsector (don't know if its important or not) create a sound folder in your mod folder, and create a sounds.json in your /data/config folder.
        if you look at the sounds.json structure, you should be able to understand it (although it might be easier to learn from mods with less sounds)


we are now going to check out our commodity in game. so lets save and close the CSV file
i advice you to download and install the 'console commands' mod (https://fractalsoftworks.com/forum/index.php?topic=4106.0) for this part, so you can test out your commodity
enable the game, and press 'CTRL' + 'SHIFT' + 'BACKSPACE' to open the console commands
then type in the following command:
'addItem commodityID'
were 'commodityID' is replaced with the ID of your new commodity you added to your CSV file
and if all went well, there it is!

but wait, if we move our mouse over the commodity, as some of you may have expected...

there is no description!
[close]
# the descriptions.csv file
Spoiler
now we need to add a description to our commodity. and there are a few ways to do this. we will be starting with the descriptions.csv file.
first, go into your mods data folder, and create a new folder named 'strings'
from there, we are going to go into starsector\starsector-core\data\strings and copy and past its own 'descriptions.csv' file into our newly created string folder
your new strings folder should now look something like this:

now we are going to open the newly copied CSV file. and then we are going to delete every line but the one at the top, and the category line
your CSV file should now look like this:

now, we are going to start to change this to match out own commodity.
first, change the id section to say your commodity id (so i would change 'lightmg' to say 'LobsterCombatant_CombatLobster')
second, change the type section to say 'RESOURCE' (so i would change 'WEAPON' to say 'RESOURCE') (also, the reason for this is to let the game know that this is looking for a commodity. it -will not- work if it says anything else, because you have a commodity that you want to have a description)
lastly, change the text1 section to say.. whatever you want your description to be (so i would change... i bunch of text to say 'mean, lean, fighting lobster')
and that's it! your new description is completed. here what mine looks like for reference:

also, ignore all the other sections (text2,text3,text4,notes) they are not needed here
if you start up the game, and give yourself one of your commodity again, it should look like this

and that's all for the basic of descriptions.
[close]
# advanced descriptions
Spoiler
in this section, we are going to cover something slightly more advanced for the first time.
if all you want to do is make a commodity and have it in game, skip this section.
if you for some reason want the following:
1) highlights in your description
2) the ability to change your description with code
3) the ability to change what is displayed when your press f1
then please read this section

so for advanced descriptions we are going to need 3 things:
1) create a new class and name it 'modName_CommodityTooltipModifier' were 'modName' is the name of your mod.
   next, make the new class 'implements CommodityTooltipModifier'
   your new class should look like this:
   
2) in your main java class (the one your mod_info says is your 'modPlugin')
   add the following function:
   @Override
   public void onGameLoad(boolean newGame) {
       super.onGameLoad(newGame);
   }
   your modPlugin should look something like this:
   
3) add your newly created 'modName_CommodityTooltipModifier' class as a transient listener. (note, you can make it none transient if you want it to rembmer data, but if you do, I advice you to make sure you dont add one if the listiner is already present (make it so it only adds if new game is true or something maybe?))
    you can use the following function to add such a listiner:
    Global.getSector().getListenerManager().addListener(new modName_CommodityTooltipModifier(),true);
    now your modPlugin should look something like this:
   

and that it! the hard part is done.
now its time to write your description. i will show you a simple example, but for more advanced things (like images, or crazy things) you will need to look up how to use the 'TooltipMakerAPI' on your own.

so, i would like to explain a few things about this.
1) line 15 is so this code will only effect the one commodity. if i didn't have that if statement, this would effect every stack of items in the game.
2) line 17 and 18 show how to create and highlight text. the text i want to highlight will always replace the %s in the first inputted text. this lets you have things like variables, instead of just static strings be added to your descriptions
3) line 21-23 show how to display text only when the text is 'expanded'.
now for showing it in game:
not expanded:

expanded:

and that's all for 'advanced' descriptions. simple i hope.
[close]
# Implementation
Spoiler
so you made it. and now we are here.
the question that must be asked, the one you have felt, silently at the back of your mind:
'how do i actually see this in game without commands'
and oh boy.. im glad you asked.
there are 3 ways to see a commodity in game without commands:
1) by making it so the item can be found and looted on things like ruins, salvage stations, and random kites outside the core worlds:
   https://fractalsoftworks.com/forum/index.php?topic=15244.0
2) by adding it to the players cargo with code:
    Global.getSector().getPlayerFleet().getCargo().addCommodity("LobsterCombatant_CombatLobster",100);
    you can replace the "LobsterCombatant_CombatLobster" with the ID of the commodity you want to add, and the 100 with how many of said item you want to add
    this can be useful when giving rewards for quests and, or other events.
    you can also use the addCommodity("LobsterCombatant_CombatLobster",100); function on any cargo in existence, if you so desire.
3) by adding it to a markets supply and/or demand (and therefore, a markets sub markets).
    with this, there are a few ways to go about it:
        1) adding your commodity to a industry supply / demand remotely
        2) replacing a industry so it makes your commodity.
        3) creating a new industry that makes your commodity.
    I will go over each of the options here in soon, but i will focus on number 1. the others will only get a quick description, or we will be here all day.

    1) adding supply and demand without overriding or creating industry:
Spoiler
        this is... different. it can cause lag, but it allows for the ability to add supply and demand without worrying about your code being overridden.
        also, normally when doing something like this, i use the marketRetrofits library, as it has a lot of things to help me run code more efficiently, but im not ready to create even a basic tutorial on how to use that yet, so here we are.
        so, lets get started! I will try to explain what we are doing as we move along:
        1) create a new class, and make sure it 'implements EconomyAPI.EconomyUpdateListener'. also, add the functions it wants you to.
           
        2) now add this newly created class as a 'UpdateListener' using the following command in your modplugin:
            Global.getSector().getEconomy().addUpdateListener(new modName_BaseCampaignEventListener());
            now your modplugin should look something like this:
           
        3) and now for the fun part! adding supply or demand to a industry. for this, go back to the class you made (the one that implements the 'EconomyAPI.EconomyUpdateListener' class).
            so, what you need to do here can vary a lot depending on what you are going to do, so my first example is going to be extremely basic, but the example is going to increase in complexity as we move on.
            so for the first example:
           
            so in this example, im adding 'Combat Lobster' as supply on lions guard HQ's, and im adding 'Combat Lobster' as demand on heavy battery's. there are a few parts to this that i would like to point out
            lines 17-20 are variables. i didn't need to make everything a variable, but it makes it easier to read and modify, so i did so.
            on line 22 we have a for loop. it loops over every market in the game. all of them. you don't need to do this, unless you want to check every world and apply demand or supply changes to industry's on every one, wish i do, so i have.
            on line 24 - 27, we see how to add supply. I would like to explain this in detail, line by line. so please read this if you want to fully understand whats going on here.
            line 24: this if statement prevents us from trying to run functions on a industry that does not exist, and crashing the game.
            line 26: this is a important line, the line that actually lets us add supply to a industry (and by extension a market) remotely. a few things to note however:
                market.getIndustry(supplyIndustry).getSupply(commodity).getQuantity().modifyFlat(source, market.getSize()-1);
                'supplyIndustry' needs to be the ID of a industry.
                'commodity' represents the ID of the commodity you want to add.
                'source' this is the 'source' of this modification. don't leave this blank please, as if anyone else try's to modify said supply or demand on the same markets industry's commodity, they might overwrite yours (or you might overwrite theres) because if the source is the same, the game assumes you mean to overwrite anything else with the same source. so be careful.
                'market.getSize()-1' is the quantity of commodity this industry should produce. it can be any integer, but most commodity have an equation using 'market.getSize()', so the market can have more commodity demand / supply when it gets larger.
            on lines 28 - 31, we see how to add demand. the function is exactly the same as lines 24 - 27, but we run 'getDemand' instead of 'getSupply'.

            we can also look and see how this looks in game
           
           
            as you can see, the lions guard is now producing lobster, and the heavy battery's are demanding it...
           
            across the inter sector!
            so you will see 'combat lobster' in trade fleets, in markets were it is demanded / supplied. everywhere. you can even get missions for combat lobster delivers.
            your commodity is completely implemented into the economy. congratulations

            ok, some design pacific issues that i would like to mention:
                1) my lobsters are only being built at the lions guard HQ. and not at worlds that have lobster.
                2) my lobsters are only being demanded at heavy battery's, and not at ground defences?
            so lets fix that:
            fair waring: this code is more complicated then the last, because i like this idea and want something good. also, i am terrible at explaining complicated things.
Spoiler
           
            so, if you look at this and think 'what?' don't worry, understanding something like this is not required. this is more of a bonus section for my own peace of mind then anything.
            so, lets go over the changes:
            lines 16 - 22 have changed in 3 ways:
                1) a new string called 'condition'. this references the market condition that will be required to add lobsters to the world.
                2) both 'supplyIndustry' and 'demandIndustry' are now arrays. this is for letting me have multiple industry have as supply or demand easier
                3) the new arrays called 'supplyValue' and 'demandValue'. this represents supply and demand + marketSize values of each industry (in supplyIndustry and demandIndustry respectively).
            lines 26 - 35 have changed in 3 ways.
                1) a new if statment stops supply from being added to markets if the 'volturnian_lobster_pens' is not present.
                2) i now run a for loop, going through all items in supplyIndustry and adding supply to them.
                3) i now run a a equation, involving supplyValue[a] to determin the amount of supply on this industry.
            lines 36 - 41 have changed, the same as lines 26 - 35, but without the if statement.
            things to note:
                if you wanted to modify this for your own needs, make sure 'supplyValue' and 'demandValue' are at least as long as 'supplyIndustry' and 'demandIndustry' respectively, or you will get a crash.

            if you don't understand this, please don't be afraid. this was something i needed to add because it was bugging me that if you played a mod that let you get lobster on one of your worlds, you would not beable to train combat lobster.
[close]
[close]
    2) replacing a industry:
Spoiler
        if you want to know how to replace a industry...
        1) copy the industry.csv file (placing it in the data\campaign folder of your mod folder),
        2) delete everything but the industry you want to replace,
        3) change the plugin to something in your own mod, that extends the previous plugin (if you dont know what the previus plugin was, its in the plugin section. it should be after the last '.' in the line),
        4) then in the apply() function (that you should override) run both super.apply(); the following command:
           supply("LobsterCombatant_CombatLobster",5);
            you can replace the "LobsterCombatant_CombatLobster" with the ID of your commodity.
            you can replace the '5' with the amount of this commodity you want this market to produce.
            please keep in mind: most commodity output increases with market size. so its wise to use an equation like:
            supply("LobsterCombatant_CombatLobster",market.getSize() - 1);
            (so the industry will produce '2' at size '3', '3' at size '4', '5' at size '6', and so on)
            (you can also do the same thing for the demand a industry has with the 'demand("LobsterCombatant_CombatLobster",5)' function)
        here's what your CSV could looks like (I overrode the lionsguard industry)
       
        please pay attention to the plugin section. its the only section i changed, and the only one you need to change with this method.
        here's what your code should look like
       
        this is what your code should look like, although what 'supply' you are adding, and what class you are 'extend' might be different
        we can even see the changes in game!
       
       
        please note this method has some issues:
        1) if anyone else try's to do the same thing to the same industry, one of your plugins is going to be overwritten, wish can cause issues
[close]
    3) creating your own industry
Spoiler
        if you want to create your own industry for your commodity.. it has less isuees, but can be a pain.
        1) copy the industry.csv file (placing it in the data\campaign folder of your mod folder),
        2) delete everything but the industry you want that you think costs an OK amount,
        3) change the plugin to something in your own mod, that extends BaseIndustry,
        4) then in the apply() function (that you should override) run the following command:
           supply("LobsterCombatant_CombatLobster",5);
            you can replace the "LobsterCombatant_CombatLobster" with the ID of your commodity.
            you can replace the '5' with the amount of this commodity you want this market to produce.
            please keep in mind: most commodity output increases with market size. so its wise to use an equation like:
            supply("LobsterCombatant_CombatLobster",market.getSize() - 1);
            (so the industry will produce '2' at size '3', '3' at size '4', '5' at size '6', and so on)
            (you can also do the same thing for the demand a industry has with the 'demand("LobsterCombatant_CombatLobster",5)' function)
        here's what your CSV could looks like (I used the lions guard industry as my base)
       
        this time, instead of only changeing the plugin, i also changed the id,name, and description
        although, you technically only need to change the plugin and id for this to work, it can get confusing for players if you don't at least also change the name.
        here's what your code should look like
       
        this is what your code should look like, although what 'supply' you are adding, and your classname might be different
        we can even see the changes in game!
       
       
[close]
    and that's all i will be talking about, in relation to creating and modifying industry in this tutorial.
    if i find/create some good tutorials on how to do this, i will likely put them -->here<--
[close]
#changing the image of your commodity
Spoiler
so this is something i have always wanted to do, but never figured it out. turns out, its relatively simple.
but before we can talk about how this works, we need to set up the listiner.
setting up the CommodityIconProvider
so first we set up a new class that implements blank. it should look like this:
Code
public class LobsterCombatant_Commodity_iconAndImageChanger implements CommodityIconProvider{
    @Override
    public int getHandlingPriority(Object params) {
            return 0;
        }
    @Override
    public String getIconName(CargoStackAPI stack) {
        return null;
    }

    @Override
    public String getRankIconName(CargoStackAPI stack) {
        return null;
    }
}
next, you are going to want to add this class as a plugin in your 'onGameLoad' function in your mod plugin. your mod plugin should now look like this:
Code
public class LobsterCombatant_startup extends BaseModPlugin {
    @Override
    public void onGameLoad(boolean newGame) {
        super.onGameLoad(newGame);
        Global.getSector().getListenerManager().addListener(new LobsterCombatant_CommodityTooltipModifier(),true);
        Global.getSector().getEconomy().addUpdateListener(new LobsterCombatant_BaseCampaignEventListener());
        Global.getSector().getGenericPlugins().addPlugin(new LobsterCombatant_Commodity_iconAndImageChanger(),true);
    }
}
(keep in mind: I left the 2 other listeners active. only the 3rd one is new, and required)
now that that's set up, we can go onto doing something more interesting.
[close]
getting a custom image for your commodity's sprite or 'rank icon'
so, im putting this here so i don't need to repetitively explain this.
first, you are going to want an image. if you are creating a sprite for your icon, see section one for how to add a sprite to your game. if you are creating an icon, do the same thing. but keep in mind the size of your icon, as icons in general are mush smaller then commodity images
secondly you are going to need to put this image somewhere. most images go into the graphics folder of your mod. but it does not matter so long as the image is in your mod folder. i would recommend keeping said folder organized though.
lastly, there is the part we have not yet talked about. the setting.json file. this can be done in _ steps
1) go into your mod folder and create or navatage to the data/config folder.

2) create a new text file and name it 'settings.json'.
    -if you are unable to change file extensions, go into your main starsector folder, then go into starsector-core/data/config and copy the setting.json file into your data/config. then remove all the files within your newly copied settings.json.
the resulting folder should look like this:

3)now you are going to want to open your settings.json folder, and add the following lines
Code
{
  "graphics": {
    "misc": {
      "LobsterCombatant_ExstraLobsters": "graphics/icons/cargo/LobsterCombatant_LobsterFighter.png"
    }
  }
}
of course, you should not use the name 'LobsterCombatant_ExstraLobsters' instead, use something like "youModName_whatThisIs"
also, the second part 'graphics/icons/cargo/LobsterCombatant_LobsterFighter.png' should be the path to the image you want to act as an 'rank icon' or 'sprite'.
lastly 'misc' is only one of many category's you can use when adding graphics to starsector. I dont know what all of them do, so i just tend to use 'misc'

4) lastly, when you use this type of code, you should use a line like 'Global.getSettings().getSpriteName("misc","LobsterCombatant_ExstraLobsters");' to get the sprites 'name' (aka, what the game uses to get sprites from its index)
-also, the "misc" should be whatever catagory you put your sprite in (mine is misc)
-also, your "LobsterCombatant_ExstraLobsters" should be the name you gave your json variable. not something like the image name.

[close]
changing your commodity's 'sprite'
so, what is this?
simply put, its a way to change that image represents your commodity in your inventory (or in other innovators, like in the open market).
as for why? its useful if you want to dynamically change the image of an commodity. like what crew and marines do, depending on the number of them in your inventory.
so lets give an example:
Code
@Override
public String getIconName(CargoStackAPI stack) {
    if(stack == null) return null;
    if (!stack.getCommodityId().equals("LobsterCombatant_CombatLobster")) return null;
    if (stack.getSize() < 150) return null;
    return Global.getSettings().getSpriteName("systemMap","icon_jump_point");
}
in this example, the sprite of my Combat Lobster remains normal, until there is more then 150 in a stack. then it gets turned into a vortex. like normal lobsters do.
so some things to note here:
1) anytime this function runs 'return null' it basically just exits the function. that's to say, when you return null here its just saying you don't want to change the sprite of this image.
2) 'if (!stack.getCommodityId().equals("LobsterCombatant_CombatLobster"))'. this is important, because without a line exiting this code when the commodity we want is not present, this icon would be added to all commodity's. something that might be useful to someone, but not me right now.
3) the returned value, 'Global.getSettings().getSpriteName("systemMap","icon_jump_point")' is a value gotten from the base games settings.json file. the "systemMap","icon_jump_point" is just the icon used to represent jump points on the map in game? maybe i don't remember..

note: both inventory spaces have combat lobsters in them. but one has enough lobsters to create a lobster vertex.
[close]
changing your commodity's 'rank' icon
so first thing first: what does this even mean?
its relatively simple. a commodity rank icon is the thing you see on, for example, marines in the top right conner. although saying that is a rather limited interpretation.
a rank icon is a image that goes on top of your commodity. this images top right conner is always at the top right conner of your commodity. this image can be as large and as small as you like. so let your imagination go wild with that.
and yet. this does work in congregation with changing your commodity's sprite.
so, let me give you an example of this in practice.

basic example
Code
@Override
public String getRankIconName(CargoStackAPI stack) {
    if(stack == null) return null;
    if (!stack.getCommodityId().equals("LobsterCombatant_CombatLobster")) return null;
    return Global.getSettings().getSpriteName("ui","icon_crew_elite");
}
so a few things to note about this function:
1) anytime this function runs 'return null' it basically just exits the function. that's to say, when you return null here its just saying you don't want to add a icon to this image.
2) 'if (!stack.getCommodityId().equals("LobsterCombatant_CombatLobster"))'. this is important, because without a line exiting this code when the commodity we want is not present, this icon would be added to all commodity's. something that might be useful to someone, but not me right now.
3) the returned value, 'Global.getSettings().getSpriteName("ui","icon_crew_elite")' is a value gotten from the base games settings.json file. the "ui","icon_crew_elite" is just the icon used to represent max level marines in the base game.

lastly, although im not going to show it in this example: this does allow for dynamic commodity 'rank icons'. just gotta use some if statments.
and here's what this would look like in game:

[close]
second example
you can use any sprite from any category you want. just remember: the sprites top right conner will always match up with your commodity top right conner. so make sure your sprites are organized properly to avoid any issues.
as an example: changing the icon to something that's not meant to be a RankIcon:
Code
@Override
public String getRankIconName(CargoStackAPI stack) {
    if(stack == null) return null;
    return Global.getSettings().getSpriteName("systemMap","icon_jump_point");
}
results in:

something you might notice, this is effecting all commodity in my inventory (but not special items, like the blueprint package that's present). this is because i removed the line that filters out all other commoditys. just to show you that you can.
[close]
[close]
[close]
lastly, i would like to link my little mod i mad for this tutorial, so you may look at it for examples, if you so wish: https://github.com/Alaricdragon/LobsterCombatant/tree/basic_Commoditys
Thanks for sharing, I will surely try it.
« Last Edit: February 03, 2025, 05:36:29 AM by EliasBailey »
Logged