Hi everyone! I'm the developer of the Freeciv-web WebGL version. I'm very interested in hearing your feedback on this version, so I can improve it. I'm always interested in hearing what you think is the most important thing to improve in the game. (I'm so happy my side-project has reached the frontpage of HN again :)
It is using the Three.js 3D engine. Currently it works nicely on modern computers and laptops with decent 3D hardware, and there could be some issues on some mobile devices. For example, old iPhone devices have very poor 3D hardware.
I just fired it up on my VR machine, frame was good for short period I played it. Awesome work in converting it to 3D! Loved the water.
I did find the movement to be abrupt. So much so that I found it disconcerting to play. I would suggest a quick transition from one location to another for the units (maybe optional).
I don't know if this is a WebGL issue, a Mac issue, a Firefox issue (I use NoScript, but I've allowed scripts for the site and the rest of the game seems to work fine), or what, but I'm having absolutely no success in getting a middle click to do anything in the WebGL version of the game (like, say, show tile info). My mouse's middle click works fine in the 2D web version, but doesn't work here (nor does clicking right and left together). (Meanwhile, I have no idea what I'd do to get middle click info if I were just using the touchpad. Combining with cmd, ctrl, option, shift, etc. doesn't seem to do anything, apart from ctrl-click emulating a right click.) Am I the only one with this issue? Any thoughts on what might be going wrong?
If you have a recent enough mac you can make a two finger click he right click and then, with better touch tool, make a three finger click he middle click.
I tried this on a "netbook-like" HP laptop with 11" 1360x768 screen that I bought for $499 last year. The keyboard is compact so it doesn't have a numeric pad, not even with some sort of "Fn" shift. The number key directions didn't work. Arrow keys work but that fact is not in the manual, and there is no diagonal keys if you don't have 1,3,7,9.
On the other hand, the graphics worked fine. The blue line for the feedback part of the "Go" command was ugly. The laptop has no discre(et|te) graphics, just what comes in the mobile Pentium it runs on. So the warning about compatibility might be overly strong.
The vertical aspect of the mountains is tricky. It adds an unnecessary challenge to lining up a worker with a mine or what have you.
There are clearly some aspects that apply to both the WebGL and HTML5 versions, so I have tried to focus on the WebGL side in these remarks.
- I notice you are using Collada 3D model files inside of a zip file: https://play.freeciv.org/3d-models/models.zip It may be better to store the models in glTF format. It would be smaller and faster loading. Although to be honest, the last time I checked converting to glTF with high fidelity was very difficult to do.
- You should probably have cache forever on your game assets (3d models, textures, etc.) but have version numbers or hashes (my preference) associated with them -- it will load faster.
- Even if you do not switch to glTF, it might be better to have each Collada 3D model as a separate resource, so that as you change things it doesn't have to redownload the whole zip file.
- It is weird that you have *.zip file. You can likely just serve the collada assets using the built-in HTTP gzip encoding: https://en.wikipedia.org/wiki/HTTP_compression Thus it will be handled by a faster path in the browser than using a JS unzipper.
- You may want a proxy scene of boxes to raycast against. Hit testing my simple scene takes 5ms and I have a top end computer. Ray casting against THREE.BufferGeometry in Three.JS is just unreasonably slow. And THREE.Geometry is just slow all around, even though raycasting is a bit faster than with THREE.BufferGeometry. Another approach is to render the scene a second time to the offscreen with unique colors per object. Then hit testing is just figuring out which color was at the pixel under the cursor. This is highly scalable and is a very commonly used technique in games.
Rendering a scene to another buffer is a good way, although you do need some minor tricks to get information such as position and normal of the intersection, particularly so with high precision.
It's worth noting that this approach causes a very costly GPU/CPU sync when hit testing needs to be done and the scene has changed since last time (because glReadPixels() has to be called to pull in the data from VRAM to RAM). This is wasteful if the scene changes every frame, as you're essentially limiting the performance of your GPU to the performance of your CPU. Rendering to a smaller off-screen buffer (thus sacrificing precision) or calling glReadPixels() at most on each Nth frame and relying on temporal coherence to save you from the most unpleasant false positives and false negatives.
I've had good success, but you can often only read back a single pixel, rather than everything. I haven't profiled it recently. I understand that it can be fairly fast these days with PCIe buses.
Thanks for the feedback! I'll try using the glTF format. I'm putting the Collada files in a zip file to save CPU resources on the server, since compression on the HTTP layer would use more server CPU. Also compressing all the models in a single zip file results in overall less bandwith usage, and bandwidth is limited on our server. Do you have more ideas about improvements?
- You could also use Three.JS's binary format. It isn't half bad, especially served using HTTP compression. Blender can do conversions to it pretty well.
- You can use Canvas to draw to and then convert those to textures, that can make it easy to create very interesting pop-up information in the 3D scene. You could have the Canvas cleared to transparent and then write non-transparent stuff to it. Then you will have text and graphics floating in the air. Could look cool.
- Use the static serving of gzipped assets as discussed elsewhere.
- You should have hashes on your *.js files with caching for ever. This is pretty standard practice.
- Think about using the HDR stuff I contributing to Three.JS -- it can lead to amazing looking materials. Here is an example that uses IBL and HDR and tonemapping: https://threejs.org/examples/webgl_materials_envmaps_hdr.htm...https://threejs.org/examples/webgl_tonemapping.html Given that you are in daylight, I think this would work amazingly. Would look way better than simple lights. But it only works on Standard/Physical materials and not Phong materials.
I didn't look into too much more as I only looked at the production minified code.
Since the models are static content anyway, perhaps try a CDN. Since you're already using GitHub, perhaps https://rawgit.com/ would be useful (mostly because it's free) until you decide you want something with guaranteed uptime.
Collada is an XML-based format -- it is just brutally bad. You need to use a binary format for fast loading times. Thus binary glTF or binary Three.JS or something custom.
Just pounding this in even further because I see it so much: Collada, OBJ, STL and similar formats are expressly designed to be editor formats and expressly not intended as consumer distribution formats. Any time they are used they give the app and WebGL in general a reputation for being bloated and slow.
You wouldn't use PSDs in your webpage. You'd use PNG/JPG. Pleas don't use Collada in your web page. Please use glTF.
zip is not a solid archive. Each file in a zip is compressed independently without referencing data from other files, so zip files can't exploit redundancy between files for better compression.
tar.gz files compress the concatenation of all files, using redundancy between files to achieve better compression ratios.
Note that gzip and zip use deflate which has a small 32KB window, so if the repetition is more than 32KB apart it cannot be used for compression.
Interesting quote from this article (not to diminish the feat of a webgl version on classic screens, gg guys!) :
> Support for virtual reality using Google Cardboard is also under development.
Flying around a world and manipulating armies sounds awesome, kind of like "google earth VR meets strategy games". I guess freeciv will need game controller support first to make this playable, though.
Just tried it out and sharing my experiences. It is quite choppy for me, only getting a few frames per second, on 2K monitor, but I'm on a computer that will happily play Civ 6 on low quality. I wasn't expecting it to be fast, though.
Part of the issue is that the laptop has a 3K display (2880x1800) running in scaled mode (3840x2160). And that it has poor cooling and overheats/throttles down at the drop of a hat. And that it's a Mac.
That's somewhat disappointing, both in absolute terms as well as compared to your values. Although maybe it's being throttled at around 40fps which is probably beyond the point of diminishing returns?
Edit: Getting 35fps in Firefox, which seems to support the idea that it's being throttled somewhere around that value.
I suspect it may be more on the side of the game code than this since FF runs games that look much more advanced much faster. See their recent WebGL 2 demo.
FPS: 1.
Chrome Version 55.0.2883.87 m (64-bit) on Windows 10.
AMD A8-3850 APU with Radeon HD Graphics 2.90 GHz
16 GB ram
On Firefox 51, I get 2 FPS (although probably roundoff error).
Doesn't matter if I use low textures without anti-aliasing.
I should not the CPU usage for shoots way up. So most likely the WebGL is not utilizing the GPU. I should note that the GPU is integrated into the CPU chip as an "APU"...maybe this particular model of APU isn't supported by the WebGL.
This is not really possible at the moment. This 3D version is using WebGL in Javascript running as a web-application, while the downloadable binary is implemented in C.
So the C version can use the OpenGL C API. Three.js is a big abstraction layer on top of WebGL, but it's certainly in the realm of possibilities. There are C abstraction layers as well.
Electron apps can work great. I have noticed a general bias against all Electron apps and I think it is because of how poorly Atom performed when it was first released. Virtual Studio Code, and RStudio are shinning examples of a good Electron App.
I've run many other Electron apps - they all suffer from the same problems. Ugly non-native UI, DPI scaling that doesn't quite work right, poor platform integration and massive binaries.
Additionally, with something like this, I'd imagine it would be quite possible to port to a simple Node based system with OpenGL support without the need to embed a browser. Would probably improve performance too due to removed sandboxing.
There's a node-webgl package which provides all of the OpenGL ES features with no need for the web browser part, there's also SDL and GLFW bindings available. While it's not full OpenGL - I couldn't find any well maintained GL bindings at least - it should be completely sufficient to port a WebGL project.
I've searched a lot for such a package, most are five years old and doesn't work. Best I could find was the x11 package, but most examples doesn't work. And if you go with a wrapper you could as well use Electron or nw.js witch I'm using atm.
Is there a way to see it in action without starting a game? I don't want to end up with someone in a game with me I just plan to abandon since I only wanted to see it in motion.
It is using the Three.js 3D engine. Currently it works nicely on modern computers and laptops with decent 3D hardware, and there could be some issues on some mobile devices. For example, old iPhone devices have very poor 3D hardware.
This is an open source project, so we're always looking for developers to help improve the game: https://github.com/freeciv/freeciv-web/