Java-Gaming.org    
Featured games (78)
games approved by the League of Dukes
Games in Showcase (427)
Games in Android Showcase (89)
games submitted by our members
Games in WIP (466)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Trying to get rid of a few if-else statements if possible.  (Read 1519 times)
0 Members and 1 Guest are viewing this topic.
Offline tyeeeee1
« Posted 2013-08-17 02:01:03 »

Hey,

I've made a lot of progress on my little 'battle-simulation' program and I've gotten to a point where the class that controls the battle is getting a bit long. I'm pretty sure that, as I continue to add things to the simulation, the battle class will become even longer and tougher to figure out.

I'm already starting to go over all the code and comment it but I'm not sure if I can cut out a few if or else statements to make the code a bit shorter and still run the same.

If anyone sees anywhere that I can get rid of or change a few statements then thanks!

https://github.com/Valkryst/Project_02/blob/master/src/main/java/valkryst/systems/Battle.java
(I'm working on the class, mainly adding comments, as of posting this so you might notice a few comments pop up or a few statements disappear or change as I find things to comment on/change.)
Offline BurntPizza
« Reply #1 - Posted 2013-08-17 02:10:17 »

First you could "lift" code that is in both branches of an if/else, such as here:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
//Player wins:
if (Math.max(cHealth, pHealth) == pHealth) {
    finished = true;
    p.setHealth(0.0);
    p.setIsAlive(false);
    c.setHealth(0.0);
    c.setIsAlive(false);
    p.setExperience(p.getExperience() + (c.getLevel() * 6));
    p.statistics.levelUp();
    System.out.println("You are both dead.");
    System.out.println(p.getName() + " wins.");
    break;
} //Creature wins:
else {
    finished = true;
    p.setHealth(0.0);
    p.setIsAlive(false);
    c.setHealth(0.0);
    c.setIsAlive(false);
    System.out.println("You are both dead.");
    System.out.println(c.getName() + " wins.");
}


Could be reduced to:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
finished = true;
p.setHealth(0.0);
p.setIsAlive(false);
c.setHealth(0.0);
c.setIsAlive(false);
System.out.println("You are both dead.");

//Player wins:
if (Math.max(cHealth, pHealth) == pHealth) {
    p.setExperience(p.getExperience() + (c.getLevel() * 6));
    p.statistics.levelUp();
    System.out.println(p.getName() + " wins.");
    break;
} //Creature wins:
else {
    System.out.println(c.getName() + " wins.");
}


That's the first tip I can give from reading that, will help a bit with length and readability, I think.
Offline opiop65

JGO Kernel


Medals: 128
Projects: 7
Exp: 3 years


Team Alluminum


« Reply #2 - Posted 2013-08-17 02:23:33 »

No, that wouldn't help at all. If you look at the code you'll see that the function calls were specific to the if statements, and cannot be moved into a more global state. Sorry, but it seems as if you didn't even look at his code...

As for the question, there really isn't much you can do, it actually is quite simple. If you start to use a bunch of if statements inside of each other, then you know you're most likely doing it wrong. As of right now, I don't have anything that would make either statement smaller.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline tyeeeee1
« Reply #3 - Posted 2013-08-17 02:29:34 »

Thanks for the replies.

Yep, opiop65 is right, that would break the program. Those statements are unique for each type of scenario so they can't be taken out of their respective if/else statements without breaking that scenario as far as I can see.
Offline Troncoso

JGO Coder


Medals: 20



« Reply #4 - Posted 2013-08-17 02:36:43 »

1  
if (cHealth <= 0.0 || pHealth <= 0.0) {

1  
if(pIsFirst) {

1  
if(!pIsFirst) {


These are your 3 main conditions. I think the code within each of these should be separate methods. It's not necessarily less code. But, it's definitely easier to read, and easier to find specific code.
Offline BurntPizza
« Reply #5 - Posted 2013-08-17 02:37:08 »

All of that particular code was in a higher-up if-block so it would not affect program flow.

Those statements are unique for each type of scenario so they can't be taken out of their respective if/else statements

I "lifted" only statements that were in fact in both scenarios, ones that would of been executed either way. So long as the exact order of execution does not matter (as in my example) or is not affected, the program logic is unchanged.

Compile and see!

EDIT:
Note that if the else block is actually another if, like this:

1  
2  
3  
4  
5  
6  
if {
    <snip>
}
else if {
    <snip>
}


Then the lift operation may not be correct, as it is possible that no block would be executed! Only ever lift code if it is common to all blocks, including an ending else block.
Offline opiop65

JGO Kernel


Medals: 128
Projects: 7
Exp: 3 years


Team Alluminum


« Reply #6 - Posted 2013-08-17 02:42:17 »

All of that particular code was in a higher-up if-block so it would not affect program flow.

Those statements are unique for each type of scenario so they can't be taken out of their respective if/else statements

I "lifted" only statements that were in fact in both scenarios, ones that would of been executed either way. So long as the exact order of execution does not matter (as in my example) or is not affected, the program logic is unchanged.

Compile and see!
No offense, but that's a horrible coding practice. Just because it doesn't affect other code now doesn't mean it won't later on. Just keep the code in the correct if statements and you'll never have a problem.

Offline Troncoso

JGO Coder


Medals: 20



« Reply #7 - Posted 2013-08-17 02:47:53 »

To be technical, he's not wrong. Both conditions have some identical code. That can be moved outside the conditions with no bad effect. It's not even really bad coding practice. Code duplication is bad coding practice.

1  
finished = true;


This (for example), which is in each of the conditions within the first main condition (if (cHealth <= 0.0 || pHealth <= 0.0) {)
Can be moved outside all 4 of them, and just have a single statement at the top. Nothing about that will break the code.
Offline Several Kilo-Bytes

Senior Member


Medals: 11



« Reply #8 - Posted 2013-08-17 02:56:42 »

Use boolean variables.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
final boolean playerLeads = pHealth > cHealth;
final boolean playerDead = pHealth < 0;
final boolean creatureDead = cHealth < 0;
final boolean playerWins = playerLeads && creatureDead;

if(playerDead)
{
  p.setHealth(0);
  p.isAlive(false);
}

if(creatureDead)
{
  c.setHealth(0);
  c.isAlive(false);
}

if(playerWins)
{
  et.cetera();
}


I'm guessing this is a problem (line 37):
1  
2  
cHealth = Math.abs(cHealth);
pHealth = Math.abs(cHealth);


Right now it is difficult to follow the code, so I may be missing something. Why have a setIsAlive(boolean)? Couldn't you achieve the same thing be making setHealth automatically make the character dead and make sure the health is at least zero? Maybe you could have have a kill() and revive(health) method, too.
Offline opiop65

JGO Kernel


Medals: 128
Projects: 7
Exp: 3 years


Team Alluminum


« Reply #9 - Posted 2013-08-17 03:00:31 »

To be technical, he's not wrong. Both conditions have some identical code. That can be moved outside the conditions with no bad effect. It's not even really bad coding practice. Code duplication is bad coding practice.

1  
finished = true;


This (for example), which is in each of the conditions within the first main condition (if (cHealth <= 0.0 || pHealth <= 0.0) {)
Can be moved outside all 4 of them, and just have a single statement at the top. Nothing about that will break the code.
Ok, i just noticed that, sorry! This is very true, you can always set these variables at the bottom under the if and else statements.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline tyeeeee1
« Reply #10 - Posted 2013-08-17 03:01:22 »

O.o I have no idea how I missed that this entire time, guess I was partially wrong. =P

I've moved the statement 'finished = true;' as high as it can go within the if-else blocks and it looks like it should work after I went through and carefully checked out which code is part of which if-else block. I can't test it at the moment because I'm working on another area of the program but it should work.

I'll take a look, after typing this, for a few more things to move around.

@Several Kilo-Bytes
You posted while I was typing this up so I'll take a better look at your comment in a minute but to answer your question the setIsAlive() method sets the isAlive() boolean in the Physiological class. I use this to figure out whether the battle is over or not and, down the road, I'll be using it to decide a few other things as well.

Edit:
I've committed the changed code to github, still looking for more things to alter.
Offline tyeeeee1
« Reply #11 - Posted 2013-08-17 03:11:54 »

Use boolean variables.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
final boolean playerLeads = pHealth > cHealth;
final boolean playerDead = pHealth < 0;
final boolean creatureDead = cHealth < 0;
final boolean playerWins = playerLeads && creatureDead;

if(playerDead)
{
  p.setHealth(0);
  p.isAlive(false);
}

if(creatureDead)
{
  c.setHealth(0);
  c.isAlive(false);
}

if(playerWins)
{
  et.cetera();
}


I'm guessing this is a problem (line 37):
1  
2  
cHealth = Math.abs(cHealth);
pHealth = Math.abs(cHealth);


Right now it is difficult to follow the code, so I may be missing something. Why have a setIsAlive(boolean)? Couldn't you achieve the same thing be making setHealth automatically make the character dead and make sure the health is at least zero? Maybe you could have have a kill() and revive(health) method, too.

Sorry for the double post, I'm not even sure if there is a rule about that on this forum. Anyway...

Setting the booleans that way works, when the battle starts, but does it keep updating itself as the code runs without me having to write statements to set the boolean? I'm having a blond moment here about that for some reason.
Offline opiop65

JGO Kernel


Medals: 128
Projects: 7
Exp: 3 years


Team Alluminum


« Reply #12 - Posted 2013-08-17 03:30:44 »

*blonde xD

And no, as the modifier is final, it will compile the variables once and they will never change.

Offline Several Kilo-Bytes

Senior Member


Medals: 11



« Reply #13 - Posted 2013-08-17 03:31:03 »

It is a final variable so it is only assigned once inside the variable's scope. If it is at the beginning of the method, it gets set once per method. If it is at the top of a loop, it gets set once per loop iteration.

Concerning setIsAlive(boolean): You would keep isAlive(), but setIsAlive(boolean) is redundant. Unless there exists an exception to the rule, it is implied that a character with 0 HP is not alive, so isAlive() could either return hp > 0; or setHealth could set a private variable isAlive to false automatically.
Offline opiop65

JGO Kernel


Medals: 128
Projects: 7
Exp: 3 years


Team Alluminum


« Reply #14 - Posted 2013-08-17 03:39:41 »

But since its outside the scope of any loops or if statements won't it never be reset to something else?

Offline Several Kilo-Bytes

Senior Member


Medals: 11



« Reply #15 - Posted 2013-08-17 03:59:31 »

It would go inside a loop.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
while(true)
{
  final boolean playerLeads = pHealth > cHealth;
  final boolean playerDead = pHealth < 0;
  final boolean creatureDead = cHealth < 0;
  final boolean playerWins = playerLeads && creatureDead;

// .........

  if(playerWins)
  {
// .........
   break;
  }
  if(playerDead) // playerLoses
 {
// .........
   break;
  }
// No one has won
// ...
}


You could make it non-final and move it out of the loop if you don't want to use break.
Offline opiop65

JGO Kernel


Medals: 128
Projects: 7
Exp: 3 years


Team Alluminum


« Reply #16 - Posted 2013-08-17 04:02:25 »

Ah this is true. I never knew you could change the value of a variable with the final modifier after it had been compiled at runtime. Well, I learn more everyday!

Offline BurntPizza
« Reply #17 - Posted 2013-08-17 04:37:08 »

Ah this is true. I never knew you could change the value of a variable with the final modifier after it had been compiled at runtime.

You can't really, each time the loop is executed, playerLeads, etc are actually considered brand new variables, and can thus be declared final, as to the code, it is their "first" declaration.
Offline tyeeeee1
« Reply #18 - Posted 2013-08-17 04:41:18 »

Ah, that makes a lot more sense now and it saves a few calculations. ^.^

I've modified and uploaded the new Battle class and now it's back to looking for more, would optimizations be the word? Thanks!
Offline ReBirth
« Reply #19 - Posted 2013-08-17 05:07:46 »

Usually I love to get rid if-else tree but I'm busy right now so I can't take a look.

But here some advice. For advance problem, for example when you work as developer and have to continue previous work that consists 7000 lines of if-else, search for Karnaugh Map for boolean logical optimization.

Offline BurntPizza
« Reply #20 - Posted 2013-08-17 05:49:43 »

Another thing, this time more for readability than reducing logic:
Any time you have a bunch of statements that are used identically in many places, you can "un-inline" them, by putting them in a private method (with a good, descriptive name!), and replace all usages of those statement bundles with that method. Example, these two statements are used together a lot:

1  
2  
System.out.println(c.getName() + " is dead.");
System.out.println(p.getName() + " wins.");

Could be put into, say
printStatus();
or something.

Another thing to do, in this code here:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
//Player wins:
if (playerWins) {
    p.setExperience(p.getExperience() + (c.getLevel() * 6));
    p.statistics.levelUp();
    System.out.println(p.getName() + " wins.");
}
//Creature wins:
else {
    System.out.println(c.getName() + " wins.");
}


You could get rid of the serveral
playerWins
if/else blocks entirely by simply:
1  
System.out.println((playerWins ? p : c).getName() + " wins.");


Of course, this only would replace the System.out calls in the blocks, although in this specific case it eliminates the if/else entirely.

Again, not actually reducing logic really, but much more concise and readable, in my opinion.
Do elsewhere accordingly as you see fit.
Offline Several Kilo-Bytes

Senior Member


Medals: 11



« Reply #21 - Posted 2013-08-17 06:26:47 »

Ah this is true. I never knew you could change the value of a variable with the final modifier after it had been compiled at runtime.

You can't really, each time the loop is executed, playerLeads, etc are actually considered brand new variables, and can thus be declared final, as to the code, it is their "first" declaration.

Oh, final variables are very cool. If you are programming in Java it is very helpful to understand how variable assignment works. Final variables can be static, local, or field variables. They can only be assigned to once and must be assigned to before they are read, but only need an assignment if they can be read.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
public class Point
{
/**
 * The sum of any two numbers multiplied by amazing_constant is the average of those two numbers.
 */

  public final static int amazing_constant;

  public final double x, double y; // Must be assigned in constructor

  public Point(double a, double b)
  {
     // x and y do not need to be set yet because they aren't used here
    System.out.println("The average of a and b is " + (a + b) * amazing_constant);
     // but must be assigned somewhere
    x = a;
     y = b;
  }

  public double distanceTo(Point p)
  {
    final double dx, dy; // Local variables can be final
   final double r; // If a local variable is never used, it will still compile
   dx = p.x -x;
    dy = p.y - y;
    return Math.sqrt(dx * dx + dy * dy);
  }

  public static Point getCentroid(List<Point> points)
  {
     // A final variable can get more than one value, but every execution path must write to it exactly once before it is used
   final double multiplier;
     // Local variables, like all final variables must be assigned a value before they are used.
   double sumX = 0, sumY = 0;
    for(Point p : points)
    {
       sumX += p.x;
    }
    if(points.size() * 3 - 1 == 5)
    {
      multiplier = amazing_constant;
    }
    else
    {
      multiplier = 1.0 / points.size();
    }
    return new Point(sumX * multiplier, sumY * multiplier);
  }

  static
  {
    int z = 0;
    for(int i = 1; i <= 256; i *= 2) z ++;
    amazing_constant = z / 4.0; // Yes a final variable can be assigned this way.
 }
}


Parameters can also be final, but it's not that useful to do so because there is no way to make values referred to read-only and all user defined types are Objects. Sad But an object with only final public variables is useful since you know those values will never change even if you share it with another section of code. Look at the length variable of the String class. It is a final public int and its value depends on what gets passed to String's constructor.

It's important to know final variables are not C style defines. They are much more elegant and can help avoid bugs rather than cause them.
Offline tyeeeee1
« Reply #22 - Posted 2013-08-17 07:18:00 »

Another thing, this time more for readability than reducing logic:
Any time you have a bunch of statements that are used identically in many places, you can "un-inline" them, by putting them in a private method (with a good, descriptive name!), and replace all usages of those statement bundles with that method. Example, these two statements are used together a lot:

1  
2  
System.out.println(c.getName() + " is dead.");
System.out.println(p.getName() + " wins.");

Could be put into, say
printStatus();
or something.

Another thing to do, in this code here:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
//Player wins:
if (playerWins) {
    p.setExperience(p.getExperience() + (c.getLevel() * 6));
    p.statistics.levelUp();
    System.out.println(p.getName() + " wins.");
}
//Creature wins:
else {
    System.out.println(c.getName() + " wins.");
}


You could get rid of the serveral
playerWins
if/else blocks entirely by simply:
1  
System.out.println((playerWins ? p : c).getName() + " wins.");


Of course, this only would replace the System.out calls in the blocks, although in this specific case it eliminates the if/else entirely.

Again, not actually reducing logic really, but much more concise and readable, in my opinion.
Do elsewhere accordingly as you see fit.

Thanks.

Putting those print messages into their own method is a good idea but it wouldn't be worth doing at the moment since they're only there for testing purposes at the moment. Instead of working on a GUI and all that fancy graphic-related stuff I'm just creating the basics of the game and testing everything with print statements. Thanks though. ^.^

The ternary (is that the correct word for it?) operator seems like it would be pretty useful in this case. I barely know how to use it but I'll take a look tomorrow afternoon and see if I can figure it out well enough so that I can start using it in the program.
Offline BurntPizza
« Reply #23 - Posted 2013-08-17 07:33:35 »

The engine is usually more important than the paint!   Wink

I like to think of the ternary operator like this: The expression
(condition ? object_or_value1 : object_or_value2)
is equivalent to calling this method:

1  
2  
3  
4  
5  
Object ternary(boolean condition, Object object1, Object object2) {
    if(condition) {
        return object1;
    } else return object2;
}


Of course, it returns a primitive value if passed that, but can also return object references, as in my example, so pretend that the method is overloaded for all primitive types as well.

Anybody feel free to correct my thinking if it is wrong/misleading, or if there are other subtleties to point out.
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #24 - Posted 2013-08-17 09:02:58 »

While its not neccesarily saving 'lines'  it does make some things modular
e.g.
you have these 2 lines in at least 4 cases

1  
2  
3  
4  
p.setHealth(0.0);
p.setIsAlive(false);
c.setHealth(0.0);
c.setIsAlive(false);


The only difference is p and c.  You can stick it in a method and call either or

1  
2  
3  
4  
5  
6  
resetEntity(p); // or alternative resetEntity(c);
...
void resetEntity(Entity e){
    e.setIsAlive(false);
    e.setHealth(0,0);
}


Its trivial change, but makes the 'main meaty' chunk have 4 less lines'  though it does't reduce total file line count at all.


The same goes for lines 94-112 and 128-146(maybe 146?)
1  
2  
3  
4  
5  
6  
7  
if(pIsFirst){
    SomeMethod();
}
...
if(!pIsFirst){
    SomeMethod();
}

 would reduce about 15 LoC  and reduce some of the 'clutter' in the meaty part of the code

Another thing, is in your if(playerDead || creatureDead)
you call finished = true;
However, in all conditions you use "break"  thus  negating the effect of finished = true.  If you are using break,  then why not just use while(true) ?
Thus eliminating 'finished' boolean completely?


 Huh Huh Pointing persecutioncomplex Roll Eyes Tongue

Again, some of these are just coding style more than anything?




Edit:

Just saw a major code/logic reducer, improvement from
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
if (c.getUsesArmor()) {
    if (!pIsDefending)
        cHealth -= p.getBaseDamage() + p.weapon.getWeaponDamage(p.getMyWeapon()) - c.getArmorPoints();
    else
        cHealth -= (p.getBaseDamage() + p.weapon.getWeaponDamage(p.getMyWeapon()) - c.getArmorPoints()) / 2;
} else {
    if (!pIsDefending)
        cHealth -= p.getBaseDamage() + p.weapon.getWeaponDamage(p.getMyWeapon());
    else
        cHealth -= (p.getBaseDamage() + p.weapon.getWeaponDamage(p.getMyWeapon())) / 2;
}

to become something like
1  
2  
3  
int defending = (pIsDefending ? 2: 1);  //  defending = 2 half damage, !defending = 1 full damage
int armor = (c.getUsesArmor() ? c.getArmorPoints() : 0);
cHealth -= (p.getBaseDamage() + p.weapon.getWeaponDamage(p.getMyWeapon()) - armor) / defending;


thats 11 lines to 3 lines. and this happens in at least 2 places

"Experience is what you get when you did not get what you wanted"
Offline 65K
« Reply #25 - Posted 2013-08-17 10:03:02 »

Before starting to just shuffle a few statements, you could fix the basic design problem:
Battle does too many things.
1. It watches the game state and looks out for the winner.
2. It implements the game AI.

Two different unrelated tasks should be split up in dedicated classes.
Then it is rather uncommon to run a main loop inside the constructor.

Battle
 |
  -- Jury
  -- AI

Offline tyeeeee1
« Reply #26 - Posted 2013-08-17 19:19:03 »

Before starting to just shuffle a few statements, you could fix the basic design problem:
Battle does too many things.
1. It watches the game state and looks out for the winner.
2. It implements the game AI.

Two different unrelated tasks should be split up in dedicated classes.
Then it is rather uncommon to run a main loop inside the constructor.

Battle
 |
  -- Jury
  -- AI

I've just started moving a few things around and this seems like a pretty good idea. I've moved out all of the code that decides if anyone has won or lost the battle to the new Jury class.
After that I started to use the ternary operator to get rid of a few print statements and then I got rid of the whole 'finished' boolean variable and started just using 'break;' instead to exit the loop.

Jury class: https://github.com/Valkryst/Project_02/blob/master/src/main/java/valkryst/systems/battle/Jury.java

Most of the tactic related code is within the Tactics class but I'm not sure if I want to move the rest of the tactic related code from the Battle class.

Thanks!
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (76 views)
2014-04-15 18:08:23

BurntPizza (69 views)
2014-04-15 03:46:01

UprightPath (81 views)
2014-04-14 17:39:50

UprightPath (66 views)
2014-04-14 17:35:47

Porlus (81 views)
2014-04-14 15:48:38

tom_mai78101 (105 views)
2014-04-10 04:04:31

BurntPizza (165 views)
2014-04-08 23:06:04

tom_mai78101 (261 views)
2014-04-05 13:34:39

trollwarrior1 (211 views)
2014-04-04 12:06:45

CJLetsGame (220 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!