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 4 release, downloads in first post

#256 Post by Jake »

DaFool wrote:First presentable dummy 'battle' (just dummy enemies). Animation is very jerky and I could use the 2X faster Ren'Py right now. Then again there were just too few frames in the prerenders to begin with. I think it would also make sense to bind the panning controls to the arrow keys so won't accidentally select a unit while panning.
It's looking pretty cool - and I must say, I never expected the engine to be used for gaily-skipping loligoths, let alone as the first thing I see from someone else! ;-)

I guess it could just be 'cause it was captured at a low frame rate, but the animations looked like they were playing fine to me - the big obvious problem is the move/z-order thing that PyTom's fixed now, so hopefully it'll be a lot cleaner once that's released.

(As it goes - it looks like you've exhibited the skip-on-pan bug that makes a fighter who's in the middle of moving position inaccurately for a few frames if you pan the viewport at the same time. This is caused by me not having found a way to force all Displayables to re-paint all at once, meaning that the panning transform is actually just set to check it doesn't need to re-position the sprite every tenth of a second. When you pan, some things don't catch up with the new position fast enough, resulting in that display bug. I've been meaning to look into ways to force Ren'Py to re-display everything, but having not had a quick win, it's on the back-burner.)
Server error: user 'Jake' not found

blakjak
Veteran
Posts: 224
Joined: Fri Dec 21, 2007 2:36 pm
Location: France
Contact:

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

#257 Post by blakjak »

DaFool wrote:First presentable dummy 'battle' (just dummy enemies). Animation is very jerky and I could use the 2X faster Ren'Py right now. Then again there were just too few frames in the prerenders to begin with. I think it would also make sense to bind the panning controls to the arrow keys so won't accidentally select a unit while panning.

http://www.youtube.com/watch?v=_-0hnlXrKyg
Wasn't expecting something so cute when you mentioned a mecha themed game, but I must say a Prohibition era SRPG with goth lolis is just grand =)

I love the battlefield, with all the bridges, the dummy cars also.

It's really inspiring.

User avatar
jack_norton
Lemma-Class Veteran
Posts: 4084
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 4 release, downloads in first post

#258 Post by jack_norton »

Nice video. I like the background in particular, even if before I saw the enemies I expected something fantasy :D and as Jake said during panning there's annoying displayable bug (is quite noticeable). But for a WIP, is very well done.
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 4 release, downloads in first post

#259 Post by Jake »

jack_norton wrote:there's annoying displayable bug (is quite noticeable)
To be fair to DaFool, it's totally not his fault as well. ;-)
Server error: user 'Jake' not found

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

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

#260 Post by Jake »

Alpha 5 released!

Image

I'm demonstrating the new card-counter-style WargameSchema and the hex grids at the same time, but rest assured - like everything else, you can mix and match as you prefer, there's nothing stopping you using a hex grid for a regular battle or wargame counters on the path battlefield or whatever. ;-)


New things:
  • Hex Grids
  • WargameSchema for simple card-counter-style wargames
  • GetPositionsInRadius, GetPositionsInLine, GetPositionsInRect methods on Battlefield - you can use these to pick target positions for your spells, perhaps find all the squares within a set radius of the target spot for grenades, etc.
  • 'Invulnerable' property for Fighter (R/W)
  • 'PlayerControlled' property for Fighter (R)
  • Added code to TurnBattleMechanic to automatically perform moves by non-player-controlled fighters first. (c.f. Custom Skills demo -> Charm; this uses the above PlayerControlled property.)
  • Added a Pause method to Battle which plays nicely with RequestPause to try and avoid unnecessary asynch pausing if the requested pause time has already been eaten up (e.g. in panning waits) before the battle gets around to redrawing - really you should try and use _battle.Pause() instead of renpy.pause() for any battle-related pausing to try and avoid unnecessary waiting.
  • Added 'damager' parameter to BattleAware.FighterDamage and a 'FighterKilled' event method to BattleAware - to provide a base for XP/levelling
  • Added a 'range' option to AttackSkill
  • Added an 'includeCancel' option to PickSkill
  • Added an 'End Turn' option to PickFighter
  • Added SetUpFighter method to BattleMechanic
