Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (775)
Games in Android Showcase (230)
games submitted by our members
Games in WIP (856)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [LibGDX] Entity Components - Should I read from file?  (Read 2811 times)
0 Members and 1 Guest are viewing this topic.
Offline Gibbo3771

JGO Kernel


Medals: 128
Projects: 5
Exp: 1 year


Currently inactive on forums :(


« Posted 2015-03-30 13:12:57 »

I am a little stumped on the best approach for this, I want to clean up my code a bit and move my entity components to an external file that is loaded in at runtime.

However I am a little unsure how to go about this, as I have never done any extensive I/O coding, I usually just write the code once and when I am happy with it, dump the entire thing to disk using Protobuf or Json and then read it in later.

I would like it to be somewhat readable though, so that if I want to make small changes (like balancing) down the road, I don't have to re-write it and redump it.

I am using the Ashley Entity Framework which is fairly lightweight, along with LibGDX and Box2D. I have it setup so that entities bodies and fixtures are not created until they are added to the Ashley engine, so there is no serializing of actual Box2D bodies; which is nice.

Serializing sprites is bad though, correct? So my option there would be to store the file path and instead grab it from the AssetManager after the entity has been loaded from disk.

Any ideas? Suggestions?, for the record, playable characters (of which there are currently 5) have between 15 and 20 different component combinations that make them unique.

The main idea here is to remove a lot of horrible code into a nice file that is readable and can be altered.

"This code works flawlessly first time and exactly how I wanted it"
Said no programmer ever
Offline junkdog
« Reply #1 - Posted 2015-03-30 13:56:48 »

You basically don't want to serialize components like Sprite, instead rely on having an AssetReference component or similar. I tend to divide my components into plain data and transient components. A transient component is basically a component which doesn't readilylend itself  to de/serialization. You have to construct those from plain data components, in the case of saving/loading.

Some more info here, though managers are specific to artemis, I'm sure something similar can be used for Ashley too: https://github.com/junkdog/artemis-odb/issues/128#issuecomment-52243456

As for save format, json is pretty convenient although it can be verbose unless you take steps optimize it.

Edit: example AssetReference component.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
public final class AssetReference extends Component {
    public String atlas;
    public String frame;
    public boolean animated;
    public float duration;

    public AssetReference(String atlas, String frame) {
        set(atlas, frame);
    }

    public void set(String atlas, String frame) {
        this.atlas = atlas;
        this.frame = frame;
    }
}



artemis-odb: bugfixing and performance optimized fork of artemis ECS
Offline Gibbo3771

JGO Kernel


Medals: 128
Projects: 5
Exp: 1 year


Currently inactive on forums :(


« Reply #2 - Posted 2015-03-30 15:52:11 »

Very nice information here.

Do you recommend serializing components using json, then add them to the entity rather than serializing the entire entity with the components?

The first one seems cleaner, as a serialized character at the moment has literally over 1000 lines in the json file.

However, I don't want to have to read the data in every time I spawn a new character or object, as this will make it slow.

For reference, this is what a basic character looks like:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
   private static Entity createHaldor(Vector2 position) {
      Entity e = new Entity();
      PhysicsComponent physicsComponent = new PhysicsComponent(
            BodyType.DynamicBody, true, 2);
      DrawableComponent drawableComponent = new DrawableComponent(new Sprite(
            VRD.ASSETS.get("sprites/01/jump.png",
                  Texture.class)), DepthBuffers.VD);
      SizeComponent sizeComponent = new SizeComponent(1.5f,
            MathHelper.getRatioY(1.5f, drawableComponent.getSprite()
                  .getWidth(), drawableComponent.getSprite().getHeight()));
      MotorComponent motorComponent = new MotorComponent();
      AnimationComponent a = new AnimationComponent();
      LabelComponent labelComponent = new LabelComponent();
      ContactComponent contactComponent = new ContactComponent();
      GroundColliderComponent groundColliderComponent = new GroundColliderComponent();
      DirectionComponent directionComponent = new DirectionComponent();
      AirborneStateComponent airborneComponent = new AirborneStateComponent();

      groundColliderComponent.transform.setPosition(new Vector2(0, -.6f));
      groundColliderComponent.transform.setParent(physicsComponent.transform);
      groundColliderComponent.width = 0.35f;
      groundColliderComponent.height = 0.25f;

      labelComponent.name = "Haldor";
      labelComponent.internalName = "haldor";
      a.current = AnimationCache.getAnimation(labelComponent.internalName,
            "jump");
      motorComponent.maxSpeed = 4f;
      motorComponent.accelerationRateX = 25f;
      PolygonShape poly = new PolygonShape();
      poly.setAsBox(0.75f / 2, 1.5f / 2);
      CircleShape circle = new CircleShape();
      circle.setRadius(0.375f);
      circle.setPosition(new Vector2(0, -.375f));
      physicsComponent.addNewFixtureDef(FixtureData.BUILDER.name("foot")
            .density(0.25f).restitution(0f).friction(0f).shape(circle)
            .dataToSet(contactComponent).build());
      circle = new CircleShape();
      circle.setRadius(0.365f);
      circle.setPosition(new Vector2(0, .375f));
      physicsComponent.addNewFixtureDef(FixtureData.BUILDER.name("head")
            .density(0.25f).restitution(0f).friction(0f).shape(circle)
            .dataToSet(contactComponent).build());
      physicsComponent.transform.setPosition(position);
      drawableComponent.transform.setParent(physicsComponent.transform);
      drawableComponent.transform.setPosition(new Vector2(-sizeComponent
            .getWidth() / 2, -sizeComponent.getHeight() / 2));
      drawableComponent.transform.setAngleAxis(0, 0, 1, 0);
     
      e.add(sizeComponent).add(physicsComponent)
      .add(drawableComponent).add(motorComponent)
      .add(contactComponent).add(a).add(labelComponent)
      .add(directionComponent).add(groundColliderComponent).add(airborneComponent);
     
      return e;
   }


You can probably see why it might be beneficial to read the parameters from a file lol.

EDIT: I was considering using Lua, as this will allow me to have components configured in a script outside of the code base. I thought about this approach given the fact I won't be maintaining this project (or won't be the only one) in the long run.

"This code works flawlessly first time and exactly how I wanted it"
Said no programmer ever
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline junkdog
« Reply #3 - Posted 2015-04-10 14:30:01 »

Sorry for the late reply, I saw your reply late in the night, decided I'd attend it tomorrow - and "tomorrow" was several days ago.

You probably don't want to serialize the entire entity as this would include a lot of data tied to the engine. Json might be a little  verbose, but it's very easy to work with. I have some old artemis code lying around which reads entity definitions from json; it should be rather easy to adopt, as ashley and artemis have very similar API:s. Not the most efficient code, but it works.

artemis-odb: bugfixing and performance optimized fork of artemis ECS
Pages: [1]
  ignore  |  Print  
 
 

 
hadezbladez (27 views)
2018-11-16 13:46:03

hadezbladez (36 views)
2018-11-16 13:41:33

hadezbladez (19 views)
2018-11-16 13:35:35

hadezbladez (14 views)
2018-11-16 13:32:03

EgonOlsen (1890 views)
2018-06-10 19:43:48

EgonOlsen (1926 views)
2018-06-10 19:43:44

EgonOlsen (1283 views)
2018-06-10 19:43:20

DesertCoockie (1711 views)
2018-05-13 18:23:11

nelsongames (1400 views)
2018-04-24 18:15:36

nelsongames (2032 views)
2018-04-24 18:14:32
Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45

Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!