Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

[Game Design] Battle buffs

Scenario
Active Time Battle system

Analysis
Most implementations add buffs as an after-thought and do not respect how the addition changes gameplay.
The most frequent scenario is that the player learns the underlying system behind the buff and uses this knowledge to their advantage in battle, this results in;
  • Players learning the underlying stats of monsters to maximise the effect of the buffs
  • Buffs becoming an item to be tracked and monitored in battle scenes
  • Comparisons are made between status effects and buffs to find which are more affective
  • Some buffs go unused, others are exploited
Often many players will simply avoid teaching their party "support spells" as they are seen as not as useful as damage or healing spells, making implementation of support spells pointless.

Games can go either way with this; The buffs can be made more effective to encourage use with the cost of chance to hit or they can be made less effective with a high chance to hit.

The player needing previous knowledge of how many turns before a buff is removed only adds to what they need to track during a battle.

Technical
Buffs are usually stored as flags such as "Reduce attack by 10%" or "Apply sleep effect".
Each buff will have some sort of event for removing itself such as "After 5 turns remove buff" or "If item X is used remove buff".
Some buff flags may also modify the flags for other buffs, as an example a sleep debuff may override a confusion debuff or a speed buff may override a slow debuff (Or cancel out a slow debuff).
Using a support spell usually costs the same amount of ATB speed as any other action, effectively taking up a full "turn" of the caster.

Battle World's Solution
Status effects and buffs are moved from being a flag to being on a stack.
During the net-effect calculation the stack is traversed from bottom to top, any status that overrides another will cancel out the effect at this moment.
Buffs are reduced in effectiveness, however they cost 50% ATB speed as opposed to the full 100%, making the buff less costly.
In addition to this, all buffs can be stacked.
Buffs and statuses are removed from the stack top-down as their removal conditions are met.
Status effects such as sleep can be stacked, making the effect "deeper". The target may need to be hit several times before all sleep effects are removed, along with the sleep effects being removed after X number of turns.
Some statuses clear the stack, such as "Death", which removes everything from the stack but applies the death effect to the actor.

The applied buffs are displayed above the actors.

Benefits;
  • Applying a buff before each attack becomes a new tactic; [applying a defense increase buff before an attack against a monster that auto-counters, applying two sleeps in a row to deepen a sleep, applying multiple auto-regens on an actor to make up for a low-defense]
  • Players are less inclined to think about when a buff wears off; if the player is unsure that a buff will last they may reapply it to strength the current effect and re-add it to the top of the stack, the challenge of this is organising the order of buffs for those that nullify others in the stack
  • Reducing target's armour by 5% is more useful when you can stack it up during a full battle-round to take the armour down by 40%

Draw-backs;
  • Adds a new layer of complication to new-comers (The system can be ignored and treated like any other buff system, but having a speed + slow buff together may be confusing to see)
  • The effect override can become complicated to manage, it will encourage dedicated players to learn the system and understand how it works (Which rewards players who put in the research), however there is a risk of creating confusion where a buff wears off and the effect that it overrides becomes apparent.
  • How does this work for buffs that last after battle is more difficult. Does poison last after battle? Does 5x poison require 5 antidotes?

Unexplored additions
  • Items 100% remove a specific type of debuff from the stack (Antidote removes all poison debuffs), makes items more useful but this could be frustrating if enemies have the ability to use items. More thought is needed here for specific enemy script (Certain enemies always use antidotes when poisoned?)
  • Perhaps do something with over-saturation of an effect?
  • Spells apply different number of effects to the stack? [Poison applies 1x HP drop, Toxic applies 2x HP drop?]
  • How does this work with nullify and constant equipment? (How does regen helmet fit into this? Always keep buff on top of stack? Have nullifies stackable?)

Examples

[Status Stack: Actor1]
[Regen]
[Regen]
[Poison]
[Armour +10%]
[Armour +10%]
[Speed +10%]
Actor 1 has speed +10%, armour +20%, a poison effect that is nullified by a regen effect and a bonus regen effect.


Apply Armour -5%, Attack once, repeat for steadily increasing attack power every 1.5 turns.
After 5 turns debuff is removed, so 3 effective armour -5% can be applied by each actor in between an attack, in a 4 actor party this can be a 60% armour reduction by target after 6 full rounds, with attacks in-between.
Alternatively, 4.5 rounds each can be spent applying the debuff so at round 5.0 the entire party attacks at once with a 90% armour reduction or a single actor can perform the attack with 3 spares applying a final debuff for a 105% armour reduction.

Statuses
  • Death
  • Drop
  • Charge
  • Haunted
  • Confused
  • Asleep
  • Raged
 
Scenario
Previous engines notorious for undergoing incremental improvements over a long period of time and becoming redundant in technology and design.
While the learning experience is good, it is not a good idea for these experiences to reach commercial production as they have done in past iterations.

The problems that Gen 4 face need to be analysed and detailed so steps can be made to improve the engine and create a more robust development environment that meets the new requirements that the engine is now facing.

The Gen 4 engine has now gone beyond the scope of just Battle World and is being used in commercial products on a variety of platforms, this was not the original intention and problems have already arisen around the engine's first projected development plan and the current use it has.

