Consider alternatives to a browser-based client
dertseha opened this issue · 6 comments
Initial reactions to the browser-based client were mixed.
Primary concern was the long load times.
Think about alternatives (dedicated client) - if feasible.
A little bit of rubber-ducking here:
Iterating through the list of the languages I know, I have the following options:
- C++:
Even with C++11, it's tedious to write anything with this language. While there exists a wide array of UI libraries, the list of things missing is long before any actual editor functionality could be added. - JavaScript (or more general: the browser):
This is the current choice. Small code-base and quick results (Server responds with JSON, directly used in client without any schema). Mentioned downside: slow to load a 64x64 tile grid.
There was that node/chromium based offline client UI library, perhaps this stack is quicker?
I also did a prototype with elm, a functional language for the browser. A simple 64x64 tile map was quickly displayed, though, any update such as selecting a single tile caused long delays; A shadow-DOM isn't suitable if only one cell of 64x64 cells changes...
- Java
Could be a last-resort. Still tedious to get the whole chain running (REST API, serializing JSON objects...) - Go
My preferred language for this project because all the core libraries are written in Go. Could bypass the REST API.
Only downside: As of beginning of 2016, there is still no "somewhat" stable UI library with binary releases. See this curated list:
https://github.com/avelino/awesome-go#gui
The best contender so far is the library "UI", which had a recent redesign and a still fragile API - next to a flaky build system (as per issue list)
A different approach in Go could be to use a OpenGL based display (there is go-gl with glfw3 binding) - without any UI controls (as there is no OpenGL UI control library for Go). Only a text command interface with mouse for point & click.
Would people like that? I guess not.
Although, this gives me the idea of displaying the tile map in the browser using WebGL - or at least use 2D canvas to draw the stuff. This loses the nifty knockoutjs binding, yet this is exactly what causes the long load times. After all, the tile map is always rendered the same, there is no styling involved.
This is an interesting path. First I'll have to figure out if it is actually the DOM-generation part that is the slow thing (and not the barrage of changed knockout observables when loading a full map).
Doing a quick check, it is not the DOM generation of the 64x64 map, it is the huge list of knockout observables; I commented out the DOM part iterating through the tiles and the level still took long to load.
Thinking about it, perhaps not all tile properties need to be observables? Possibly only those used in the tile map; other properties, such as height and the like, are only used for the selection summary - that one could be reduced to trigger only through one observable.
PS: I forgot to add earlier: I find it funny to struggle with performance with that 64x64 map on today's GHz machines while there was an editor 22+ years ago running on DOS and probably 386 CPUs ;)
Removing some of the non-tile map related observables didn't help either. Too bad.
With the intention of creating a prototype painter in Java I tried to set up JDK &IDE on my development system. Apparently that doesn't work (my combination of system & IDE) and after 2+ hours I'm giving up on that path.
Too bad to be because of a tooling problem, first and foremost I want to be able to work properly.
I've come full circle and, since the proof-of-concept worked, I can now detail on the solution.
For the map display I chose to use OpenGL and refer to an old Go project of mine, which allowed cross-compilation of OpenGL stuff to both native and WebGL (!).
Meaning I can now program the client in Go again and use OpenGL for the display of map details (textures, objects, ...). Only for the data input, the client relies on a classic interface with controls. Thanks to a view-model abstraction, this data interface can then be specialized in HTML (using knockout.js, as before) or in the native application.
With the native compilation is also the drawback: There is still no "production ready" library for graphical user interfaces in Go. The only viable is https://github.com/andlabs/ui which is in early Alpha stage and requires the compilation of a native library as well.
So I made the weirdest hybrid one can imagine for the native build: An OpenGL window next to a console-text interface.
To avoid hand-crafting each input for each environment, I abstracted the view-model one further level and included the type of the input in the view-model as well. That way only the view-model is extended with an entry of a limited set of choices - and the view only provides the corresponding control.
The fun part: Thanks to the strict view-separation, any view is now possible, even a future, native graphical view.
Oh, and about the main issue that started it all: Performance is amazing. The browser build is a bit slower than the native build - though only noticeable on my weak development system. It takes only a few seconds to load (and switch) a level.
And as further bonuses because of the OpenGL approach: Zooming was easily done and it was very easy to add palette animation as well.
I also prepared the client to have a direct data interface as well, so it doesn't have to go through a server.
Now, after adding (nearly) all functions of the old JavaScript client, I both like and dislike the control interface.
The OpenGL based interface is great though - performance and capabilities are useful.
As for the control interface, it's great to be able to define various properties in the code and they are available immediately in both client versions (native and browser). And on the other hand, this uniform interface is also a pain to use. The browser interface is now downgraded to the capabilities the text interface, which is already only a cludge.
More and more I believe the only option is the one I (also) wanted to avoid: move the whole interaction into OpenGL. Though I still want to strictly avoid building some UI library (lists, buttons, text fields). I'd much more appreciate a fully integrated solution, with keyboard shortcuts and mouse interaction (radial menu?). Text only to a minimum where necessary.
But before revamping the interface again, I'd first want to figure out what properties there may be - i.e., continue on the actual hacking of resource files again.
Either way, the initial concerns are adressed: Levels load within a few seconds, and there's an alternative to a browser client now.