Jump to content

Advice on project setup and workflow. (framework, tools, libraries etc)


Rojoss
 Share

Recommended Posts

Hey everyone, I'm one of the developers of Curve Fever which is a multiplayer snake game.
Due to a complete redesign and performance/loading issues we plan to remake the game with HTML5 canvas.

We've already done a little bit of research but I'm already noticing there are hundreds of options for everything.
Reading through each option would first of all take a lot of time and secondly it's always advertised better than it is and it leaves out the downsides.
I'm looking for some general advice and some advice on frameworks and tools to use.
I have a few concerns and requirements listed below along with the information about our current project/setup.

About the project
The current game is made in Unity and exported to WebGL.
However, 20% of the users are unable to load the game and 25% of the users that can load the game has FPS below 40.
This is too high and we've had several talks with the developers that work on WebGL in Unity but they say that it's unlikely that it's gonna have massive improvements.
Totally understandable because Unity is a massive engine and WebGL is mostly used for demos and such and not full games.

Our game is a 2D topdown multiplayer snake game played by milions of users.
The servers are custom made with Go(lang) and the communication is done with websockets using Protobuf messages.
Most of the game is actually UI for things like chat, friends, shop, lobby, profile, popups and so on.

Requirements
These are the main requirements we have for our new setup.

  • Exportable for standalone (Windows, MacOS and Linux) - Preferably with generic API's for native things.
  • Exportable for Android and iOS - Preferably with generic API's for native things.
  • Exportable for web portals and Facebook.
  • Being able to run the game locally on Windows, MacOS & Linux.
  • Great workflow for quick development and design.
  • Structured code base (Typescript?)
  • Easy for designers to create UI elements and such.
  • Easy to create UI animations. (or animations in general)
  • Rapid prototyping.
  • Quick load times
  • Good performance on multiple devices.
  • Some kind of versioning would be great.
  • It's also quite important that it's open source.

Specific questions
Here are some specific questions we have currently.
We're mostly just looking for general advice on what to use and what not to use with the requirements we have.

  1. Is there something like Electron that also exports to mobile or do we have to use two services?
  2. Is it correct that it's best to create UI in the dom?
    If so, how well will it work with services that export the game?
  3. Since most of our game is UI would it be wiser to not use a game engine like Phaser?
    To give some more context, basically all we have to do in the game is render curves (lines) on the field.
    The curves will have to be erased too because of client side prediction (multiplayer networking).
  4. Is there something that lets us create UI elements easily with animations and such like it's done in Unity?
    I know that a lot can be done with HTML, CSS and JS but not all game designers may be experts with this and it'd be much easier if there was some sort of software where designers can design the game in.
  5. How good are the profilers/debuggers in the available engines?
    Or do people often only use the browser profiler/debugger?
  6. Just putting this here for people that only read these questions.
    What are some good practices and workflows.
    Would be great to hear what stack of tools and libraries etc people use and why.
Link to comment
Share on other sites

Hi Rojoss,

I believe most of Unity's WebGL games don't work well is because they use emscripten to compile C++ to asm.js and that might bring a lot of issues when dealing with cross browser support, specially if the browser is not optimized to handle it. For example Firefox runs asm.js programs pretty good but others don't.

I feel so far the best solution to have a robust UI cross browser is to implement it yourself using what every graphics API you choose to use (canvas or webgl). DOM based UI could display different in each browser around.

For rendering I would definitely recommend WebGL since it's widely supported and allows for faster rendering of polygons. Honestly I would recommend building the rendering backend yourself. It'll give better control of what you want it would be tailor made to your own needs, also WebGL is not that complicated to get you can easily build a canvas type of API that runs 20x faster than native canvas.

For debuggers, if you work with Chrome there is the DevTools which are pretty good and easy to use. Includes CPU and memory profilers. The newer version also include GPU profilers. Firefox have very similar tools too. If you choose to go with WebGL for rendering I would highly recommend using a plugin called WebGL Inspector. It gives a nice look into what gl calls are being made, how your vertex buffers look like, the gl state, etc.

Personally I try not to over complicate my self. Don't make simple task more difficult for yourself just because it uses the latest or the coolest library or design pattern. Keep it simple, clean and fast.

Regards,

Felipe

Link to comment
Share on other sites

55 minutes ago, Felipe said:

