396 Commits

Author SHA1 Message Date
Dylan K. Taylor
56da492e48
World: make less noise about deleted tile entities
no need to repeat the same message 100 times
2025-05-28 22:10:20 +01:00
Dylan T.
059f4ee7bf
Extract GeneratorExecutor system from World, v2 (#6682)
- `AsyncGeneratorExecutor` class added that encapsulates the logic of generating chunks using async tasks as previously
- `GeneratorExecutor` interface added that can be implemented to provide chunks in other ways
- `SyncGeneratorExecutor` which invokes the generator directly on the main thread, useful for simple generators like `Flat` where async tasks are not needed
- Some redundant APIs were removed from `World` (these will probably come back as deprecated stubs for the remainder of 5.x, but I was having too much fun deleting code)
- Removed internal `World->registerGeneratorToWorker()` (no longer useful)
- `World` now invokes generator executor instead of posting AsyncTasks directly
- Some internal classes moved to `pocketmine\world\generator\executor` (PopulationTask excluded because plugins use it in lieu of being able to regenerate chunks
- Generators can opt into main-thread execution by setting the `$fast` parameter to `true` in `GeneratorManager::register()`
2025-05-27 21:51:10 +01:00
Dylan K. Taylor
6196b9c995
Merge branch 'stable' into minor-next 2025-05-04 17:20:27 +01:00
Dylan K. Taylor
f2e7473629
Update PHP-CS-Fixer 2025-05-04 17:19:15 +01:00
Dylan K. Taylor
fe70b31881
Fix crash when a player is added to the world 2025-04-26 22:11:03 +01:00
Dylan K. Taylor
ad6f7dfedb
World: verify saveability of blocks, entities and tiles at entry points
I want to do the same for items, but items are going to be a pain in the ass.
For items there are multiple possible entry points and all of them will need to be checked:
- dropped items
- inventory contents
- lecterns
- item frames

I don't see a good way to deal with all these. We can't check for registration in the constructor
because we need to fully construct the item in order to register it.

Blocks are also a potential issue in other areas, but setBlock() is definitely the biggest offender.
2025-04-20 19:48:28 +01:00
Dylan K. Taylor
51cf6817b1
World: fixed overflow checks for getCollisionBlocks(), closes #6630 2025-02-16 23:24:39 +00:00
Dylan T.
9b3b45258a
Optimise collision box checks by caching some basic info (#6606)
This PR significantly improves performance of entity movement calculation.

Previous attempts to optimise this were ineffective, as they used a cache to mitigate the cost of recomputing AABBs. Entities tend to move around randomly, so the non-cached pathway really needed to be optimized.

This change improves performance on multiple fronts:
1) avoiding Block allocations for blocks with 1x1x1 AABBs and with no AABBs (the most common)
2) avoiding Block allocations and overlapping intersection checks unless a stateID is specifically known to potentially exceed its cell boundaries (like fences)
3) avoiding overlapping AABB checks when overlaps can't make any difference anyway (cubes)

Together, these changes improve the performance of World->getBlockCollisionBoxes() by a factor of 5. In real-world terms, this shows up as a major performance improvement in situations with lots of entities moving in random directions. Testing with item entities showed an increase from 400 to 1200 moving items with the same CPU usage.

This change is built on the assumption that `Block->recalculateCollisionBoxes()` and its overrides don't interact with any world. This is technically possible due to the crappy design of the `Block` architecture, but should be avoided. As a world is not available during `RuntimeBlockStateRegistry` initialization, attempting to interact with a world during `recalculateCollisionBoxes()` will now cause a crash.

This turned out to be a problem for `ChorusPlant`, which was fixed by 70fb9bbdfd06c7eda00b4cd2c2c3840755e6b8f6. The correct solution in this case was to use dynamic states similar to how we currently deal with fence connections.
2025-02-06 15:42:10 +00:00
Dylan K. Taylor
cd59e272bc
PHPStan 2.0 fixes 2025-01-07 22:10:42 +00:00
Dylan K. Taylor
357dfb5c7e
Fixed build 2025-01-06 23:01:14 +00:00
Dylan K. Taylor
b6bd3ef30c
Improve PHPDocs in world package 2025-01-06 22:46:16 +00:00
Dylan K. Taylor
cf1b360a62
World: Prevent block cache from getting too big
This has been a long-standing issue since at least 2016, and probably longer.
Heavy use of getBlock(At) could cause the cache to blow up and use all available memory.

Recently, it's become clear that unmanaged cache size is also a problem for GC, because
the large number of objects blows up the GC root buffer. At first, this causes more frequent
GC runs; later, the frequency of GC runs drops, but the performance cost of them goes up
substantially because of the sheer number of objects. We can avoid this by trimming the
cache when we detect that it's exceeded limits.

I've implemented this in such a way that failing to update blockCacheSize in new code
won't have lasting impacts, since the cache count will be recalculated during scheduled
cache cleaning anyway.

