Battle Engine - Alpha 6 release, downloads in first post

Ideas and games that are not yet publicly in production. This forum also contains the pre-2012 archives of the Works in Progress forum.
Message
Author
Jake
Support Hero
Posts: 3826
Joined: Sat Jun 17, 2006 7:28 pm
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#196 Post by Jake »

usul wrote: Perhaps you already built it in and forgot about it!?!
I definitely already wrote it, I just thought I'd taken it out again! (I can't remember why, though...)

Still, good to hear that you've got it working.
usul wrote:I just realized something about the combat system in the Game Engine, fighters and enemies never miss. Will you be integrating a system where you take into account each character's stats (such as agility, attack, defense) to test whether or not each attack hits or misses?
Probably, at some point, yeah.

This is also something you can do yourself, though - and there's two places you could do it.

If you want it to apply to every attack of any kind - physical, magical, etc - then this kind of thing is the responsibility of the AttackResolver. If you check in engine-schema.rpy, around line 280 the AttackResolver stuff starts. There's a DefaultAttackResolver, which is the very basic one used for most of the demos, and later there's an ElementalAttackResolver, which has the Fire/Water/Earth RPS elements stuff built in. Check on line 155 of grid_demo.rpy to see a demonstration of how to use CustomSchema to get your own custom AttackResolver into the game.

Basically, the ResolveAttack method on the relevant AttackResolver is called whenever one Fighter attacks another - which gets triggered by a call to Battle.Attack, as seen on line 176 of engine-skills.rpy, for example. The parameters are the attacking fighter, the strength of the attack, the list of attributes applied to that attack, the target fighter, and if applicable the range the attack was carried out at. The AttackResolver is expected to perform whatever game-state changes need to be performed for that attack - so call the fighter.Damage method to inflict however much damage is appropriate (the engine will check for Fighter death automatically) and do any other things (maybe an attack with the 'poison' attribute has a chance of adding the 'poison' Effect to the target fighter, for example). If you inflict a damage greater than 0, it's taken off the target fighter's health; if you inflict a damage less than zero, the target fighter is healed up to a maximum of their base health (fighter.BaseStats.Health).

So to write an AttackResolver which works exactly like the ElementalAttackResolver but checks the fighter's 'Skill' stat to see if they hit, you might write something like this:

Code: Select all

    class SkillBasedAttackResolver(ElementalAttackResolver):
        
        def SetUpFighter(self, fighter):
            fighter.RegisterStat('Skill', 75)
            
        def ResolveAttack(self, attacker, attack, attributes, target, range=1, **parameters):
            
            #Check skill - which is a percentage chance of hitting
            if ((renpy.random.random()*100) <= attacker.Stats.Skill):
                # it's a hit, so we perform the attack as normal
                super(SkillBasedAttackResolver, self).ResolveAttack(attacker, attack, attributes, target, range=range, **parameters)
            else:
                # it's a miss, so we announce this to the user
                attacker._battle.Announce(attacker.Name + " missed!")
Of course, if you only want it to apply to physical attacks, then you might put a check that the attributes list contains 'melee' (used by the AttackSkill, but not - say - the magical skills) and only even check for misses under that condition.



The second way of doing it would be to make similar modifications (or create a similar alternative to) the AttackSkill skill which starts on line 158 of engine-skills.rpy. Here you could actually check for a hit before calling the attack resolver, and limit it entirely to attacks made through the attack skill - maybe you have a different way of checking for a hit for melee attacks, ranged attacks and magic attacks.
Server error: user 'Jake' not found

User avatar
jack_norton
Lemma-Class Veteran
Posts: 4085
Joined: Mon Jul 21, 2008 5:41 pm
Completed: Too many! See my homepage
Projects: A lot! See www.winterwolves.com
Tumblr: winterwolvesgames
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#197 Post by jack_norton »

BTW I found a very interesting explanation about hexgrid maps here:
http://www-cs-students.stanford.edu/~am ... g.html#hex
thought maybe could be useful for you when you'll implement it in the engine.
follow me on Image Image Image
computer games

Jake
Support Hero
Posts: 3826
Joined: Sat Jun 17, 2006 7:28 pm
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#198 Post by Jake »

jack_norton wrote:BTW I found a very interesting explanation about hexgrid maps here:
http://www-cs-students.stanford.edu/~am ... g.html#hex
thought maybe could be useful for you when you'll implement it in the engine.
Thanks for the link! I've seen several hex approaches in the past, and I tend to like the treat-it-as-a-square-grid-with-offset-rows approach... I don't have any problems with display (the first piece of software I published was a hex map editor for wargaming!) and I don't have any problems with pathfinding/distance (since those algorithms are agnostic of the structure of the map, they'll have to be once the varying-cost-of-movement stuff goes in) but line-of-sight is an entirely different matter!

(I do wonder how many hex-grid games even need LoS - most of the ones you see are high-level wargames where each hex represents at a minimum hundreds of square metres, sometimes being many kilometres wide... but I don't want to rule anything out, and it's certainly possible.)

