Skip to content

the games programming systems

yoel123 edited this page Oct 21, 2020 · 20 revisions

api do you speak it

the big idea is: make everything easy to use, accessible using one or two methods to manipulate the feature you want.

let's say you want to add a structure (just a hypothetical example), you add it to the structure database, and if it has a special event add it at the method "stractures_spacial_events" at stracture_manger.java in:game objects package.

now you can add 10 of these with their own stats and events, by just adding to the database and a method in some class. no need to reinvent the wheel or think about what to do where etc.

lets start

item system:

add an item:

go to db packge, then open item db, inside the method gen_items() after all the item add:

db.put("item name","item name",5,0,2,1,30");

the first string is the handle that will be used to call the item using db.get("item name").

the second string is the data separated by a comma here is the data table columns: //name,amount,paid,cost,min_price,max_price

so in "item name" the 5 is the amount then 0 is how much was paid for the item of this type,2 is the current cost , 1,30 is the price range from 1-30.

all items will be added to the market items attribute, items data is stored on the item class that acts as a modal for the data (item.java is inside game_object package).

the items owned by the player are stored on the player class on items ArrayList (its an arraylist in market too).

player class has a few methods to manipulate its items. buy,sell,get_item(by name), and items_list(returns a string list of players items).

let's say we want to make an event that requires the player to have 3 engines for some reason.

to get the engine item handle (from player) we will write:

item e = game_manger.p.get_item("engine");

this can be done from any object in the game.

if the player never got an engine e will be null check it like that:

if(e==null){/*do somthing*/}

now lets check if he has 3 of these (if e is not null):

if(e.amount>3){/*do somthing*/}

need to remove 3 engines?

e.amount-=3;

market system

obviously, it heavily uses and relies on the item system.

what it does is handle buying selling and displaying items.

its methods are mainly on market.java and player.java in game_objects package.

in market.java, we have methods that deal with the market's supply and demand (supply_and_demend_gen method),display_all method returns a string with all of markets items , and a method that just gets the items price by items position in the items ArrayList get_item_price.

pupulate_items fills the items ArrayList inside market with all the items inside item db.

the player also has an ArrayList of items why? simple the player has items he owns and thers the items available for trade in market, both are different things.

the markets supply_and_demend_gen changes the prices and amount of items in the market, for now it does this randomly for each item in the items ArrayList in the market.

the players item prices change to the market items using markets update_player_item_price method its called when the player wants to sell items in market_screen under the method do_sell like tis:

game_manger.m.update_player_item_price(game_manger.p);

player has buy and sell methods to manipulate his own items, get_item method will get an item modal by name from players items, items_list method will return a string with all the players items.

buy method gets an item and the amount of the item you want to buy, it calculates the price and all the rest inside.

sell method is the opposite of buy, it adds credits and reduces an item amount, it gets a price (price per item) after the amount because some events let you sell items at different prices than its attribute price\cost. it also calculates the tax you owe from the sell and adds it to tax owed, so if you want to sell on "black market" dont use sell.

for both sell and buy return a boolean, if a buy or sell item succeeds it will return true.

example use in smuglers_sell event in do_event in event_manger.java:

				//check if can buy
				if(game_manger.p.buy(goods_to_sell, goods_amount)) 
				{
					cio.println("done deal");
					messge = "done deal";
				}else 
				{
					cio.println("deal failed (you dont have enough credits");
					messge = "deal failed";
				}

that's how players buy method is used, can be used like this all over the project. it could have been sell method, with minor changes.

event system

there are 3 types, for now, events you activate in events screen, immediate events that happen as soon as they appear (you see their results on event screen the same turn they happen, and long term events to handle events that happen after a few turns.

all possible none long term event that can happen are stored on the event_db from this pool events are generated.

regular events and immediate events that happen or can be activated are stored on the players events ArrayList attributes.

those events are added using random_events method of event_manger class (random_events also clears all previous none long term events).

random_events runs inside game_manger inside pass_turn method once the players selects the pass turn option in the games main menu.

inside game_main screen show_events shows all the activatable events and immediate events that happened this turn. it asks the player to select an event, and then the event runs in do_event method of event_manger.

inside do_event thers all of the activatble events logic like:

if(action.equals("smuglers_sell")) 
		{

will run if its a smuglers_sell event (there can be a couple of events that have the same action in the database).

each event logic is special as it meant to change the games pace a little.

immediate events are run as soon as random_events methods pick one.

the logic of immediate events is inside do_immidiate method like:

                //events that cause you to loss money
		if(action.equals("money_reduce")) 
		{

as you can see its the same as do_event the difference is that you don't ask for user input, immediate events resolve automatically.

like activatable events, the action logic can be used with multiple events in the database, "money_reduce" action can be a "meteor shower" or "armed robbery"(this event type can be negated by buying insurance we don't want an event that breaks the game).

and it can have any type of logic you can imagine.

long term events are a bit different they work with counters,as they are events that happen after a few turns, the counter collection and the current counter list are attributes of player class:

counters_list is an ArrayList and attribute of player.java it holds the names of all long term events currently waiting to happen.

counters is a IndexableMap and attribute of player.java it holds the counter count and the max value it will count to (done behind the scenes using methods (inside the player class):

add_counter is a method that adds a counter, it gets the name and the duration example: add_counter("bla bla",3) this means bla bla will happen in 3 turns.

add_counter_once is the same as add_counter but it won't add the counter if its already exists in counter ,useful if you want one instance of a certain long-term event.

remove_counter does exactly what it says, removes a counter by name lets say we want to remove "bla bla" we will call remove_counter("bla bla").

reset_counter resets a counter by name, in case you want the long term event to run from the start again.

each pass_turn the counters will be updated using long_term_events_update of the event_manger class. once a counter is finished do_long_term_events will run (also inside event_manger ).

do_long_term_events is where the event happens, like immediate and activate events each event has its own unique logic :

if(name.equals("worker_union_fine")) 
		{

for example inside this if is the logic that will happen once the timer for worker_union_fine ends, the player will get a fine for not paying his employees.

and thats how the event system works, the code itself is not complicated to read once you know what it does.

tax system

this one is a smaller system, most of it is in player.java.

in short, tax is added when you sell stuff, if you don't, a counter will start for a long-term event, hen it ends you will get a fine.

i made this before i had the long term events counters.

add_taxes method inside player is how you add taxes from player earnings, it gets the earnings multiply it by the tax_rate which is a player attribute, and adds the result of that calculation to taxes_owed.

taxes_owed is how much tax you owe.

update_taxes is a player method that runs every pass_turn.

update_taxes checks if you owe taxes if you do it incraments didnt_pay_taxes_c attribute which is the counter that counts how many turns you didnt pay all your taxes. paying taxes resets didnt_pay_taxes_c to 0.

if you dont and the counter exceeds 13 taxes_problem boolean attribute turns true. then you're in real problems.

but before that if(didnt_pay_taxes_c>didnt_pay_taxes_max) you will get a fine (tax increase).

pay taxes functionality is in mangment_screen under pay_taxes there the player is asked if he wants to pay taxes, if he does, the amount he chose to pay goes into player class pay_taxes method.

and that's it for taxes, its a simple system for now.

station personal system

the station personal are used in events and calculating stats and other modifiers.

general workers and engineers are used to maintain the station and its system, there will be a minimum number you need to run the station.

guards are used for all security-related stats and events.

all these are managed using station_personal class inside game objects package.

station_personal is also an attribute in player called s_personal it holds an instance of station_personal.

to access station_personal simply write:

game_manger.p.s_personal

from anywhere within the project.

all of players station personal are stored on station_personalclass attribute called plist which is an IndexableMap used to store character class.

character is a very flexible class it has two IndexableMaps one for stats and one for traits, in station_personal a character is used to describe a group o people like workers/guards, etc. usually character will be used to describe a single character.

using station_personal class to add personal type thars create_personal method it gets three arguments:String name,int amount,int salary.

let's say we want to add a guards type with the amount of 2 and salary of 300 per turn:

create_personal("guards", 2,300);

now we will add 3 more guards:

add_personal("guards", 3);

thers also a method to remove personal (incase you fire them etc etc):

remove_personal("guards", 3);

this will remove 3 guards.

calculate_salery will return all of the station's personal salary that needs to be paied for this turn.

the actual salary you need to pay from the last turns is stored on payments_owed attribute.

in player thers a method called incrament_sallery_owed it does what it says it does, it incraments the salery you owe all of your orkers this turn to payments_owed in the station_personal instance in player.

incrament_sallery_owed is called every pass_turn

inside pass_turnwe have an if:

	//if owe personal payments
		if(game_manger.p.s_personal.payments_owed>0) 
		{
			game_manger.p.add_counter_once("worker_union_fine",12);
		}

if you don't pay your workers a timer will start, if you dont pay your workers you will get a fine.

in pay_sallery in player once some of the salery is payd the counter is removed:

remove_counter("worker_union_fine");

you need to pay at least 200 credits for the counter to stop.

if the time fires the long term event, inside event_manger inside do_long_term_events thers an if for worker_union_fine:

if(name.equals("worker_union_fine")) 
		{

the code inside that if will increment the times you got a worker union fine:

game_manger.p.s_personal.union_fine++;

the fine is multiplied by the times you got it and once you get too many, your business gets closed.

upgrade system

this one is the easiest, goto upgrades db, add the upgrade, and that's it, it's available to buy on management screen. //upgrade name,price,desc db.put("better_plumbing","better_plumbing/500/better plumbing will make your station plumbing system degrade slower and easier to fix");

that's an example upgrade the name is:better_plumbing it costs 500 credits and after that is the upgrade description.

the upgrade will be added to the upgrades the player can buy.

what will it do depends on you, you can call the players upgrades for anything.

so you can check if a player has an upgrade every pass_turn and then do something, or check if the player has a certain upgrade inside an event, lets say its a robbery event, check if "the player has the advanced security" upgrade then don't do the negative part of the event. or an event that increases supply and demand or anything you can think about.

that's it, you add an event and program what it does somewhere so it will do something.

edit upgrade logic now has its own file called upgrades_system it's inside game_objects package.

upgrades also may have requirements so the new upgrades table columns are:

//upgrade name,price,desc,requirement

requirement is a string of other upgrade names separated by a comma.

some upgrades need you to have other upgrades operational

marketing system

marketing is used to get more goods in the market or advertising rent space.

for now you can market for goods on marketing_system in market_goods

marketing for goods increases all the goods amounts next turn for one turn.

the more you pay for goods marketing the more people see it the more goods will come to your station (you asked for it).

station damage system

critical systems can be damaged and also upgrades.

damaged upgrades cant be used (except for ones that give you a permanent bonus).

critical systems can do a lot of problems.

each turn your engineers will fix damages at the cost of supplies (if you have supplies).

the more engineers you have the faster the repairs will be, see damage_system.update_damege_effects that method runs every pass_turn.