It's a game with space fighting in it, and I think I have the AI decently coded in terms of combat. However what I've been TRYING to do is make some sort of adjustment to their combat skills in relation to the difficulty level, which goes from 1 to 10.

One thing I tried was, in the routine where the ship determines which way it needs to face, I'd add a random angle left or right, which was scaled by the difficulty so that lower difficulties would result in a greater value added to shift the angle. So essentially what that did was every frame the ship would make its calculations and adjust its aim toward the ship, but offset by a certain amount so that the easier the difficulty, the worse their aim.

This did in fact make the game easier, but it looked silly. Every frame the ships would wiggle back and forth because the random factor would be different every frame and that caused some problems with it being sensible, and sometimes a ship would so often think that it was "way off aim" that it would rarely fire at a target sitting still right in front of it.

So if you guys could just shoot at some stuff for a bit (you have to do some actual damage to a ship otherwise most of them who are set to friendly won't attack you until you really convince them you're NOT friendly ) and try to help me come up with new ideas to adjust how they fight, that'd be great!

Even if your suggestions aren't really about making the difficulty change, just about modifying the AI, I'd greatly appreciate them all! Thanks

i suggest one of two things:(1) scrap the random angle function altogether, and let the amount of damage done by a direct hit be adjustable so that at easier levels, less damage is incurred by each direct hit (this will achieve the same effect of your random angles, because in either case, the hit points of the player are preserved at easier levels) or(2) don't add a random angle to each frame or cycle of the routine in which the ship determines which way it needs to face. this is what cause the wiggling, stalling and silly look. instead, let the random function come in every fifth, or tenth or hundredth routine. this will make the direction seeking seem smoother, and still allow for poor aim at easier levels.

scrap the random angle function altogether, and let the amount of damage done by a direct hit be adjustable so that at easier levels, less damage is incurred by each direct hit

That's an inverse of the usual smarter enemy approach in production strategy games, the "smarter" AI actually just produces more stuff than the player can. Instead of making the AI smarter or dumber the AI breaks the game rules to be more or less powerful. That's not much fun and always feels like a bit of a gyp.

Perhaps a simple thing to make the ship AIs seem more like newbies is to reduce their rate of fire or to have them fire panic shots when they haven't quite lined up on the target, or both so the panic shots use up a fire cycle.

Along the same lines you could have a ship on the easy levels take a little longer to decide to turn. Once the turn has started it can be as acurate as normal or you can have a small chance of planned over/undershoot followed by another delay before trying again.

Sure malhkan, on the upside, i can describe to you what it can/can't do:

The bot sees the enemy, and transitions into the 'ANGRY' state (it is an enemy, after all). At first, say the bot is barely angry (0) because the enemy isn't a really bad enemy, and hasn't done anything yet. The bot may just stand there and watch, not doing anything (this is defined by the beahavior for a '0' anger level). This can be defined mathematically:

0.5 - 0 == 0.5 1 - 0.5/0.5 == 0

The bot moves at 0% of its average speed, so basically.. it doesn't move.

Then, the enemy makes some rude gesture that the bot sees. This increases the bot's anger level by 0.2 (to.... 0.2). Now say the behavior defines that the bot should approach the enemy at a walking pace at a 0.5 anger level (this 'walking' speed could also be defined on the bot, keeping the behavior object more generic, and enabling it to be a singleton instead of an instance object). Because the bot is less than that (0.2 is less than 0.5), it should approach the enemy at a pace relative to that:

0.5 - 0.2 == 0.3 1 - 0.3/0.5 == 0.4

So, the bot should approach the player at 40% of its average 'approach' speed.

Then, say the enemy pulls out a gun. This increases the bot's anger level by 0.6, making it 0.8:

0.5 - 0.8 == -0.3 1 - -0.3/0.5 == 1.6

So, the bot should approach the player at 160% of its average 'approach' speed.

Then, say the enemy shoots the bot. This increases the bot's anger level by 1, making it.. 1 (maximum value).

0.5 - 1 == -0.5; 1 - -0.5/0.5 == 2

So the bot should approach the player at 200% of its average 'approach' speed.

Anyway.. you get the idea. There are no specific intermediate states within 'angry'. The reaction is based purely on the difference from the average.

And that my friend, is a direct quote from a guru called "Shmooh" on the jME boards. And that is what im going to be aiming at.

Anyway, if you change the "speed" bit to accuracy, you can see that it sorta does exactly what you need it to do.

/** * * Fuzzy State Machine State whereby the state has a value * which detemines how potent this state is * * @author Ahmed * @version: $Id: FuzzySMState.java, Sep 19, 2004 6:13:32 PM */publicclassFuzzySMState {

// the state's nameprivateStringname;

// the current effectivness of the stateprivatefloatfuzzyLogicEffectiveness;

/** * Constructor for a fuzzy state machine state with * a given ID * * @param name, the name of the state */publicFuzzySMState(Stringname) {this.name = name;fuzzyLogicEffectiveness = 0f; }

/** * Sets the name for this state * @param name */publicvoidsetID(Stringname) {this.name = name; }

/** * Obtains the name of this state * @return String */publicStringgetID() {returnname; }

/** * Returns the current effectiveness of this state * * @return float */publicfloatgetEffectiveness() {returnfuzzyLogicEffectiveness; }

/** * Calculates a fuzzy transition. The input is how much * to add to the current effectiveness of this state by. * It returns a distance away from the mean of the state * * @param input * @return float */publicfloatfuzzyTransition(floatinput) {// check to see if the input is more than 1.// if it is, then make the input 1if (input > 1) {input = 1; }

/** * Creates a new instance of a fuzzy state machine * * @param stateID * the initial state at which the machine resides */publicFuzzySM(StringstateID) {states = newHashMap();currentState = stateID; }

/** * returns the current state of the FSM * * @return string which holds the information */publicFuzzySMStategetCurrentState() {return (FuzzySMState)states.get(currentState); }/** * sets the current state * * @param arg_state * the state to set the current state to */publicvoidsetCurrentState(Stringstate) {currentState = state; }

/** * Deletes a state associated with the FuSM Should be used carefully as the * state that is removed could be the current state * * @param stateID */publicvoiddeleteState(StringstateID) {states.remove(stateID); }}

Very neat! Thanks for that. I like the idea, hopefully I'll have time to implement it

In regard to your ship steering mechanism I'd recommend looking into feedback loops. A nice article was put out in Game Developer magazine in the June/July issue; pg. 18. It would be quite easy to vary the loop used (its equation) to create lazy ship navigation that is smooth and simulates a green pilot.

Another may be tuned to be more exact, etc.

One could use this not only for navigation, but say for any turrets on the ship (if any), etc. lots of uses.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org