Currently I'm thinking of just dividing each hex into four along X and Y axes, to turn an X by Y hexgrid into (what will be treated as) a 2X by 2Y grid of squares, then check LoS through the squares using the same line-drawing approach I do with square grids.
Server error: user 'Jake' not found

User avatar
usul
Veteran
Posts: 415
Joined: Mon Oct 29, 2007 12:35 pm
Projects: Teachings of the Buddha, System-Addict, Generation XxX
Location: Quebec
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#199 Post by usul »

Ok, I've been playing with animations and some things work well, others not so much.

The walking animation using the 'moving' state works like a charm. I've base the movements from the animator's survival guide and despite the fact that I've only drawn four images for the walk, it's looking good albeit a little clunky. No technical problems here.

Now when it comes to the attack, I tried to do a little animation for which I use ATL code when declaring the image in the assets.rpy file. It worked well for the first attack, but on the subsequent attacks only the last image is shown. Am I doing this wrong. Anyway, here's the code I used:

Code: Select all

    image warrior melee:
        'gfx/fighter_melee_anti.png'
        0.5
        'gfx/fighter_melee.png'
Also, how would one go about creating a healing spell. I guess that what I'm really asking here is how to you indicate to the engine that you're looking to select from the friendlies instead of from the baddies!?

Oh and one more thing, keep up the great work!
"The universe is non-simultaneously apprehended"
— Buckminster Fuller

User avatar
usul
Veteran
Posts: 415
Joined: Mon Oct 29, 2007 12:35 pm
Projects: Teachings of the Buddha, System-Addict, Generation XxX
Location: Quebec
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#200 Post by usul »

I tried declaring the image using Animation, but the first frame doesn't show at all, even on the first attack unlike the ATL code which appeared at least that one time. Here's the code:

Code: Select all

image warrior melee = Animation('gfx/fighter_melee_anti.png',1,'gfx/fighter_melee.png')
"The universe is non-simultaneously apprehended"
— Buckminster Fuller

User avatar
jack_norton
Lemma-Class Veteran
Posts: 4085
Joined: Mon Jul 21, 2008 5:41 pm
Completed: Too many! See my homepage
Projects: A lot! See www.winterwolves.com
Tumblr: winterwolvesgames
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#201 Post by jack_norton »

Jake wrote: (I do wonder how many hex-grid games even need LoS - most of the ones you see are high-level wargames where each hex represents at a minimum hundreds of square metres, sometimes being many kilometres wide... but I don't want to rule anything out, and it's certainly possible.)
Well I would use LoS :) is cool when you suddenly find ambushed by other enemy units :twisted:
follow me on Image Image Image
computer games

User avatar
usul
Veteran
Posts: 415
Joined: Mon Oct 29, 2007 12:35 pm
Projects: Teachings of the Buddha, System-Addict, Generation XxX
Location: Quebec
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#202 Post by usul »

Just noticed that the 'damage' state doesn't take into account the character's facing. X_x
"The universe is non-simultaneously apprehended"
— Buckminster Fuller

Jake
Support Hero
Posts: 3826
Joined: Sat Jun 17, 2006 7:28 pm
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#203 Post by Jake »

usul wrote:Just noticed that the 'damage' state doesn't take into account the character's facing. X_x
Did you supply facing parameter/s when you set up the state/transition? The function parameter lists are as follows:

Code: Select all

  def AddStateSprite(self, state, disp, facing=None):
  def AddStateTransition(self, fromState, toState, disp, duration, fromFacing=None, toFacing=None):
For the 'AddStateSprite' method, you need to supply a 'facing' parameter which tells the framework which direction to show that particular sprite for - for the 'AddStateTransition' method, the 'fromFacing' and 'toFacing' are the facings to look for when checking if there's a transition from 'fromState' to 'toState'.

When moving from prevState (facing prevFacing) to newState (facing newFacing) it will check for transitions with the following facings, in this order of preference:
  • (prevState, oldFacing) -> (newState, newFacing)
  • (prevState, 'default') -> (newState, newFacing)
  • (prevState, oldFacing) -> (newState, 'default')
  • (prevState, 'default') -> (newState, 'default')
So you can do stuff like:
  • Define a transition to use when moving, turning from facing South to facing East:

    Code: Select all

    mySprite.AddStateTransition('moving', 'moving', turnSouthToEastAnim, 0.5, fromFacing='S', toFacing='E')
    
  • Define a transition to use when being damaged while facing South, regardless of where you were facing before being damaged:

    Code: Select all

    mySprite.AddStateTransition('default', 'damage', getDamagedSouthAnim, 1, fromFacing='default', toFacing='S')
    
  • Define a transition to use whenever going from standing to moving, regardless of your facing:

    Code: Select all

    mySprite.AddStateTransition('default', 'moving', startMovingAnim, 0.5, fromFacing='default', toFacing='default')
    