Closes #152.
2024-12-15 18:40:32 +00:00
Akmal Fairuz
269effcecf
Introduce Utils::getRandomFloat() (#6532)
Drop-in replacement for lcg_value() for PHP 8.4
2024-11-26 11:33:29 +00:00
pmmp-restrictedactions-bot[bot]
8ccd1edb17 Merge 'stable' into 'minor-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11904511045
2024-11-19 01:36:11 +00:00
Akmal Fairuz
faf1e26bac
Fix: implicitly nullable parameter declarations deprecated (#6522) 2024-11-18 23:54:22 +00:00
Dylan T.
ff695a5f97
PlayerInteractEvent: added APIs to independently control reaction of item and block (#4683)
This allows, for example, banning the usage of spawn eggs, without preventing opening of doors, without the need for item ID whitelists.

It also allows customizing the behaviour of item and block interactions when sneaking - it's now possible to force spawn eggs to work when sneaking, or force containers to open.

Finally, this also allows preventing any interaction at all without preventing block placement (by setting both to false). Since cancelling the event will typically prevent placement too (which might not be desired).

Side note: Blocks are now always synced when right-clicking on a block.
This differs from the previous behaviour, where the blocks were only synced when the action "failed".
However, since this change introduces a situation where the action may succeed but have different results than the client expects, it's best to just always sync blocks in this situation.

Fixes #3267
2024-11-15 21:19:54 +00:00
Dylan K. Taylor
06b2e61d3c
Merge remote-tracking branch 'origin/stable' into minor-next 2023-12-14 14:02:15 +00:00
Dylan K. Taylor
67ad2bad17
World: fixed edge case that could lead to crash during block update sending 2023-11-17 13:24:06 +00:00
Dylan K. Taylor
e9c5846a06
World: simplify condition 2023-11-16 10:06:43 +00:00
Dylan K. Taylor
d09af2e30d
World: don't assume that random Vector3 are int vectors
we can safely assume this for blocks (though the type info doesn't reflect it) but this is not safe to assume for random APIs that might be used by plugins.
2023-11-06 17:15:17 +00:00
Dylan K. Taylor
457660235e
Crops must have access to a light level of at least 9 2023-11-06 16:02:57 +00:00
Dylan K. Taylor
9832fe899f
Merge branch 'stable' into minor-next 2023-11-01 16:39:44 +00:00
Dylan K. Taylor
e6e2c54ec9
Fixed various reentrant-unsafe 2D array element unsets (similar to previous commit)
this pattern was used in various places
2023-11-01 16:28:59 +00:00
Dylan K. Taylor
9eb2a46942
World: remove useless isChunkLoaded checks
getChunkEntities() will return an empty array if the chunk isn't loaded anyway, so this is just wasting CPU cycles.
2023-11-01 15:53:37 +00:00
Dylan K. Taylor
8491d3c6c0
Merge branch 'stable' into minor-next 2023-10-24 11:56:51 +01:00
Dylan K. Taylor
af432c1a7f
Give neighbour block updates its own timer
this way we aren't conflating them with scheduled updates, which are usually caused by e.g. water
2023-10-23 12:33:36 +01:00
Dylan K. Taylor
41c5f63565
World: remove dead code 2023-10-23 12:17:41 +01:00
Dylan K. Taylor
8fa5c7cdab
World: do not apply fake state properties from tile if the block doesn't expect this tile type
This was causing a variety of crashes due to incorrect tiles, presumably from PM3 worlds.
2023-10-20 10:28:46 +01:00
Dylan K. Taylor
7dd3a70d2e
Revert "World: discard tiles on load if they aren't the correct type or no tile is expected"
This reverts commit 8f804f6f342e650156767372bac2d42b55297361.

This change is too disruptive, since popular plugins like
ExtendedBlocks and ExtendedBlocksConverter relied on custom tiles.
Deleting them at this stage would prevent these plugins from working,
making it impossible to upgrade old data.

An alternative solution to this problem will need to be developed.
2023-10-20 10:16:49 +01:00
Dylan K. Taylor
73659318f6
World: Avoid unnecessary Vector3 usages in neighbour block update scheduling
The old code was allocating 6 Vector3s which were all immediately discarded. In addition, we didn't need to take the performance hit of reading Vector3 properties when we could have just passed integers directly.
The real performance difference of this is likely to be close to zero, but it's still worth doing.
2023-10-19 16:46:52 +01:00
Dylan K. Taylor
ccd2cdd324
World: improve performance of calculating non-cached AABBs for a cell
Avoiding getSide() improved the performance by 2x ...
2023-10-19 13:13:46 +01:00
Dylan K. Taylor
c7a358a56f
World: extract getBlockCollisionBoxes() from getCollisionBoxes()
closes #6104

This function has been a footgun for anyone using it, since it also returns entity AABBs by default.
In all core use cases, this functionality was disabled, and we were paying a needless (admittedly micro) performance penalty for passing the extra useless argument and useless condition check.
2023-10-19 12:52:24 +01:00
Dylan K. Taylor
3c614b505d
Merge branch 'stable' into minor-next 2023-10-16 21:28:59 +01:00
Dylan K. Taylor
538b698a00
Revert "World: specialize nearby entity updating for block updates"
This reverts commit 128eb500ebee5163583b84640a9c4f28c0218d42.

This breaks when entities in neighbouring chunks overlap into the
current chunk without actually being tracked by it.
Perhaps it might be worth having entities tracked by all chunks their
AABB touches in the future, so that we don't have to check padding
chunks and waste CPU time.
2023-10-14 19:43:46 +01:00
Dylan K. Taylor
128eb500eb
World: specialize nearby entity updating for block updates
this slashes the cost of checking this with no entities by 50%, which should be the common case for farms and such.
once factoring in other things, this translates into a real-world performance gain of about 15% for block updates.
2023-10-13 17:35:47 +01:00
Dylan K. Taylor
8f804f6f34
World: discard tiles on load if they aren't the correct type or no tile is expected
in many instances, remnants of improperly removed blocks from PM3 have been causing problems, such as flower pot tiles where there are no flower pots.

this change might break some plugins which are using tiles for custom purposes, but this is a misuse that was never supported properly in the first place.
2023-09-27 14:57:06 +01:00
Dylan K. Taylor
ae564e445d
Start migrating EnumTrait enums to PHP 8.1 native enums 2023-09-07 17:20:52 +01:00
Dylan K. Taylor
31d8cc1cb5
Generate and use constants for pocketmine.yml constant names
a couple of usages of properties that no longer exist couldn't be migrated.
in addition, this revealed a couple of dead properties in the default file.

this is not an ideal solution (I'd much rather model the configs using classes and map them) but in the absence of a good and reliable library to do that, this is the next best thing.
2023-08-25 13:23:38 +01:00
Dylan K. Taylor
f4d5605de1
Use hasHandlers() on more warm-hot events 2023-08-23 14:35:53 +01:00
Dylan K. Taylor
447f061566
Use Event::hasHandlers() for a few more hot events 2023-08-09 15:46:20 +01:00
Dylan K. Taylor
59c88fe7f7
Added WorldDifficultyChangeEvent 2023-08-09 12:22:03 +01:00
Dylan K. Taylor
9f14901820
Merge branch 'stable' into minor-next 2023-08-08 17:48:12 +01:00
Dylan K. Taylor
1cf508abdb
World: use Facing::OFFSET in getHighestAdjacentLight() 2023-08-03 16:51:09 +01:00
Dylan K. Taylor
6ac45526f9
Use new features in pocketmine/math 1.0.0 2023-08-03 16:46:16 +01:00
Dylan T
c91c8c2f9e
Improving performance of small moving entities (e.g. dropped items) (#5954)
* World: cache block AABBs directly in the world
this removes some indirection when fetching the AABBs, and also allows the AABB cache to live longer than the block cache.

In local testing this showed a 10-20% performance improvement, but it was difficult to properly measure.

* World: eliminate padding block checks in getCollisionBoxes()
this substantially improves the function's performance for small entities.

The padding of 1 block in each direction was previously necessary to account for blocks like fences, which might have an AABB larger than the cell containing them. However, by tracking this information in the collisionBoxCache directly, we can avoid the need to check this at the expense of slightly more complex code. This reduces the number of blocks checked for a moving item entity from 27-64 all the way down to 1-8, which is a major improvement.

Locally, this change allowed me to simulate 2100 item entities without lag, compared with 1500 on the previous commit.
2023-08-03 14:51:51 +01:00
jasonw_4331
1a2c10e844
World: Fixed getSafeSpawn() not accepting seed positions below y=1 (#5955)
this should have been changed during the introduction of y=-64 minimum world height, but it got missed.
2023-08-02 18:05:16 +01:00
Dylan K. Taylor
537721fe7d
Replace Closure::fromCallable() usages with first-class callables
PHP 8.1 <3
2023-07-19 13:34:42 +01:00
Dylan K. Taylor
8dedbb7471
World: clamp clickVector components from 0-1
this ensures that #5827 won't randomly start crashing if clients give bad values.
2023-06-21 16:59:14 +01:00
Dylan K. Taylor
a49842278a
WorldProvider subsystem no longer depends on Chunk
Instead, it provides the data needed to construct the chunk, which doesn't require the provider to be aware of anywhere near as much logic.
2023-05-29 17:44:00 +01:00
Dylan K. Taylor
ce5e663a73
Assume chunks are dirty by default
having them be clean by default makes no sense. It only makes sense for them to be clean if they were loaded directly from disk without any alterations.

Default clean is a footgun.
2023-05-29 17:22:39 +01:00