principia icon indicating copy to clipboard operation
principia copied to clipboard

Robot Manager targetting an absorbed robot crashes the game on Windows with certain inputs

Open MineCake147E opened this issue 2 years ago • 6 comments

Principia version

1.5.2 Beta build 2023-12-26

OS / Hardware
  • Platform: Custom built PC
    • Operating System: Windows 11 Home 22H2 (22621.2861)
    • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
    • RAM: 32 GB DDR5 ECC RDIMM
    • Graphics: NVIDIA GeForce GTX1060(6 GB)
    • Storage:
      • OS (C: ) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
      • DATA (D: ) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
      • WORKSPACE (E: ) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
Summary

image

  1. The level is set to the Adventure mode.
  2. There is a Robot Manager.
  3. Aside from the Adventure Robot, there's an additional robot that is controlled by the Robot Manager with its IN16 is somehow activated, while being somehow absorbed.
  4. After the simulation starts playing and the controlled robot is absorbed, the Principia crashes.

Here is a table of Inputs that crash the game when the controlled robot gets absorbed.

Input ID Crashes Description
0 God mode ON/OFF.
1 Speed modifier (0.0-1.0). Only enabled if the cable is plugged in. A value of 0.0 means the robot is unable to walk.
2 Disable action (useful for disabling box mode until certain power up is enabled).
3 Jump strength multiplier.
4 HP increase (heal), value * 10
5 HP decrease (damage), value * 10
6 Max HP increase, value * 10
7 Max HP decrease, value * 10
8 Weapon damage multiplier 0.0 = No extra damage, 1.0 = 5 times the damage.
9 Toggle robot action.
10 Walk left.
11 Walk right.
12 Stop all movement.
13 Jump.
14 Aim.
15 Attack.
16 Attach to nearest backpack/RC
17 Detach from any backpack/RC
18 ✅* Respawn
19 Freeze
20 Toggle roaming (non-adventure robots only).
21 Cycle weapons
22 Cycle factions

❌: The game doesn't crash ✅: The game crashes

* For IN18, the robot under control doesn't fall. There are some additional set of conditions to crash the game. To crash the game, one of these conditions below must be satisfied.

  1. The robot should initially be touching the Absorber.
  2. The IN18 of the Robot Manager should be connected to the OUT0 of the Absorber, so that the Robot Manager lets the robot respawn only after the robot is absorbed.
Steps to reproduce
  1. Create a new Empty Adventure level.
  2. Put the things listed below:
    1. A Robot Manager.
    2. One of any kind of Robot that can be controlled by a Robot Manager.
    3. Some object that absorbs the robot.
    4. A Jumper with the value set to 1.0.
  3. Connect the Jumper to the IN16 of the Robot Manager.
  4. Let the Robot Manager track the Robot.
  5. Play the game.
  6. Observe the Principia crashes.

MineCake147E avatar Jan 01 '24 07:01 MineCake147E

Can indeed reproduce.

image

Strangely only crashes on Windows, works fine on Linux.

rollerozxa avatar Jan 12 '24 22:01 rollerozxa

i think this is another use after free...?

griffi-gh avatar Jan 12 '24 23:01 griffi-gh

Yes, obviously.

rollerozxa avatar Jan 12 '24 23:01 rollerozxa

seems like the Robot Manager never receives ENTITY_EVENT_REMOVE, even though it's subscribed to it
literally have no idea why this doesn't work, since Lua Script relies on the same event and it does work there... (even if it's actually not handled properly)

griffi-gh avatar Mar 30 '24 00:03 griffi-gh

seems like subscriptions get reset??? between initialization and actual absorb.
calling subscribe every frame (hack) fixes the issue....??

griffi-gh avatar Mar 30 '24 00:03 griffi-gh

https://github.com/Bithack/principia/blob/87b00fb5930a03be0bce75fae8e2b6e86eccd0bc/src/src/entity.hh#L839-L845

... interesting...
seems like this is a side effect of the default setup implementation, which clears all listeners and subscriptions
(The robot manager subscribes to the ENTITY_EVENT_REMOVE event in the init "stage", which gets called before setup)

Commenting out the following lines in the setup implementation "fixes" the issue:

// this->listeners.clear();
// this->subscriptions.clear();

image

But I'm pretty sure this has some unintended side effects...

By the way, saving and reloading the state before the robot is absorbed causes the game to not crash, since setup is not called if the level is reloaded from a state buffer:

https://github.com/Bithack/principia/blob/87b00fb5930a03be0bce75fae8e2b6e86eccd0bc/src/src/entity.cc#L560-L578

griffi-gh avatar Mar 30 '24 00:03 griffi-gh