Caveats
If you're moving code from Alpha 4 to Alpha 5, I made a small breaking change - and there's a couple of other things to consider:
  • If you make any calls to Fighter.Damage, a new parameter is required - this should be a Fighter instance to show who or what damaged this target. Pass None if not applicable.
  • UIProvider.PickFighter may now return None if 'End Turn' desired.
  • WargameSkill - enforced by the WargameSchema - doesn't really work for AI fighters, so that schema is only good for hotseat play right now. It probably really needs its own AI since the considerations are different.
Alpha 5 - All[25MB]
Server error: user 'Jake' not found

User avatar
jack_norton
Lemma-Class Veteran
Posts: 4084
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 5 release, downloads in first post

#261 Post by jack_norton »

Looks very good for an alpha :) Keep up the good work.
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 5 release, downloads in first post

#262 Post by Jake »

jack_norton wrote:Looks very good for an alpha :) Keep up the good work.
Thanks (and all 'alpha' means is 'not feature complete yet', I'm definitely not trying to use it as an excuse for shoddy coding or anything)! ;-)


As it goes, I forgot to mention before - I took a bit of a different approach to hex-grid LoS to that described on most sites I read on the matter[*], so if anyone does play around with the hex maps, I'm particularly interested in hearing about it if there's any places where you think a unit should be able to draw LoS but the engine says they can't - I'd need to know the positions of the source and target and also anything else nearby that might block LoS, obviously.


[*] Basically, I first treat the hex grid as if it were a grid of rectangles in which every other column is offset by half a rect. Then when calculating LoS, I re-map to double the Y component, so it's a grid of rectangles in which every other column is offset by a whole rect. Then I use a regular draw-a-line-on-a-grid algorithm derived from Bresenham, and at each step map back to the original hexes to build up the path the LoS takes. The upside is that it's simple and less likely to be implemented 'wrong'; the downside is that for every hex-to-hex line I have to pick whether to start or finish in the upper half or the lower half of the hex, and that part may need a little tweaking yet.
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 5 release, downloads in first post

#263 Post by DaFool »

Was able to upgrade successfully, thanks.

Question: is it possible to define an Unselect / Cancel Selection (or Hide Menu) option? I tried making an empty Skill but apparently the only way to get out is with

Code: Select all

        def PerformAction(self, fighter, target):
            fighter.EndTurn()
and I don't want to end the fighter's turn. If getting into the Skill selection menu is a non-backtrackable process, then I'll need to figure out how to define an empty action that closes the dialogue box, because right now all I get is a dead button.

(Although I patterned the overall battle mechanics after Valkyria Chronicles and in VC selecting a combatant is an irreversible action, the difference with a 2D mouse selection style is that I have to give leeway for accidental selection. Deselection is usually mapped to a right click or clicking away from the current selection)

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

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

#264 Post by Jake »

DaFool wrote: Question: is it possible to define an Unselect / Cancel Selection (or Hide Menu) option? I tried making an empty Skill but apparently the only way to get out is with

Code: Select all

        def PerformAction(self, fighter, target):
            fighter.EndTurn()
and I don't want to end the fighter's turn. If getting into the Skill selection menu is a non-backtrackable process, then I'll need to figure out how to define an empty action that closes the dialogue box, because right now all I get is a dead button.
If I'm following, you're looking for a way to cancel the selection of a fighter without ending their turn so that you can go back to the fighter-selection screen and still retain the opportunity to use that fighter in that turn?

Basically, if you want to do that right now, you'll have to write your own BattleMechanic to allow for it - if you check the wargame stuff in engine-wargame.rpy it kind of does a couple of similar things (including making use of the 'includeCancel' option on Fighter.PickSkill). However, sorting out turn-end properly is something I have on my radar - I had a go right when I started with Prioritisers, but I never really used them as much as I expected to when I first started coding, and that whole area is due a revisit...
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 5 release, downloads in first post

#265 Post by DaFool »

Yeah, after I posted it occurred to me that the wargame example has something to that effect (I haven't delved into the new code yet). Basically when selecting a character doesn't necessarily end their turn... it's only if you command them to move, attack, or both, that the end fighter turn is enforced. It also occurred to me that during a combined move+attack phase, the cancel selection option should be disabled right after the move command so that the only options left would be to Skip (without attacking), Move (if the move points haven't been fully consumed), or Attack/Magic choices.

On another concern, I noticed in the Wintervoices indie game that panning occurs when you move the mouse cursor to the edge of the screen. Since I have always been bugged by the onscreen panning buttons interfering with character selection, I had experimented some time ago with making the battle map occupy a smaller portion of the screen, but it didn't work well since the move/targeting hotspots are still active even if they occupy the 'dead zone' where the HUD is supposed to be located. So I decided to just trash the HUD for simplicity sake and just have the choices be context-based since the engine kinda does that already. I'm thinking now of making an empty 1-pixel wide panning button strip for each edge and have it activate on-hover instead of on-click. I'll verify when I get home if this will be easy enough to do, but I think this method is the most intuitive.

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

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

#266 Post by Jake »

DaFool wrote: Basically when selecting a character doesn't necessarily end their turn... it's only if you command them to move, attack, or both, that the end fighter turn is enforced.
Mm, I think the best approach is probably to do something with Priority, in the long run.

The way it's supposed to work is that a Fighter's Priority score is a percentage of how close they are to their next activation. So in an Active battle mechanic, we just increment the priority of everyone each tick based on their speed, and once a Fighter gets to 100 they get a turn. In turn-based mechanics, there's less of a need for that kind of thing, so it's more or less ignored... but I imagine that something like this requirement should probably be simple enough to do by setting the priority of everyone in the faction to 100 at the beginning of the turn, then having each skill that you want to 'lock' a fighter into acting decrease the priority a little (and force a Fighter.EndTurn() if applicable); the BattleMechanic then needs to not remove the fighter from the list of candidates until after their priority has gone down below 100. (This is a modification of plans for an Action-Point-based fighter activation system, and of course it may turn out to be cleaner to introduce a new stat in that manner than just decrease priority, even if it's just a "have I done something?" flag rather than literally AP.)

One other thing I've been thinking of recently is the possibility of modifying the behaviour of things like BattleMechanic (things that come out of the Schema, basically) via a generic battle-configuration settings collection, which should be easier for people to understand and use than having to supply constructor parameters all over the place. So perhaps this is a good starting point for that kind of thing - have a battleConfig.AllowCancelFighterSelection or something which you can set to True or False depending on whether you want people to be locked into their fighter selection or not.


DaFool wrote: I'm thinking now of making an empty 1-pixel wide panning button strip for each edge and have it activate on-hover instead of on-click. I'll verify when I get home if this will be easy enough to do, but I think this method is the most intuitive.
This is one of the options I've been considering trying, as well! The one concern that I have about it is that as I understand it, Ren'Py will give you a 'hovered' event when you first move your mouse over it, and then not give you another event until 'unhovered', which fires when you move your mouse off again. So you'll probably actually have to set up a new user-defined displayable or something with a short re-draw time which checks camera-speed rather than camera-position properties and modifies the camera-position based on those, and have the hover/unhover events set and unset the camera speed properties so that scrolling continues all the time that the mouse is hovered over the edge of the screen...

(And I would advise a strip slightly wider than 1 pixel, otherwise it'll be pretty hard to hover over in windowed mode...)

I imagine it would probably still bug the user a bit from time to time, just 'cause there'll be times when the user wants to click something right on the edge of the screen and the game pans instead when he moves his mouse over there, but hopefully it'd be a lesser effect.
Server error: user 'Jake' not found

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

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

#267 Post by Jake »

Here, have an auto-scroll extra. You can see it in action simply by copying the file into the Alpha 5 game directory and changing line 101 of scroll_demo.rpy from

Code: Select all

        battle.AddExtra(PanningControls(leftLabel=u'←', rightLabel=u'→', upLabel=u'↑', downLabel=u'↓', distance=250))
to

Code: Select all

        battle.AddExtra(AutoScroll())

It turns out it wasn't even so troublesome as I'd thought; I'd completely forgotten ui.timer when I wrote the earlier post, but it seems to work perfectly fine with that.

(The potential concern I have is that - since ui.timer isn't a Displayable and thus I'm not deliberately adding it to the scene myself - I don't know how long it hangs around. It seems to me from the behaviour I see that it probably lasts until renpy.scene is called for the layer it's on, or perhaps until a new ui.timer is declared, but I can't be sure without digging into it, and I don't have the time right now. So there's a small chance that the attached code actually collects up thousands of ui.timers over the course of a regular-length battle and will collapse under its own weight after a hundred turns! ;-)
Attachments
autoscroll.rpy
auto-scroll Extra for battle engine
(3.52 KiB) Downloaded 102 times
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 5 release, downloads in first post

#268 Post by DaFool »

It works very nice... still a little twitchy (I swear it feels like the panning actually speeds up or something), but works better than with the set-movement buttons.

I have managed to get a decent player faction vs enemy faction battle (I only recently have enough animated sprites to form teams), and the enemy turn takes really, really long... around 10 seconds per enemy. Maybe it's because it has to cycle through and analyze 400+ positions (20-24 squares on each side) But when an enemy decides to act it proceeds smoothly with the move and attack phases. I'm wondering whether I should just make a big hourglass graphic or something to show the player that the engine is still thinking (indeed it is impossible to pan during that time) right before a for loop is invoked.

I know I should remember this, but when an enemy has 3 available actions, with priorities 1,2,3 respectively, what are the probabilities of occurrence? All I know is 1 is the highest priority.

I'm kinda stumped regarding area effect spells/grenades. Should they be skills or should they be items? (since the devastation is so high, the use during battle is very limited, like a very special move. It seems better to limit them by number of items rather than use MP). I think someone mentioned shooting arrows before during the early parts of this thread, but how would projectile attacks be implemented? Instead of an effects animation occurring both to the caster and the target at the same time like with a regular magic attack, a 'launch' animation must start from the caster, then a moving sprite of the projectile must be animated as it is guided towards the target, then finally an explosion effect happens at the target site.

Also, is there an example of how to use the new XP levelling? I'm looking at engine-xp.rpy and it seems incomplete.
Let's say before I call a battle I have this:

Code: Select all

    $ clyde_speed = 80  #or clydestatmanager.speed once the RPG system is set up and I have a class that determines levels and attributes based on XP
    $ clyde_move = 7
    $ clyde_attack = 10
    $ clyde_defence = 10
    $ clyde_health = 100
    $ clyde_MP = 30
    $ clyde_Ini = 4    
Then I declare a battle with

Code: Select all

        clyde = PlayerFighter("Clyde", Speed=clyde_speed, Move=clyde_move, Attack=clyde_attack, Defence=clyde_defence, Health=clyde_health, MP=clyde_MP, Initiative=clyde_Ini, sprite=clydeSprite)
clyde is already a Fighter object that has starting stat values and interim values as he takes damage during a battle. How does one go about implementing the following scenarios:
1. Clyde defeats an enemy and levels up during the battle, permanently upping his base stats.
2. Clyde defeats an enemy and XP is collected which can either be allocated by the player or automatically applied, but that's done after the battle so the battle must keep remembering to add the XP.

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

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

#269 Post by Jake »

DaFool wrote:It works very nice... still a little twitchy (I swear it feels like the panning actually speeds up or something), but works better than with the set-movement buttons.
The panning quite possibly does speed up a bit... it'll use whatever the default panner in your schema is (which is the SmoothPanner, using an ease-style warp of time/movement). If you want a linear pan, you'll need to implement a linear panner (or wait for me to do the same thing ;-).
DaFool wrote: Maybe it's because it has to cycle through and analyze 400+ positions (20-24 squares on each side)
Hmm... it should only be checking positions which the Fighter in question can actually get to, but the naïve implementation in MovingAIFighter will increase in order by the number of squares available to move to and also the number of Fighters in other factions. There's a lot of inefficient code in there which is just waiting to be optimised, though - a fair amount of the grid functionality is still using identical generic-network-of-nodes logic to the path battlefield, where the fact that the squares are laid out in a grid actually simplifies the work a lot. Plus, there's lots of scope for caching of intermediate results, which would help!

Basically, when I wrote the battlefield classes originally I figured I'd come back and clean them up later and functionality was more important than efficiency right then, and when I wrote the AI Fighters I figured I was really just writing a stopgap AI for the demo code and people would just write their own AI for anything serious... but then I expanded them a bit and they started to look more capable after all.
DaFool wrote: I know I should remember this, but when an enemy has 3 available actions, with priorities 1,2,3 respectively, what are the probabilities of occurrence? All I know is 1 is the highest priority.
The numbers are weighting. So if you give skill A '1' and skill B '2', it should pick skill B twice as often; A=10 and B=1 should pick B one time out of eleven.
DaFool wrote: I'm kinda stumped regarding area effect spells/grenades. Should they be skills or should they be items? (since the devastation is so high, the use during battle is very limited, like a very special move. It seems better to limit them by number of items rather than use MP).
This is really a game-design question... Items are basically single-use-only Skills; for the most part they behave the same way, it's just that Skills can be used as many times as their IsAvailable method allows, while Items can only be used once and they're automatically removed from the inventory.

So if you want a specific guy to be able to cast explode-over-five-squares magic whenever he has sufficient MP, make it a skill; if you want anyone to be able to throw an explode-over-five-squares grenade but for grenades to be in controllably-limited supply, make it an Item.
DaFool wrote: I think someone mentioned shooting arrows before during the early parts of this thread, but how would projectile attacks be implemented? Instead of an effects animation occurring both to the caster and the target at the same time like with a regular magic attack, a 'launch' animation must start from the caster, then a moving sprite of the projectile must be animated as it is guided towards the target, then finally an explosion effect happens at the target site.
Basically that! I've been meaning to come up with an example for some time, using a directional magic-bolt sprite that gets rotated to suit and moves through space using a similar method to the Move skill (that is, in steps with changes in Z periodically, unless PyTom adds the ability to transition Z in a transform before I get around to it).

DaFool wrote: Also, is there an example of how to use the new XP levelling? I'm looking at engine-xp.rpy and it seems incomplete. Perhaps you're still determining how to interface it?
Basically, yes - it is incomplete, and non-functional in the form that got into Alpha 5 accidentally.

I actually finished a first-draft of it this lunchtime, but I've not even tested it yet, so I'll have to get back to you on an ETA... ;-)


The plan right now is for something along the lines of:

Code: Select all

  xp = ExperienceTracker()

  clydePlan = LevelPlan()
  clydePlan.AddLevel(500, {"Attack": 5, "Defence": 2, "Health": 25})
  clydePlan.AddLevel(1000, {"Attack": 8, "Defence": 6, "Health": 50})

  xp.AddPlan(clyde, clydePlan)

  battle.AddExtra(xp)
So this would set Clyde up with a new Level-based experience plan: once he gets 500 XP, he increments a level, and at that point gains 5 Attack, 2 Defence and 25 Health (as additions to his existing BaseStat values); once he gets a further 1000 XP (so 1500 in total) he gets an additional 8 Attack, 6 Defence and so on.

(The base classes I've written so far - presuming they work - are actually quite capable of watching any stat and providing any kind of change to a Fighter's state based on any stat-change crossing a pre-defined threshold, the LevelPlan is just the simplest 'default' implementation. So you could have things like Fighters gaining XP when their health gets low, or gaining stat increase straight off the back of XP without needing Levels, or whatever. I'm still wondering if I could make it easier to use, but then again you're always going to have to supply a certain amount of information to make a working levelling scheme!)
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 5 release, downloads in first post

#270 Post by DaFool »

Thanks to the answers to the multitude of questions!

Regarding xp, I'm thinking the enemies should carry an xp value upon defeat (another parameter). Another possibility is that they can share the same xp levelling scheme... so the player fighters can be Lvl. 16 and the monsters can be Lvl. 18, and a multiplication factor is introduced if a player is able defeat a monster a certain number of levels above it. (And then later on you might be able to combine them Disgaea style and enjoy the benefits of massive leveling up up by stacking monsters right before you defeat them). Combine that with the ability to add an item drop to the inventory upon defeat and that's basically the whole JRPG system already. Right now though both the players and enemies share the same RPGDeath.

Post Reply

Who is online

Users browsing this forum: No registered users