OK, so backing WAY up, you already noted that just doing a simple iterative program was slow/inefficient to develop**
Instead of looking at the program as, "I need to do this, then do this, then do this," think, "I need to break this big problem down into smaller problems, and make it by building it by solving the small problems first**"
Java and PHP support objects (Java requiring them, PHP having added OOP), so you'd tend to use objects** But you can use an array just as well as an object** That's an implementation detail**
The thing to do is look at all the global variables you're probably using now, and things you couldn't add, and try to encapsulate them as their own whole entities** For instance, you might have a level as a data structure** It would then have references to things contained in the level (a player, a monsters list, an item list, etc**)** If it were set up with a simple grid, you might have that grid and what's on it in that data structure (so you'd then need to define the grid's tiles, too)**
So, then, you can have say, a monster** It needs a position in the level, possible moves per time/turn, possible actions when the player gets near, some way to track health status, etc**** You could then look at that, and realize that any 'actor' on a level needs those same things, so add a hostility flag to make it a monster, or even go further and add a faction tag**
Now, defining what those entities can do would make up functions for them (or methods in their objects, with OOP--same thing, different organization)** The data structure itself for each thing represents its state** The functions change that state**
So, then, after following that out further, the main engine of the game will call those functions to change those states, rather than directly manipulating the state data** There are many benefits, but the biggest benefits to a small one-man project will be that of simpler, easier-to-follow code, and the ability to move code around to where it needs to be called, which may very well change as features get added or removed.
Code:
actor_attack($monster["imp21"], $player)
Instead of:
Code:
$attack = $imp21_attack * rand(0, 100);
if ($attack > $player_dodge) {
$damage = rand($imp21_damage_min, $imp21_damage_max)
* (1.0-$player_armor);
if ($player_health > $damage) {
$player_health -= $damage;
// other related code
} else {
// game over code
}
} else {
// miss code
}
So, let's say every critter, and the player, is a simple old table (PHP array), like so:
Code:
actor = {
"health" => num > 0 iff not dead,
"attack" => num > 0,
"dodge" => num > 0 <= 100,
"defense" => num > 0 <= 1 (1 == immortal?),
"dmg_min" => num >= 0,
"dmg_max" => num >= dmg_min,
"x" => valid grid column,
"y" => valid grid row
}
The attack function might look like (note: I'm rusty on PHP, so this may be syntactically incorrect):
Code:
function actor_attack($attacker, $defender) {
if ($attacker["attack"] * rand(0, 100) > $defender["dodge"]) {
$dmg_dealt = rand($attacker["dmg_min"], $attacker["dmg_max"])
* (1.0 - $defender["defense"]);
if ($defender["health"] > $dmg_dealt) {
$defender["health"] -= $dmg_health;
event["was_hit"]($attacker, $defender, $dmg_dealt);
} else {
event["was_killed"]($attacker, $defender, $dmg_dealt);
}
} else {
// miss code, if any
event["was_not_hit"]($attacker, $defender);
}
}
I can assume that the functions in the event array will handle the special work not in this function, and pass it off to them, giving them just enough local info to get by with. They can then be made into simple dummy functions until fleshed out. The attack/defend code also doesn't have to have any overlap with movement, reach, turns, or anything else, either--it can be called wherever it is needed, which could very well change over time. So, much of the program can be changed without affecting it. It's a nice little modular chunk of the much bigger system. So now, there's an attack+hit/miss function that will work with an arbitrary number of game entities, using event-driven coroutine equivalents (event["name"](args) can call further events, until the turn is over, FI), and no fancy uber-abstract OOP for miles.
The thing is, building up like that,
the rest of it can wait, and doesn't yet matter. Design, build, and test the small parts first, on their own, then make the larger parts with them.