WIP brain API#6968
Conversation
private final MemoryKey<Boolean> IS_SCARED = Bukkit.createMemoryKey(NamespacedKey.fromString("scared", this), Boolean.class);
private final SensorKey SCARIES_SENSOR = Bukkit.createSensorKey(NamespacedKey.fromString("scary_mobs_finder", this));
private final ActivityKey SCARED_ACTIVITY = Bukkit.createActivityKey(NamespacedKey.fromString("scared", this));I updated how custom keys are created. This allowed me to get rid of the maps, and instead just do some instance checking in the utility classes (which have now been merged as well). |
e0e0411 to
652bd16
Compare
|
I have included a new example that further shows what this system can use and have documented most of the api. Opinions appreciated. :) |
cef7a46 to
ae6f04d
Compare
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
|
This will be a really nice API, I have a team which makes a "Vanilla with additions" server, so we develop our own APIs and libraries for "mod-like" development with plugins, we do many NMS hacks to reach "modded" experience for players, obviously making hacks is bad, I tried to make something like "Brain API" via VarHandles and reflection, but it looked very dirty, and probably the performance in this case would be very poor. so as a plugin developer I need fast and minimally hacky API for interacting with entity AI. I plan contribute in this WIP API, because I think that it will be useful for other people like me. |
|
Hello everyone, I did some refactor of this draft API. (Owen knows about it) This refactor is about making better backward compatibility with Bukkit MemoryKey API, cleaner implementation and better maintainability of Brain API. I tested it, but anyway it can contain some bugs. Feel free to give a feedback about this refactor! API changes:
Impl details:
public static PaperMemoryModuleType<?> toPaper(net.minecraft.world.entity.ai.memory.MemoryModuleType<?> nms) {
// custom types actually register in NMS Registry, that's why we are getting them from it.
final PaperMemoryModuleType<?> customMemoryType = (PaperMemoryModuleType<?>) PaperMemoryManager.INSTANCE.getTypeByKey(CraftNamespacedKey.fromMinecraft(Registry.MEMORY_MODULE_TYPE.getKey(nms)));
// Here we are getting Vanilla type (from cache) if custom type doesn't exist.
return customMemoryType == null ? PaperMemoryModuleType.of(CraftMemoryKey.toMemoryKey(nms)) : customMemoryType;
}It is the main method which makes possible refactoring of everything else. And the third is Code examples.This is how this API public static final MemoryModuleType<List<Squid>> SQUID_CANDIDATES = Bukkit.createMemoryModuleType(NamespacedKey.fromString("squid_candidates"));
public static final MemoryModuleType<List<Parrot>> NEARBY_PARROTS = Bukkit.createMemoryModuleType(NamespacedKey.fromString("nearby_parrots"));
public static final MemoryModuleType<Location> MEETING_POINT = Bukkit.createMemoryModuleType(MemoryKey.MEETING_POINT);This is how to manipulate with memory in this refactor: // Obtaining MemoryManager from BrainManager
MemoryManager memoryManager = Bukkit.getBrainManager().getMemoryManager();
// Getting memory value of given entity.
List<Squid> squids = memoryManager.getMemory(entity, TestPlugin.SQUID_CANDIDATES).orElse(new ArrayList<>());
if (target == null || target.isDead()) {
if (squids.isEmpty()) {
// Erasing it.
memoryManager.eraseMemory(entity, TestPlugin.SQUID_CANDIDATES);
memoryManager.eraseMemory(entity, TestPlugin.SQUID_RAGE);
return;
}
target = squids.remove(0);
} else {
entity.getPathfinder().moveTo(target);
}Afterword.As Owen said: "ALL FEEDBACK WELCOME!", I wanna see Opinions about this refactor, especially about its maintainability, and impl. |
|
Responding to @ExtraExtremeERA
|
Regarding this point, I would defo like your opinion on this. The issue is that the type of the entity is required in some cases, and in the future when most likely more entities are moved over to use the brain system it will cause the generic to be tossed everywhere. See: https://canary.discord.com/channels/289587909051416579/925530366192779286/925667741984243723 Ping me in contrib tho and we can discuss more, cause i'd like more feedback. |
Machine-Maker
left a comment
There was a problem hiding this comment.
also a bunch of unneeded imports, line changes, stuff like that but those don't really matter right now.
| + Brain<?> brain = getBrain(livingEntity); | ||
| + | ||
| + if (memoryKey instanceof PaperMemory<V>) { | ||
| + brain.setMemoryWithExpiry(PaperBrainUtil.getHandle(memoryKey), value, expireIn); |
There was a problem hiding this comment.
setMemoryWithExpiry expects a non null value
There was a problem hiding this comment.
Hmm should I make a new expiry method instead that is not null then?
There was a problem hiding this comment.
Redis has a concept we could follow.
You can 1. set a non-null value and 2. set its expiry. When 0 it will directly expire. If possible I would not use a long in API instead a duration to make conversion easier and calculation a non issue.
Defining two constant durations is recommended as well.
Like EXPIRE_NOW (0) and REMOVE_EXPIRY (-1). Both as duration for sure.
|
Rebased to 1.19, redid the example, asking for feedback, you can now tick all entity brains, etc. |
| + */ | ||
| +public final class VanillaActivityKey implements ActivityKey { | ||
| + | ||
| + public static final Map<NamespacedKey, ActivityKey> ACTIVITY_KEYS = new HashMap<>(); |
There was a problem hiding this comment.
This field allow mutation for plugins which we don't really want here
|
Hey, would it be possible to add the BrainAPI for the camels? For example, that I can prevent the camels from lying down. |
|
oh, nvm, I deleted my previous comment, because I forgot that it is the goal of this API for some reason. The only thing it needs to support camels is a rebase to put a |
|
For it to be more properly integrated, this PR will need to be redone with all the new registry-related APIs. I am closing this as in general this will need to be rewritten, and don't have the time for that atm. |
This API is supposed to completely expose the "Brain" API that are used by certain entities such as goats, axolotls and villagers. However this api ALSO allows manually ticking brains of all entities.
This API is HEAVILY in WIP. I have created this pull request in order to collect as much feedback as I can here, so there is a lot of stuff like imports, access transformers, and paper comments I have to still do.
Some things I need help with:
I pushed a rough example in the test plugin, the pickled brain! See https://canary.discord.com/channels/289587909051416579/925530366192779286/989010753371652106 for the behavior.
ALL FEEDBACK WELCOME!
If you would like to use the brain debugger, use this fabric mod. This will allow the debugger to render.
enable-brain-debug-1.0-SNAPSHOT.zip