I believe most of Unity's WebGL games don't work well is because they use emscripten to compile C++ to asm.js and that might bring a lot of issues when dealing with cross browser support, specially if the browser is not optimized to handle it. For example Firefox runs asm.js programs pretty good but others don't.

Yeah that's the main reason most users are unable to load the game.
Firefox has much faster load times than for example Chrome.
We've pretty much already decided that we should step away from Unity if we want to make accessible games which is our main vision.

57 minutes ago, Felipe said:

For rendering I would definitely recommend WebGL since it's widely supported and allows for faster rendering of polygons. Honestly I would recommend building the rendering backend yourself. It'll give better control of what you want it would be tailor made to your own needs, also WebGL is not that complicated to get you can easily build a canvas type of API that runs 20x faster than native canvas.

I've read through some services that create mobile apps based on web applications/games but I've read a lot of things about slow WebGL rendering.
I think we should be using PixiJS for the rendering so that we can easily define which rendering method to use.
If you don't agree I'd like to hear why it's better to only target WebGL or use something different.

1 hour ago, Felipe said:

I feel so far the best solution to have a robust UI cross browser is to implement it yourself using what every graphics API you choose to use (canvas or webgl). DOM based UI could display different in each browser around.

Making everything yourself is always great but can also be really time consuming.
Since we basically just have to port the game with a new design and some changes it'd be much easier to just get started with existing tools and frameworks.

Based on the research I've done so far I think we can do with just PixiJS for the game itself with a few small libraries for audio and input handlers etc.
And then for the UI I'm still not sure.
Pretty much everywhere I read that it's better to put the UI outside of the canvas in the DOM.
I've also heard people say that most exporting services don't support DOM elements and only export canvas.
Since we'd like to have a downloadable version of the game and a mobile version it's quite important for us that this is possible.

For designers it must be really simple to setup UI views and elements.
Most of the UI won't be static and there will be many different screens/views.
For example a shop page, profile page, rankings page, lobby screen and so on.
Personally I think it'd be great to use a MVC pattern for this with something like Ember, Angular or whatever but I suppose this is gonna be hard to combine with the canvas and the code base would become a mess.

All the popular frameworks available use entity component systems and don't have UI functionality integrated.
So it doesn't make much sense to create the UI using those frameworks.
Unity also uses ECS but since Unity has a nice interface for designers it actually makes sense but we won't have the time to create a tool for our designers to create interfaces.

What do people think of combining a MVC pattern for the UI with a ECS system for the game engine/framwork?
And if it makes sense to do so what systems would be best to use, how would the communication go between the game engine and the UI framework?
For example if we write a very basic ECS game engine using PixiJS for the rendering, and then have something like AngularJS for the UI like all menus etc.

I'm sorry if I'm being too vague but there are so many possibilities and we'd like to get a good start and set everything up properly.

Link to comment
Share on other sites

4 hours ago, Rojoss said:

Is there something like Electron that also exports to mobile or do we have to use two services?

Cordova can target all platforms, see their support matrix. I've not heard of cordova targeting desktop though so no idea on performance, ease of use etc etc. Typically cordova plugins can be very hit and miss.

In theory you can create one codebase, have Electron build it for desktop and Cordova/Phonegap/etc build it for mobile and separate build for web, although in practise this would get a lot more difficult. It's tricky to build a generic enough interface to target all these platforms and you have to be careful how you deal with device capabilities, the absolute worse is to have a load of `if` clauses littered around your codebase that makes testing near impossible and continued development hard at best.

4 hours ago, Rojoss said:

Is it correct that it's best to create UI in the dom? If so, how well will it work with services that export the game?

Usually I'd agree, the DOM is good at UI elements (even though it wasn't designed for it, there are loads of good ways of doing this). Certainly canvas is poor at this sort of stuff and you end up coding up a load of stuff that the DOM gives you out of the box (layout, event handlers etc etc). There is no issue with interop between canvas elements and anything else.

Not sure what services you are talking about.

4 hours ago, Rojoss said:

Since most of our game is UI would it be wiser to not use a game engine like Phaser?

Possibly not, UI (I think) is easier in DOM, so you have to weigh up what Phaser gives you, it does a lot of other stuff like state management and input helpers etc etc and there's no reason it couldn't work with a DOM based UI as well.

5 hours ago, Rojoss said:

Is there something that lets us create UI elements easily with animations and such like it's done in Unity?