History
  • Gen 1 – High level software graphics, single threaded, Lua script, no modularity
  • Gen 2 – High level hardware graphics, single threaded, Lua script, no modularity
  • Gen 3 – High level hardware graphics, some threading support, Angel script, high modularity, networked
  • Gen 4 – Hardware graphics, some threading support, Ruby script, medium modularity

It is a bad idea to create an engine when you are learning especially now that engine technology has evolved so much.

I wrote an analysis paper for creating a game engine, which won the award for project of the year for my university, the focus of the paper was the mistakes made during engine Gen 3's production and the lessons learnt from that contributed to Gen 4, the current working engine technology that is now powering high-performance 3D mobile applications.

The biggest problem identified with the previous engine developments is the dependency chain which hampered portability, code-health, maintainability and legibility, this is a problem frequently found with high level engines, removing the dependencies for Gen 4 has greatly helped it in most aspects.

Generation 4 Problems
Memory allocation was identified as a bottleneck during Gen 3's analysis with a recommendation to use custom memory allocators with fixed limits to improve performance at the cost of safety, however this was not adopted by Gen 4 as additional research into allocator implementation is required.
At this moment, C is the most appropriate language for custom memory allocation and research in this language is mostly complete, the inevitable C++ implementation has not been started and has had no research.

Too much work is placed on the Gen 4 main thread; threading paradigms were analysed with a conclusive paradigm given in the Gen 3 report, however this was not implemented as part of the Gen 4 graphics library (Hardened Edge) until performance problems were becoming apparent on mobile devices.

There are also problems with header clashing where different operating system's internal headers are being included with engine API headers, causing reservations with common function names (AddJob on the Win32 API is a frequent headache), in addition to this the mobile/desktop graphics APIs are frequently split with pre-processor definitions, there is no layer between the graphics API and the graphics engine.

Scripting environment is not implemented due to current project plans. A scripting environment is pretty much needed in modern development for rapid iteration and quick content creation.

Texture generation is the slowest area of graphics API interaction, the Gen 4 texture loaders are designed to create textures on the GPU as soon as the texture is read, this is a mistake as it means there is a GPU lock and the use of the graphics API restricts this to the main thread, causing a massive slowdown for this area.

Future projects
Generation 4 showcased stereo 3D rendering with VR development in mind and the high portability led to mobile applications being the main focus, both VR and mobile applications require high frame-rates for the best end-user experience and particularly on mobile application load-time is expected to be minimal.

This engine is now too developed for a clean re-factoring and at this point it is now a better idea to reimplement with VR and low-power devices in mind.

The current outlook for devices is more threads, more cores, more physical processors, more memory, but not faster clocks, it is now even more crucial to think about clever methods of keeping a high frame-rate rather than optimising functions and expecting them to run on a future generation of faster processors.

The mobile API in particular need to be more independent and less reliant on the mobile operating systems which hinder performance and invade the application run-time more often than necessary (Android comes to mind here).

Shaders are per-material and not per-object and are difficult to interact with from application.

Improvements
The graphics API must run on the thread of the spawning context with the scene objects managed in dedicated memory space and pushing calls for the graphics API safely from their managed thread.

Texture streaming is now worth it, the conventional method of generating GPU textures presumes that the texture is already loaded and ready to go onto the GPU, to reduce load times it is now better to load textures as they are needed during run-time and load them directly into memory that is planned to be mapped onto GPU memory.
This also allows for streaming video data or other external texture data as the frame is readied, ideal for projects that require this.

2D rendering should be explored. At the moment this is largely unexplored but is increasingly more often required. Gen 2 utilised a dedicated 2D buffer for UI elements, something similar could be useful, but ultimately a new UI API will be needed.
A lot of potential for a bespoke, independent UI API is around the corner, so this could be implemented as a new module entirely.
Font rendering is important for 2D rendering.
Rendering to any surface is very useful, allows in-game UI controls (Doom 3 style interactive monitors)

Shader binding class, called when specific shaders are bound with a pointer to read-only memory. The memory is written to by any point that wishes to modify shader programs through the binding class.
Stepping away from fixed-named shader variable is important, however the GLSL version differences are a problem between mobile and desktop, it could be worth introducing a second language that generates the required GLSL code, perhaps the scripting language can be used for this?
Shaders written in Ruby would be fantastic.

An engine console and networked interface aligns well with future project plans, particularly with Battle World's unique use of networking systems.
The protocol should be compatible with both thread communications and networked communications depending on the context; additional research is required here as well as IPv6 testing for IP networking.

Conclusion
The growth of Gen 4 should be locked down with immediate effect until the first set of products have been released.
By locking down the engine, modules that were originally designed within Battle World's scope can be jettisoned for development as individual components with the intention of running them on Gen 4 and future engine builds.

Unfortunately this looks like another failure for Battle World but a great success in testing the new development practises and designs suggested by my Gen 3 report. The differences between Gen 3 and Gen 4 are worlds apart, so any future changes will now appear minimal in contrast, which indicates that things are going right.

There is also an opportunity to start developing engine tools that are in-engine as this technology is now at hand with the new resources accessible to Gen 4, this is an opportune moment to expand licensing of the graphics engine to cover clientèle usage and no longer keep the engine as an internal-tool (The demand for this is also high at this moment).
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top