TDWorld Development Thread

The flickering is from the exception I posted earlier:

java.lang.IllegalArgumentException: Comparison method violates its general contract!
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.badlogic.gdx.utils.TimSort.mergeHi(TimSort.java:791)
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.badlogic.gdx.utils.TimSort.mergeAt(TimSort.java:449)
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.badlogic.gdx.utils.TimSort.mergeCollapse(TimSort.java:387)
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.badlogic.gdx.utils.TimSort.doSort(TimSort.java:129)
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.badlogic.gdx.utils.Sort.sort(Sort.java:59)
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.badlogic.gdx.utils.Array.sort(Array.java:424)
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.badlogic.gdx.graphics.g3d.utils.DefaultRenderableSorter.sort(DefaultRenderableSorter.java:36)
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.badlogic.gdx.graphics.g3d.ModelBatch.flush(ModelBatch.java:198)
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.badlogic.gdx.graphics.g3d.ModelBatch.end(ModelBatch.java:218)
2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err:     at com.winricklabs.tdworld.TDWorld.render(TDWorld.java:184)

So trying to figure that out still… it only happens on a mobile device.

What are the contents of the array that you’re sorting? Try to check the compare implementation for the class which is in Array.

As you can see from the stack trace, it’s libgdx’s comparator:

2020-11-01 19:11:54.643 23782-24614/com.winricklabs.tdworld W/System.err: at com.badlogic.gdx.graphics.g3d.utils.DefaultRenderableSorter.sort(DefaultRenderableSorter.java:36)

It usually results in this after a bit :frowning:

Yes, true. But that exception seems to be happening because the objects it is trying to belonged to a class which didn’t respect the comparator laws. Try to check that place too.

If that is the message, I guess you’re trying to sort an Array<Renderable> probably? I’m not familiar with LibGDX, but this seems to be the cause to me.

I’m not explicitly calling sort anywhere. LibGDX does that. I am just adding model instances to model batches and rendering them. The classes being sorted are 100% owned by LibGDX.

I’m going to try my own comparator with a version of TimSort that logs a warning instead of throwing an exception. I think this is potentially a valid scenario for model batches that don’t have directly connecting meshes, but the default sorter doesn’t handle it elegantly and maybe the exception is screwing up the rendering pipeline.

As an experiment I replaced the default renderable sorter with my own, which is a copy of LibGDX’s except it uses a modified version of the TimSort class to not throw IllegalArgumentException. :stuck_out_tongue:

The flickering has gone away, but now after a while I get “com.badlogic.gdx.utils.GdxRuntimeException: No buffer allocated!” and the screen ends up like the above screenshot. I think that might be due to rendering objects already disposed, will debug this week.

Alright, well after making sure that once something is disposed it can’t be rendered I still ran into this. After some profiling and tweaking, I think it’s related to memory usage. Once memory usage gets high, I think some reference is being cleared that’s causing that exception.

Limiting the strategic view some and the number of tiles rendered at a time solves the problem.

I still see occasional flickering, no longer associated with any types of errors or lag, so I think it is GC related.

Going to work on some more features and testing iOS, will keep optimizing for the memory manager in the back of my mind, maybe I’ll think of something. I see it runs occasionally, pretty consistently cleaning up ~28mb. That’s probably all the dead creeps. I really didn’t want to build my own arena allocator for them, I was hoping the GC could deal with it. It may be that my objects are too big. I already use an arena allocator for the bullets.

We’ll see.

1 Like

Strategic view animations (did not know audio was recording sorry):

2 Likes

Implemented an animation queue (here’s a stack of animations, render them in order) and used that to smooth out the camera movement when rotating the phone. Will make a video later.

Smother camera movement:

Always wondered how G. Maps did it. Not sure if they implemented it the same way, but was fun to figure out.

1 Like

Lots of progress, want to make the next video once I can actually take buildings using the UI.
Right now trying to add labels above the buildings (always face camera, sized based on distance away, etc).

Adding the text was fun, because it required me to build a new async render queue alongside the synchronous one, since constructing the textures requires the main thread.

For some reason haven’t gotten them to face the camera reliably yet… I’m still a bit of a 3d graphics noob.

