denniskaselow / dartemis

A Dart port of the Artemis Entity System Framework
BSD 2-Clause "Simplified" License
49 stars 6 forks source link

More than 32 entities with the same components #55

Closed Norbert515 closed 3 years ago

Norbert515 commented 3 years ago

Hi, it seems like

void processEntity(int entity) {
   someMapper.getSafe(entity);
   ...

returns null if more than 32 entities of this component combination exist at the same time.

In my use case, I have a weapon system that fires bullets at a specific interval. These bullets are destroyed after a specific amount of time by another system (or when they collide). When I increase my fire speed over a specific threshold, the game break with null errors.

Happy to provide more information if it's needed!

denniskaselow commented 3 years ago

Is this your only entity which exists more than 32 times? Or the only one where this bug happens?

Does the system only use Aspect.allOf or also Aspect.oneOf?

What is returned If you use world.componentManager.getComponentsFor(entity)? An empty list or a list of components that should not be handled by this system?

Norbert515 commented 3 years ago

For testing purposes, I increased the fire rate and my MovementSystem throws an exception.

class LinearMovementSystem extends EntityProcessingSystem {

  LinearMovementSystem() : super(Aspect.forAllOf([PositionComponent, VelocityComponent]));

  late Mapper<PositionComponent> positionMapper;
  late Mapper<VelocityComponent> velocityMapper;

  @override
  void initialize() {
    positionMapper = Mapper<PositionComponent>(world);
    velocityMapper = Mapper<VelocityComponent>(world);
  }

  void processEntity(int entity) {
    PositionComponent? position = positionMapper.getSafe(entity);
    if(position == null) {
      var it = world.componentManager.getComponentsFor(entity);
      print(it);
      return;
    }
    VelocityComponent vel = velocityMapper[entity];

    position.lastPosition = Vector2(position.x, position.y);

    position.x += vel.x;
    position.y += vel.y;

  }

}

When breaking at it, it shows that both the PositionComponent and VelocityComponent are present:

Screenshot 2021-06-18 at 20 57 17
Norbert515 commented 3 years ago

Some more information in the debugger. This also shows that this is entity number 32 - position is null even though it is present in components

Screenshot 2021-06-18 at 20 59 11
denniskaselow commented 3 years ago

It probably throws an exception if you use final position = positionMapper[entity] instead?

Norbert515 commented 3 years ago
======== Exception caught by scheduler library =====================================================
The following RangeError was thrown during a scheduler callback:
RangeError (index): Invalid value: Not in inclusive range 0..31: 32

When the exception was thrown, this was the stack: 
#0      List.[] (dart:core-patch/array.dart:110:52)
#1      _CastListBase.[] (dart:_internal/cast.dart:99:38)
#2      Mapper.[] (package:dartemis/src/core/mapper.dart:17:44)
#3      LinearMovementSystem.processEntity (package:hacknslash/game/general/ecs/movement/position.dart:55:48)
#4      List.forEach (dart:core-patch/growable_array.dart:403:8)
...

Yeah

denniskaselow commented 3 years ago

Damn. Guess I introduced a serious bug when going from 0.8.0 to 0.9.0. 0.9.2 coming soon ;).

denniskaselow commented 3 years ago

0.9.2 is on pub and it should work now.

Thanks for opening the issues. I haven't used the nullsafe version of dartemis yet, because I'm waiting for nullsafe AngularDart, otherwise I'd have run into this bug too.