Entity Tracker
A game debugger of a artemis-odb World state, working over the network. Artemis is an Entity Component Systems framework for games, written in Java.
The Entity Tracker consists of two things:
- the library that should be injected to a game - it tracks the ECS World
- the external UI displaying all the entities and components
Both communicate over TCP.
To read "what, why, what for?" explanations head over to my blog:
→ Artemis Entity Tracker - inspecting your game state through network
which is based on a previous (and much simpler) iteration of the Entity Tracker
Source code: https://github.com/Namek/artemis-odb-entity-tracker
Features
- View state of any component of any entity in the game, values updating in real time
- Modify state of components in real time
- Filter entities by specific component types and/or systems. Per-component filter modes: Include [+], Exclude [-], Doesn't Matter [ ]
- Toggle Systems and Managers
- Additional layout mode for a lot of component types (very wide entity list)
Feature Wishlist
- adding/removing entity components
- marking entities I want to track, getting noticed when they get destroyed
- searching for entities having certain values
- remembering component states on timeline for diffing those later
- pausing the world
- calling in-game procedures written by user and registered to the debugger
It has totally custom homemade Java serializer which deserializes into a Value Tree structure, similar to JSON but binary. It doesn't deserialize into original in-game types because the UI doesn't have them. Thus, the serializer on the Library side does not need any configuration besides injecting the EntityTracker object into the Artemis World. However, it keeps information about types of classes and fields so it's something more than JSON.
It's written in Kotlin. The library compiles to Java lib, the UI builds into a HTML + JavaScript.
The hard parts
- UI implementation is inspired by the elm-ui. Virtual DOM is a complete (JavaScript to Kotlin) rewrite of the snabbdom library. So I stole two libraries and joined those together with some additional bits on my side to track the changes of data.
- the entity list has a virtual scrolling which means it renders only the entities that are visible due to list scrolling. This was made with Canvas 2D instead of some DOM trickery. Thus, custom scrolling, spacing and so on. Not really easy in practice, a total surprise here.
- the Serializer brought challenges. Supports full recurrency, both in objects and types. I recommend reading the Serializing Java series on my blog to appreciate it.
The story of huge refactor
Originally, the interface was made with Java Swing.
Swing was buggy, took lots of time on every small change in layout design and the internals of the Java Swing seemed to create lots of memory garbage. I was somewhat OK with performance only for a small projects. However, I totally didn't felt OK with the speed of development. I wished for declarative UI. So I did few things:
- moved from Java to Kotlin
- refactored everything to kotlin-common which enabled me to build both JVM server and JavaScript client
- ported snabbdom (Virtual DOM library) and elm-ui to Kotlin and coupled them together.
This was a tough decision since it's no more possible to run UI within a game process. On the other hand, it felt very convenient when I had to only restart the game during development and debugger was already there, waiting in the background. So now everything is sent over network which was just an option before.
Now the speed of development seems not much better since we have a almost-declarative UI in an imperative language. The biggest drawback though, is the Kotlin to JavaScript compilation, it's just pretty slow as for Kotlin 1.3.50.