public void faceCamera(PerspectiveCamera perspectiveCamera) {
    ModelInstance modelInstance = modelInstances.get(0);

    Vector3 position = new Vector3();
    modelInstance.transform.getTranslation(position);
    modelInstance.transform.setTranslation(new Vector3(0, 0, 0));
    modelInstance.transform.setToRotation(Vector3.X, Vector3.X);

    Vector3 right = new Vector3().set(Vector3.Y).crs(perspectiveCamera.position).nor();
    Vector3 up = new Vector3().set(right).crs(perspectiveCamera.position).nor();
    modelInstance.transform.set(perspectiveCamera.position, up, right, position).rotate(Vector3.X, 180);
}

Ignore the extra object creation, just want the code to work before optimizing… :slight_smile:

The problems with this are:

  1. The models move, while they should only be rotated.
  2. The models are backwards :stuck_out_tongue:

Any ideas why they move around?

1 Like

More research: So basically this is called billboarding. Learning how to do that properly. I already have the text rendered into textures and placed on quads, just figuring out the matrix transformations.

Got billboarding working with Libgdx’s Decal class, which is an interesting adventure of TextureRegion, DecalBatch, and CameraGroupStrategy…

Anyway, now the issue is transparency. As in it doesn’t work, wonder why?

decal = Decal.newDecal(widthWorldSpace, heightWorldSpace, new TextureRegion(texture), true);
decal.setPosition(topCenter);
decal.setBlending(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
1 Like

Turns out the shader for decals is defined in the group strategy class, CameraGroupStrategy. Not sure why that is yet, I think that needs more thought. But anyway, to make transparency work with Decal you need to fix the shader, so I created my own group strategy class.

	String fragmentShader = "#ifdef GL_ES\n" //
		+ "precision mediump float;\n" //
		+ "#endif\n" //
		+ "varying vec4 v_color;\n" //
		+ "varying vec2 v_texCoords;\n" //
		+ "uniform sampler2D u_texture;\n" //
		+ "void main()\n"//
		+ "{\n" //
		+ "   vec4 texel = v_color * texture2D(u_texture, v_texCoords);\n" //
		+ "   if(texel.a == 0)\n" //
		+ "      discard;\n" //
		+ "   gl_FragColor = texel;\n" //
		+ "}";

Now I have transparency.

Building labels, in all their rotating, scaling, transparent glory:

Looks terrible. Most likely abandoning this feature, and will have road labels instead. Maybe it will be a feature you can turn on.

Going to disable it for now since it makes the game look bad.

Tomorrow starting work on the tower selection UI so you can actually link towers - the building name will appear there anyway.

1 Like

First mockup for the building selection UI (when building is Neutral)

4 Likes

Update - been doing lots of account related things, namely user registration & authentication in the backend/client. The goal is to really get people interested as soon as they see the first UI, so the registration/UI screens have the actual game world playing behind them.

1 Like

What if I told you I had a UI system that allowed you to focus/scroll to inputs with the native system’s keyboard? :slight_smile:

Also, this is the login UI so far.

1 Like

Registration (+ picking faction and v1 of faction icons), logging in, logging out, session management (storing temporary cookie on device and validating/expiring on server) is done - including all error handling/validation. We even detect if it’s a returning user on the device or if it’s the first time their logging in and default to either the login or registration UI.

The faction icons I made are kinda funny. I’ll be trying to find someone with talent in that area to make them and other art for the game.

Immediate items up next:

  • Registration/Login UI - support scrolling to input when keyboard opened - I broke this when switching to default ScrollPane.
  • Send email confirmation email/verify account.
  • Cross platform bugfixes with authentication flows (uis are gigantic on my desktop)
  • HUD to indicate when connected/not connected to server
  • Registration UI - lore/faction details

There are other things on the mind too, like when you click a building the building selection UI opens immediately. I think there should be some kind of animation on the building first, which will make it feel satisfying. Oh, and I have to finish that darn building selection UI which should be easier now that I have better understanding of Scene2D.

The rest of this week will mostly be working on FastComments as there are a lot of customer requests there, I’m currently working on this on Sundays…

1 Like