#Discussion about code architecture
1 messages · Page 1 of 1 (latest)
What is the plugin about?
It's main purpose is to provide a easy and scalable way of managing and querying state in your game.
For this, the plugin has two main components.
The Memory and Properties System, and the Conditions System.
We'll discuss the Memory and Properties System.
This system is composed of three pieces.
- TJProperties
- TJMemories
- TJMemorySubsystem (Game Instance Subsystem)
TJProperties:
They are a UObject derived class, with the EditInLineNew and DefaultToInstanced specifiers.
They are intended to be used with the Instanced UPROPERTY.
They are mostly wrappers around simple data types, like a int, float, bool, etc.
The interesting thing is that they must notify (using a delegate that the base TJProperty class has) whenever their value changes.
The plugin comes with the common types already implemented (int, bool, float, string)
TJMemories:
A TJMemory is another UObject derived class, and has a custom editor.
They are simply a map of FNames and TJProperties.
It has utility methods to get a property, add, or remove.
They are basically a container with a fancy editor that provides custom debug functionality and a better interface to edit a map than the default unreal details.
TJMemoryManager:
It's a GameInstance Subsytem that manages memories.
It has a map of FNames and TJMemories.
It has utility methods to register, unregister and get memories.
The Idea is that users only need to create and expand the TJProperties, then create their memories however they see fit, and use the Memory Manager to easily access them when needed.
It's very useful to know when certain properties change, for example for UI, so the idea of this part of the plugin is to provide a easy and extendable way of accessing state with as few dependencies as possible.
is it typesafe? like can I accidentally get the wrong property type?
also maybe gameplay tags instead of names?
you might be able to use instanced structs to get around the overhead of using uobjects to store like 4 bytes too
are the properties owned by the subsystem or by whatever is using them?
The properties feel like a significant duplication of effort when we already have class members as properties and even blackboards as a bucket of properties.
I'm not sure why you'd need a parallel system like this, but it's hard to tell because the notion pages are incomplete and there's no code to look at.
This documentation would be better as the readme to source on github (or wherever, I don't know what your release plan is)
I've built conditions as instanced objects and it doesn't really need any additional scaffolding to work well.
they are owned by the memory they are in
it is typesafe, since they are UObjects, if you cast to an incorrect type, its a nullptr.
this is something that seems like quite a good idea!
The only thing is that UStructs can't have delegates in them, so you wouldn't be able to use a TJProperty as a standalone UPROPERTY() in a class and have it notify when it changes.
Is the overhead of UObject's really significant?
The idea of the Memories and Properties is to store state, and conditions indeed don't need them, but together they are quite powerful. There's a special kind of condition called TJPropertyCondition, that looks to see if it's true when the property it's watching changes, and notifies you if it is.
I think I understand what you mean by a duplication of effort, but I fail to see how already having class members as properties. Blackboards indeed are very similar to Memories. You think I could leverage them?
Why should I go through the extra step of creating a TJProperty_Int instead of just having a class member of type int?
Is it just for this system of callbacks when properties change?
It's not really a way that games respond to data changing, often times because you want to do things after some bulk of changes happen. Like all the effects from a weapon, not just the HP change.
It is indeed for the system of callbacks when properties change.
It's very true what you say that sometimes you only want to notify when some bulk of changes happen.
My first instinct would be that you can always derive from the base TJProperty, and decide exactly when to call it.
you can always derive from TJProperty, have any number of actual variables you want, and methods to modify them, and just Notify when you determine that it actually has changed.
Well, I look forward to seeing it in a released state with completed docs and maybe some examples.
Right now I can't see it as the solution to problems I've run into but it's very difficult to see that based on what you've currently posted and the available notion pages.
It is indeed difficult to see this without examples.
I will try to complete the documentation and have some video examples so you can see it in action.
I don't know if it came this way, but I'm not trying to be defensive or dismiss your doubts.
I really appreciate your time, and I'll post here as soon as the documentation is done!
You're not. And I don't want to come off as too much of a buzz-kill either.
You are not ahahaha!
hi! The documentation is far from finished, but I'd like your feedback in the last thing I've written, which is also one of the things I'm a little lost as to how to make better.
If you can read the TJConditions page, and then TJConditionValue, I would appreciate feedback!