No idea for Phaser but there are numerous (very numerous!) web frameworks for handling this is DOM, given the need for this stuff I'd assume its a great deal more powerful than Unity UI elements (I know there are many issues with Unity, for example, I play a desktop Unity game and none of the UI handles retina at all, although other games do manage this so possible a version thing?).

Working with the DOM is a discipline in itself, I wouldn't expect a competent non-JS dev to just pick it up in a matter of hours but its also not too difficult that a bit of learning effort wouldn't pay off.

5 hours ago, Rojoss said:

How good are the profilers/debuggers in the available engines?

No idea, but browser profilers/debuggers are pretty good and debugging in a dynamic language is several orders easier than elsewhere. Having said that, JS is ridiculously permissive so you do need that crutch.

2 hours ago, Rojoss said:

What do people think of combining a MVC pattern for the UI with a ECS system for the game engine/framwork?

Personally I'm not a fan of straight MVC, particularly for UI. There has been a big shift over the last few years towards more functional approaches to UI work, its a bit of a paradigm shift, particularly if your background is with a classical language.

2 hours ago, Rojoss said:

For example if we write a very basic ECS game engine using PixiJS for the rendering, and then have something like AngularJS for the UI like all menus etc.

I've paired Pixi with React numerous times with very little issue. Generally comms are via some variant of Pub/Sub i.e. UI dispatches actions, listeners then decide what to do with those messages, messages are passed around as structured (but very simple) objects.

Link to comment
Share on other sites

7 minutes ago, mattstyles said:

...

Thanks for all the answers they'll be very helpful for us for deciding what to use.

10 minutes ago, mattstyles said:

Not sure what services you are talking about.

To export the game for different devices for example the one you mentioned. (Cordova)

 

12 minutes ago, mattstyles said:

I play a desktop Unity game and none of the UI handles retina at all, although other games do manage this so possible a version thing?)

We have build scripts that modify the build when it's completed to support retina.
It's really hacky but it works, we actually had a meeting with several Unity developers during GDC last week and they weren't aware this was an issue and will be putting it on the roadmap for the near future probably.

14 minutes ago, mattstyles said:

There has been a big shift over the last few years towards more functional approaches to UI work, its a bit of a paradigm shift, particularly if your background is with a classical language.

Could you maybe give me some names/examples/links of these more functional approaches?
I've never really made full JS web applications so my knowledge about these kind of topics is quite limiting.
Just a search term would be sufficient. :P

Link to comment
Share on other sites

3 hours ago, Rojoss said:

To export the game for different devices for example the one you mentioned. (Cordova)

Gotcha, yeah, no issues using DOM, DOM will be their primary concern. They all work by instantiating a webview (not sure for desktop, Electron just opens a webpage too using Chromium, presumably Cordova does the same) so they just load a webpage exactly the same way the browser does (there are some issues here, Android webviews aren't always guaranteed to be the version of Chrome running on the device, although up-to-date versions of Android do fix this, Crosswalk is an option here which I think has its own browser version, probably just ensuring a newer Chrome version), the only difference is that its a local resource rather than remote.

3 hours ago, Rojoss said:

Could you maybe give me some names/examples/links of these more functional approaches?

React has led the way on this, but there are many many React-likes and stuff like Vue, Angular 2 is a total rewrite of Angular and builds on the general developer excitement about building UIs this way. This is a sort overview on how React does stuff, but follow a quick 10 minute tutorial to get a better feel for it. React is just a view library, its literally just responsible for turning data in to views so there are a number of different ways to present that data to the view.

A good way to think about it is that you have one central state for the entire application, the UI is dumb and just creates actions, some business logic (often implemented as stores) then hear those actions, perform logic based on the action (and any meta passed with it), create a change to the state which is then pumped into the view layer to be re-rendered. So you think of it that any change to the state redraws the entire screen (not so different to how Pixi.Render would work) and its up to React to do this in a performant and reliable way, as a dev you don't really worry about it, just change the state and redraw. For UI this is fantastic, for many games this is fantastic but if you're really pushing the envelope graphically it can be slow.

There are some cool projects like React-pixi and regl that bring this philosophy to canvas and webgl, its a great methodology because React is only concerned with differences in a virtual tree (i.e. a virtual dom) so any renderer can be stuck on the end (React is primarily for the DOM, but it can also renders strings for the server to return, or native stuff—see React-native for mobile shizzle— or canvas as React-pixi shows and webgl instructions as regl shows).

There's a bit of learning curve to understand why it chooses its methodology and there can sometimes be a bit of a learning curve in learning the implementation, the mitigation here is that this is good stuff to learn even if you return (or stay) in a classical and/or MVC world i.e. whereas much you learn when learning Angular is domain specific there is less when learning React (i.e. if you learnt how React does its thing, then ditched it and used Vue, you'd just in immediately, if you learnt Angular and then ditched it for other frameworks you likely lose most of that learning).

