Tweak attributes. Make some tentative decisions on combat.

Upon reflection, I think my attribute notion is too complex. For each attribute, I have the current value, a current maximum, and a possible maximum. And all attributes are on a scale of 0-20. The idea was that a given attribute would max out at some value currently, like 5, and that there would be some greater maximum that you could earn somehow, like 12, all on a scale of 20.

That’s too much. I’m going to assume that everyone’s possible max is 20, so we only need to display one’s current value and current max. That will simplify the bar. It should also allow me to use yellow and red for the two colors.

After we do that, time permitting, I want to explore ideas about combat, both as regards attributes, and in general.

Here’s the current bar display:

function MonsterSheet:drawBarFraction(current, currentMax, possibleMax, icon)
    pushStyle()
    tint(255)
    spriteMode(CENTER)
    rectMode(CORNER)
    sprite(icon, 80, 10)
    stroke(255)
    fill(0)
    rect(100,0,120,20)
    fill(150,150,150)
    rect(100,0,120*possibleMax/20,20)
    fill(255,255,0)
    rect(100,0,120*currentMax/20,20)
    fill(0,255,0)
    rect(100,0,120*current/20,20)
    popStyle()
end

We’ll go to two parms and icon:

function MonsterSheet:drawBarFraction(current, currentMax, icon)

(I knew I should have moved the icon to the front. I didn’t, because I decided that the calling sequence wouldn’t change. So it changed. Shall we move icon to the front now? Yes, let’s.)

function MonsterSheet:drawBarFraction(icon, current, currentMax)

Change the callers before I forget:

    self:drawText("Strength")
    self:drawBarFraction(asset.builtin.Small_World.Sword, m:strength(), m:strengthMax())
    self:newLine()
    self:drawText("Health")
    self:drawBarFraction(asset.builtin.Small_World.Heart, m:health(), m:healthMax())
    self:newLine()
    self:drawText("Courage")
    self:drawBarFraction(asset.builtin.Small_World.Heart_Glow, 3,10)

I could imagine rolling the text name in there somehow, but this isn’t the moment for that, we have enough balls in the air already,

Now the display:

function MonsterSheet:drawBarFraction(icon, current, currentMax)
    pushStyle()
    tint(255)
    spriteMode(CENTER)
    rectMode(CORNER)
    sprite(icon, 80, 10)
    stroke(255)
    fill(150,150,150)
    rect(100,0,120,20)
    fill(255,0,0)
    rect(100,0,120*currentMax/20,20)
    fill(255,255,0)
    rect(100,0,120*current/20,20)
    popStyle()
end

Here’s the princess in good health:

good

And in danger:

bad

I’m not sure I love that display. It would be better, I think if we just saw the health value counting down, and no other color. Let’s try making the current max rectangle grey, like the full-sized one. Then we should just get a line and nothing else for it.

Should we do something fancy, flashing the bar or turning it a different color as well? Not yet. One more tweak and then I’ll decide.

Here’s the princess before a battle with a vampire bat:

bat1

And after vanquishing it. She has lost some Health:

bat2

I think I’ll go with that bar graph for now. It’s a fair mix of simple and informative.

Commit: simpler attribute bar graph.

Now let’s think about combat and attributes.

Combat

Right now, combat amounts to a monster or player trying to enter the tile of the combatant. Whoever moves to the other’s tile first gets to strike, and it looks like this:

function Player:startActionWithMonster(aMonster)
    aMonster:damageFrom(self.tile,math.random(0,self:strength()))
end

function Monster:startActionWithPlayer(aPlayer)
    aPlayer:damageFrom(self.tile,math.random(0,self:strength()))
end

Basically you randomly roll damage up to the limit of your strength and apply it to the enemy combatant’s health points. If health drops below zero, the combatant dies.

Strength never varies during the game. We could imagine reducing it along with health, according to some formula. Or we could add a random roll of some kind.

I just made up the “Courage” attribute to test the bar graph, but that, or other attributes, could come into play in combat.

Bruce Onder made two suggestions for combat. If I recall correctly, one was that when struck, a combatant should fall back, driven off their current tile. I imagine that might give a bit more reality to the battle. Maybe you could even be driven off diagonally, or more than one tile. Then you’d have to dart around to get back in position to strike.

Bruce also suggested going to a turn-based approach. As I envision that, general game motion would stop and the turn-based logic would come into play. (It might be that the whole game could be turn-based: one might never notice it.)

During combat, some kind of HUD might appear, offering current combat options. Maybe the player could strike with their current weapon, equip a different weapon, move, cast a spell, throw a grenade, … the options are limitless.

All this would be somehow conditioned by and affect the player’s statistics. Dungeons and Dragons has six basic statistics, Strength, Dexterity, Constitution, Intelligence, Wisdom, and Charisma. Most of those probably don’t apply here, because we’re probably not going to look at game play options like charming a snake or picking a lock. But some of them might.

Our Health attribute is closest to D&D Constitution, in that when it goes to zero you are other than alive. And our Strength seems pretty close to D&D Strength. We might consider adding a Dexterity or Speed attribute, which might allow more than one strike per round, or a better chance of defending against an attack. (At present, there is no defense, but it would be easy enough to change the damageFrom method to roll a defense value that could stop an attack or reduce its effect.)

Today, the only clues one gets about the progress of a battle are changes in the attribute bars, and some hints from the sounds. Those sounds could be more varied, giving more information.

The Simple Dungeon demo has the ability to float messages up from the player or monster, and we could borrow that idea and show icons or values floating up. Even words like “Missed!” could be used.

Of course, with a turn-based approach, we could have a whole panel of information scrolling by. (That would be a pain to implement in Codea, by the way.) I’ll be thinking about turn-based “off line”, but for now, I think we’ll focus on the basic notion of an attack by trying to move into the other combatant’s square.

For now, the display is simplified and combat is simple as well. We’ll see what’s next.


D2.zip