Server error: user 'Jake' not found

User avatar
usul
Veteran
Posts: 415
Joined: Mon Oct 29, 2007 12:35 pm
Projects: Teachings of the Buddha, System-Addict, Generation XxX
Location: Quebec
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#204 Post by usul »

Transition problem.

I tried the following and nothing happens. Am I missing something?

Code: Select all

bobSprite.AddStateTransition('default', 'melee', 'warrior_anticipate', 2.5, fromFacing='default', toFacing='default')
"The universe is non-simultaneously apprehended"
— Buckminster Fuller

User avatar
usul
Veteran
Posts: 415
Joined: Mon Oct 29, 2007 12:35 pm
Projects: Teachings of the Buddha, System-Addict, Generation XxX
Location: Quebec
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#205 Post by usul »

update:

The previous code works fine if I replace 'melee' with 'damage' (different state, but sprite transition appears). For some reason the melee transition does not appear.
"The universe is non-simultaneously apprehended"
— Buckminster Fuller

Jake
Support Hero
Posts: 3826
Joined: Sat Jun 17, 2006 7:28 pm
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#206 Post by Jake »

usul wrote: The previous code works fine if I replace 'melee' with 'damage' (different state, but sprite transition appears). For some reason the melee transition does not appear.
It's because the previous state to melee is 'acting'; whenever a fighter starts acting, they move to the 'acting' state, and then any state changes made by the skill itself will go from 'acting' to whatever.

When I did the facing-to-facing search stuff and made it take 'default' as a 'match any facing' facing, I considered that it would make more sense to have a 'default' to 'whatever' state transition occur whatever the previous state was, in the same way as the facing works... but then I was setting the state to 'default' all the time, whenever they're not in a particular state, so it would seem like it would behave wrong and play the transition in some cases it wasn't wanted, too.

I'm considering changing the 'default' in facing-to-facing transition searches to '*' and adding the state-to-state transition searches to use a '*' to mean 'any state' as well.
Server error: user 'Jake' not found

User avatar
DaFool
Lemma-Class Veteran
Posts: 4171
Joined: Tue Aug 01, 2006 12:39 pm
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#207 Post by DaFool »

I just noticed this because my BG artist brought it to my attention... the isometric grid you're using is not exactly on a 30-degree (lines) angle. As a result it's more 'shallow' an angle than the grid my artist came up with. Is there a reason for that and will it affect calculations? I searched online and the gridbox reference is a simple 30 degree system.

Jake
Support Hero
Posts: 3826
Joined: Sat Jun 17, 2006 7:28 pm
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#208 Post by Jake »

DaFool wrote:Is there a reason for that and will it affect calculations?
No, it's just the grid I happened to draw in Photoshop when I was doing the demos; you can fiddle with the parameters when the GridBattlefield is constructed and make it any shape (and thus any angle) you like. There's an explanation of what each of the numbers means in the comments for the iso grid demo. (All 'isometric' really means is 'the same angle each side of the projection' - a vertical line on the screen (projected grid) passes through the centre of a diagonal line of (non-projected) grid spaces. The 30-degree convention is just a convenient angle that's commonly used because it's easy to do in pixel art.
Server error: user 'Jake' not found

User avatar
DaFool
Lemma-Class Veteran
Posts: 4171
Joined: Tue Aug 01, 2006 12:39 pm
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#209 Post by DaFool »

Thanks, I found the adjustment in the 'offset' parameter. I'm only realizing the flexibility of the engine once you try plugging stuff in. Although unlike the background tiles, with character sprites you kinda expect that all of them are rendered in the same perspective since 'Isometric' specifies a specific camera angle, especially in 3D. It'll be chaos if it wasn't.

Any eta on panning?

Jake
Support Hero
Posts: 3826
Joined: Sat Jun 17, 2006 7:28 pm
Contact:

Re: Battle Engine - Alpha 3 release, downloads in first post

#210 Post by Jake »

DaFool wrote: Any eta on panning?
Panning itself I have basically working in 6.11.1; the problem is that at some point between 6.10/alpha 3 and now, something weird has happened to move transitions such that about 50% of the time when a fighter moves from one space to another, it doesn't perform the transition and instead just skips straight to the end. Its exactly the same code that's being run for each space-to-space step, and some of them work and some of them don't so I'm suspicious it's a Ren'Py issue rather than anything in my code (and I've debugged into Ren'Py a bit and found that in the missed steps, the transition isn't even being constructed), but it's also possible that I'm putting the transforms together in the wrong order or something, and I want to get to the bottom of it one way or another before I make the next release.

There's also some cleanup work needed on the panning - right now it skips directly to the new position rather than scrolling smoothly, and I'll need to write some position-interpolation code to get that working correctly, but that's relatively easy so I'm prioritising bug-hunting.
Server error: user 'Jake' not found

Post Reply

Who is online

Users browsing this forum: No registered users