Suggested Prefab constructors

SoniEx2

New Member
There should be a way to invoke constructors from prefabs, so that component fields can be set to private (requiring the use of accessors instead).
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
That really kinda goes against the overall architecture if I understand that correctly.

It would be helpful if before submitting minimal suggestions/issues you could check out whichever area, figure out how it works, and understand why it works that way. If you still think there is a reason to make a change then write a summary of the related current logic, why it works that way, how come that is insufficient or wrong in some sense, and how it could be changed to a superior approach. Or even better: when you can have a prototype PR of the changes ready for review to help justify the change and get us at least part way there :)

In this case the whole point of Components is to contain data, accessed simply via public fields. Accessors added purely to allow private variables would only serve as some sort of access/security thing, which is likely handled better elsewhere (entity access within the ES itself? Marking certain Components as @Guarded somehow for gameplay reasons?). If alternatively the accessors are meant to allow addition of some sort of logic on setting/getting values then that is a huge architectural violation of the separation between Systems (logic) and Components (data). Especially considering that Components might change in the future to explicitly make sure they never contain actual code.
 

SoniEx2

New Member
In this case the whole point of allowing constructors is to add compatibility with languages that don't support public fields. Also are you saying Lists shouldn't be allowed in components, because they have methods with logic?
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
... what.

Honestly, I think you spend most your time looking for solutions to problems that do not exist. At least not in a meaningful way. Especially considering available resources.
 

oniatus

Member
Contributor
Architecture
Maybe I did not get the problem, but what is wrong with this?

Prefab
Code:
{
    "Tryout" : {
        "value" : 1
    }
}
Component
Code:
import org.terasology.entitySystem.Component;

public class TryoutComponent implements Component{

  private int value;

  public int getValue() {
  return value;
  }

  public void setValue(int value) {
  this.value = value;
  }
}
Instantiate:
Code:
        EntityRef test = entityManager.create("tryout");
        TryoutComponent component = test.getComponent(TryoutComponent.class);
        int value = component.getValue();
        //value == 1
private fields work for me in components, I never needed a constructor for prefabs.
If you need a constructor for components instead, you can provide a default one for the entity manager and a second one, taking the arguments you want.
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
IIRC the reflection magic is what's at work on private Component fields functioning.
 

SoniEx2

New Member
But where's the convenience of auto-generating a 1000-slot inventory? That's where a constructor would come in handy.
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
While I don't see a 1000-slot inventory as a particular likely gameplay element to encounter I do agree the current inventory sizing in a prefab is awkward. But there are probably simpler ways to switch that over to where there's an option to indicate number of slots with a single int, rather than needing to change any architecture.

Not saying there's no potential, nor am I against changes if justified, but I am not buying the line of argument in here just yet :)
 

oniatus

Member
Contributor
Architecture
The current inventory component could be a valid argument for a constructor invocation but probably the way the component is used is not optimal in the first place :)

The logic of expanding the inventory to internal slots is 'logic' which could go in a system rather than a component.

If you really need large inventories, you could write something like:
Code:
"SizedInventory": {
"width"=10,
"height"=100
}
or:
Code:
"CustomInventory": {
"slots"=1000
}
Assumed you implement the required components.
On startup, we can convert the marker components to a inventory with entity-refs, lists, tables, etc. in an internal component by the system.
This would also separate the internal representation from the declaration.

Side note: Just some fast thoughts by looking at InventoryComponent and the player.prefab in the Core module deltas. No need to do it now or do it exactly this way ;) maybe I missed some stuff which already exists somewhere.

To sum this up for the topic: I think it is possible to set all fields in a component without a constructor and the need of a constructor could also be a design smell, that a component does more than just holding data.
Still open for discussion if a simple for loop is too much logic for a component :geek:
 

SoniEx2

New Member
What about java.util.List types, which use all sorts of dynamic allocation and logic and stuff but are perfectly allowed in prefabs?
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
What about java.util.List types, which use all sorts of dynamic allocation and logic and stuff but are perfectly allowed in prefabs?
They're not part of the entity system. They are used by the entity system. Critical distinction.

You could stretch that metaphor to include complaints about the underlying OS not doing things the same way as the ES. That's fine. We're only concerned about typical Terasology gameplay systems built on top of the ES and its set of best practices.
 

oniatus

Member
Contributor
Architecture
IMHO, separating the declaration from the actual implementation is a powerful feature for the cost of being a bit more complicated.

Nevertheless: It is open souce. If you really need it, go on and submit a PR :thumbsup:
 
Top