Link to comment
Share on other sites

18 hours ago, mattstyles said:

React has led the way on this, but there are many many React-likes and stuff like Vue, Angular 2 is a total rewrite of Angular and builds on the general developer excitement about building UIs this way.

Thanks for the advice on React.
Never heard about it before but I've followed several tutorials and it seems really great and performing very well based on the benchmarks I've seen.

Currently the main concern I have is the routing part because it seems weird to have a history and changing URL for a game UI.
So when you navigate to your profile page or something it should just replace the view with the profile and not add it to the history and change the URL.
But I suppose I would have to write some kind of custom routing for this.

Another concern is that it's not very designer friendly because the html stuff is mixed with the logic/JS code.
I'm sure the designers will be able to get used to this though.
The state stuff is really awesome that it just updates the actual DOM automatically when the state is updates for specific elements.

Before your reply we did some research on handlebars and thought that would be great to do.
Especially because it'd be very easy for designers to create templates with handlebars.
React seems much better regarding performance though so we'll probably look into React more first.
We just have to figure out how we're gonna handle switching views and such.

Another thing I'm a little worried about is animations, particles and other stuff.
Since React will only render things in the dom that have changed will it work if we animate elements with javascript?
I read some stuff that you can set up CSS animations for begin/end etc but in some cases CSS animations might not be sufficient I assume.

Link to comment
Share on other sites

2 hours ago, Rojoss said:

Currently the main concern I have is the routing part because it seems weird to have a history and changing URL for a game UI.

There is no requirement to do this, React isn't bothered about url (solutions like React-Router deal with that side of things), so if you wanted to pop into a profile view then you could simply have something on the state object (say, a string named `appState`) and then in a top-level component you'd grab that string and render whatever component you want to associate with each `appState`, i.e. if `appState = 'profile'` then render then <Profile /> component with whatever properties that view needs to render itself. Solutions like React-Router handle only two things, this association between keys and the components to render and it ties in (optionally) with some sort of history mechanism (which can be in memory rather than connected to the actual browser history).

If you want to use the browser back button to change state to the previous state then you'll have to track current and previous states, and listen to the back button to deal with it (from memory I can't remember how exactly you do this, like for pop and push events on the browser History object possibly).

2 hours ago, Rojoss said:

Another concern is that it's not very designer friendly because the html stuff is mixed with the logic/JS code.

The WTF moment when people see stuff like HTML mingled in to JS is common, but its an easily remedied worry. In short, think of it like a templating language (such as handlebars that you mentioned) but with the power of a proper language i.e. JS, no custom logic unique to your templating logic, if you want to have a conditional in your template just use `if`, if you want loops then use `for` or iterate using Array.map or Array.forEach for example. It's superior in every way.

A good flow (if your designers can handle crafting HTML/CSS) is to have them produce static DOM, just copy-paste that straight in to a component render function at first (if you want) and then have a developer (could be the same person) work out how to extract the dynamic parts and deliver that data, additionally making any other optimisations or working with how you've tied things together. This gives you the speed of designers actually producing HTML but the safety of a dev (with domain knowledge) actually hooking stuff up.

2 hours ago, Rojoss said:

Since React will only render things in the dom that have changed will it work if we animate elements with javascript?

Yes, stuff that likes to manually have access to the DOM is clumsy (or just wont work) in a React world, although React does allow you a few mechanisms to 'reach' in to the DOM it creates which allows for complex JS animations. As you're hooking in Pixi (which needs a proper DOM element) you'll have to do this, I've done it on several different projects and its fairly easy to hook them up.

But have a look how many of those animations (maybe all of them?) can be done in CSS by manipulating classes. Again, if you dig around you'll find plenty of examples of both JS and CSS animations out there (there are numerous modules, look for transition-groups, or look at something like React-motion which provides a different way of thinking about animations).

