UPBGE 0.2.5 - How to integrate an advanced multi-damage system into an Enemy AI using Logic Bricks?

Hello everyone!

I am developing my


game in UPBGE 0.2.5 (based on Blender 2.79) and I need some guidance on architecture.

Currently, I have a working setup split into two parts: an invisible Cube that holds the Enemy AI logic (states like patrolling/chasing via an ia integer property), and an Armature parented to it that handles the visual actions.

Now, I want to implement a complex combat system with 10 different types of damage/status effects (such as regular hits, knockbacks, stun, freeze, and floating/levitation effects).

My main questions are:

  1. What is the cleanest way to structure this inside the Logic Bricks so it doesn’t get completely cluttered?
  2. Is it better to handle the damage types by assigning IDs (like damage_type = 1, 2, 3...) on the Cube and sending them to the Armature’s Actions, or should I start moving this specific part to Python?
  3. How can I safely pause the AI movement state (e.g., changing ia property to a hit-stun state) and ensure it resumes perfectly after the specific VFX/animation delay ends?

Any advice, logic setups, or small .blend template examples would be highly appreciated!

Thank you!

you may consider using some python scripting for more state based action assignments. I find them easier to understand through code perhaps. :saluting_face:

UPBGE has lots of glitch, I regret porting my game from 2.79 to 2.79.7.
The glitch as follow .

By using sensor logic and mostly action actuators glitch.

  1. PlayAction glitch, sometime not play or skipped, in my case some of the animations going freeze.
  2. Loop action must start with true level tick activated, make the low performace if too many of them.
  3. while changing state (back ond forth), the remnant of previous action will replay when back to the previous action state.

the biggest glitch is physics
Character Physics with collision sensors, when active reduce performance heavily.
The mesh collision type still the same to any version, like ground as if very thin.

unfortunately, BGE/UPBGE/RANGE developpers never really cared to document the “know-how” and prefered spend time adding new features and so many people keep making wrong because using some flawed old youtube tutorials

by doing this you call the actuator to play the action at each logical tic , which is a non-sense. You should be able to boot at start that actuator with a single “Awalys” sensor without spamming postive - nor negative - tics. That would be for your looping animations (idle, walk, run …) . If you want to play a single action above it , you can use a second action actuator on a higher layer and pulse it only occasionnaly (so no tic spam).

Beside that, pay attention to the animations. BGE doesnt like to interpolate keyframes. I noticed some glitches too in that case. So keyframe each frame and for each bone.

image

Those 3 often means …

image

… And yes, the problem is that it works … but its backed by no logical thoughs

In most very few cases, you need to use 1 of them to pulse a python script/module or if you want to increment/decrement a property actuator … But using those to play animations,sounds or check a condition is just completely wrong

Here’s a simple setup. It plays an action attack on demand and over-rides the looping continuous action playing in the background (layer 0).

Be aware that it over-rides only common bone channels and not channels of Layer0 inexistant in the animation of Layer1

So with this, you may want to study more from the python API to go further

The Logic Bricks

The code to copy-paste into the script

import bge

scene = bge.logic.getCurrentScene()
so = scene.objects

### the 2 scene objects used in this code
cube = so['Cube'] ; arm = so['Armature']

### the attack action actuator
hit = arm.actuators['hit']

### True when button is just pushed
p1 = cube.sensors['k1'].status == 1
p2 = cube.sensors['k2'].status == 1
p3 = cube.sensors['k3'].status == 1

### if True : play this action and increment property
if p1 : hit.action = "roll_1" ; hit.frameEnd = 300 ; cube['prop_1'] += 1
elif p2 : hit.action = "roll_2" ; hit.frameEnd = 300 ; cube['prop_2'] += 1
elif p3 : hit.action = "roll_3" ; hit.frameEnd = 300 ; cube['prop_3'] += 1

## toggle 'tic' property when any is true
if any([p1,p2,p3]) : arm['tic'] = (arm['tic'] == False)

You can make code to change and update the looping action too. For exemple, to switch from ‘idle’ to ‘walk’ to ‘run’ … then back to ‘idle’ … etc