Note that many of these libraries have ditched listening to transition events as they just aren't reliable, technically its better but after extensive research most agree that if you have an transition (or animation) that takes 1000ms just firing a setTimeout is better than listening for the transitionEnd event.

Link to comment
Share on other sites

8 hours ago, mattstyles said:

There is no requirement to do this, React isn't bothered about url (solutions like React-Router deal with that side of things), so if you wanted to pop into a profile view then you could simply have something on the state object (say, a string named `appState`) and then in a top-level component you'd grab that string and render whatever component you want to associate with each `appState`, i.e. if `appState = 'profile'` then render then <Profile /> component with whatever properties that view needs to render itself.

Yeah, that sounds great.

 

8 hours ago, mattstyles said:

Yes, stuff that likes to manually have access to the DOM is clumsy (or just wont work) in a React world, although React does allow you a few mechanisms to 'reach' in to the DOM it creates which allows for complex JS animations. As you're hooking in Pixi (which needs a proper DOM element) you'll have to do this, I've done it on several different projects and its fairly easy to hook them up.

Alrighty, I suppose we can do most with CSS animations but I'll look into it already saw some neat animations made that work with react.

---

Are you familiar with setting up a project with React and PixiJS?
I've spend all day trying to get the dev environment set up without any luck.
We think it'd be great to use Typescript which seems to make everything much harder when setting it up.
I've tried webpack, rollup and browserify but I can't get it working together smoothly.
Setting up either react or pixi works fine but combing them and still having hotloading working and being able to build etc is really tough.
Most of the tutorials and templates are really oudated and I can't get them to work anymore.

I saw you replied on a few other topics that mentioned Pixi and React together so I though maybe you know how to set this up properly.
Ideally we also seperate the code from the game and the interface.


This is what we have currently.
While it compiles and doesn't give errors and such it doesn't actually hotload, like it doesn't even compile the code when I make changes. (webpack still prints out a bunch of stuff when I change a file)
Hotloading also doesn't work and it doesn't even have typescript so it's far away from working perfectly.

Webpack config: https://gist.github.com/Rojoss/0c0fb0d67d29b87fca93c3177ee12bfd
Package json: https://gist.github.com/Rojoss/d9e89afb9cc261937dfa2c216d0071ce

Folder structure
> Project root
  > src
     index.html
     > game
        > js
     > interface
        > js

Link to comment
Share on other sites

https://github.com/mattstyles/react-pixi

Here you go, super simple barebones example of bootstrapping an app up with React and Pixi.

It's really simple, it uses `budo` to rapid setup a browserify environment, config for browserify is in `package.json`, ditto for babel which does the transpilation stuff. Browserify is a really neat solution, where webpack is mega complex to do really simple stuff, browserify tends to be fairly simple to do some really complex stuff! As you're probably aware babel runs the transforms as I'm using some ES6 stuff, if you're using a modern browser though only 2 things (I think) actually require transpilation, which is the JSX syntax used by react to scaffold the views and object spread (which you might not want to use). I haven't added TS (I'm majorly not a fan, but thats a different discussion1) but to do so you'd just add a transform to browserify (tsify works) and you're all done.

`budo` scaffolds an index.html page for you (a blank one, hence `element.js` in there adds a root element to the page), its also running live-reload by default, although doesnt show hot-reloading (which wont really work with Pixi anyway). The app entry point is `index.js`, which just renders some DOM, sets up a stateful component to house the canvas element and bootstraps Pixi when that component mounts. This is the absolute simplest way to get started with React but not particularly scalable, however, its fairly easy (once you get going) to extend this base outwards to make a functioning app. I've used an event emitter to add pub/sub for the UI to talk to the Pixi components, but, again, you have numerous options here. Note that in this basic example React stuff and Pixi stuff is pretty separate, tying it up together in a nice way isn't quite so easy, but, depending on exactly what you want to do you might not really need to, the advantage of keeping them separate is that you call Pixi in the manner it was designed to be used and you don't add any overhead from stuff like traversing virtual dom or any stuff that libs like flux or redux do to route data through an app.

This was all done super hastily but hopefully you can get it going. Note the readme states to use `yarn`, you can swap this out for `npm` with no issues.

Give me a shout if anything needs clarification, I haven't used Pixi for a good while so it was good to check out how it has changed!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...