• Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by mattstyles

  1. Welcome to the forums @MrRitzy This sounds like great fun, but, yes, you are correct, it is quite complicated. But, I do not want to discourage you! Nothing worthwhile was ever trivial, so great cracking on it! You're going to need some javascript to make this all tick, so you'll have to make sure you have some skills there. Once you have some JS skills (sounds like you probably already have at least some, maybe you're already very good) you're going to need to work out how to persist some data. As its idle people are going to leave the tab/browser hosting your page/s, so you're going to have to track where they were and when so that you can drop back in to the gameplay when the user returns. Local storage will probably get you where you need to go for this, so learn how to use that. If you need more than that then you'll have to get in to some sort of backend solution to store data, this is considerably harder but you may well enjoy that challenge too. Sounds like you have made a real conscious effort to reduce your scope, great work! Keep it small, get it working. Once its working, keep building on it! And very good luck to you with this project! The community here is very active and very knowledgable, whenever you hit a roadblock keep posting here (and other places too, we're not the only oasis) and asking questions. Then, as you skill up, make sure you answer questions from others and help them to learn and grow too Good luck
  2. Rightly or wrongly, most JS applications now use a build system of some sort, which means they have access to a module system, which means that they can understand `require` (which is CommonJS format, as used by Node, to complicate things, there is now ES6 module spec as well, using `import` and `export` syntax, mostly, build systems will understand both, mostly). As most JS apps use a build system this means that most JS libraries (such as found on npm, which is *not* just for node, its for JS, which includes node and client and IOT and and and etc etc etc) now _expect_ that build system and the module system that it allows. However, many many JS libraries also expose a client-only version of their library for those who do not want to use a build system. Even if you are building an entirely client-side application I would still advise setting up a build tool chain. Some disadvantages of a build chain: * Can be tricky to set up * Still not quite as simple as just running code in the browser Some advantages: * Many cross-browser issues disappear due to transpilation * You get access to a module system, helping you to organise your code base * Due to module system you get easier access to external libraries by using a service such as npm to access that code (i.e. you no longer have to reinvent the wheel and it is considerably safer than other methods of accessing third-party code) If you did want to go down the route of using a build system I think the following steps would get you there, usually without too much trouble, but, it might involve quite a lot of learning depending on how experienced you are: * Install node on your local machine, this side-installs npm, the node package manager. * Install a command line on your machine (if it does not already have it) and spend a few hours understanding how to use it. * Create a new folder for your new project. * From the command line run `npm init`, this sets up a new project. * From the command line run `npm install -g parcel-bundler` * Create an `index.html` file and put whatever you like in there * From the command line run `parcel index.html` At this point 1 of 2 things will happen: 1) You will have port access issues on _some_ systems. Resolution to this depends on your machine, google the solution, there will be lots of solutions. 2) You local server will fire up and will serve your index.html. If you run in to point 1, fix it, and you will be at point 2. This is good. Now cancel that running script (usually ctrl-C/cmd-C from the command line). From the command line run `parcel watch index.html`. Now you have a development build running. Change the code within index.html, switch back to your browser tab, see those changes instantly propagated in the browser _without_ a page refresh. It is magic. Beyond installing node (and npm), these steps are outlined in more detail at Parcel is one of many bundlers you may use, but it is the easiest to get going with (and very good I might add, but you have choices if you don't like it). Note that none of this is non-trivial, and its up to you if you think the advantages (which I have barely touched on) outweigh the initial cost of setup. Also note that this isn't necessarily the 'best' way to get started, I'd advise some changes, but, you can do those later. This is likely the easiest way to get going with build tooling for JS.
  3. mattstyles

    Game Data

    The answer depends on your use-case. Local storage is a great option for many use-cases. Some use-cases where it definitely is not a good solution: * Users playing from multiple devices/browsers (local storage lives in one browser and can not be shared) * Local storage, in theory, can be nuked at any time by the browser (I've never seen or heard of it happening, but, browsers make no guarantees)
  4. mattstyles

    Game Data

    What's wrong with your current system? If you answer that then you'll know what you need in a _better_ system. Without knowing an answer to the above then you're just mucking around. The options for storage that you have are reasonably limited. You can use an in-browser database (modern browsers all support indexeddb, edge will soon add it for v2, websql isn't completely supported), or send your game state off to a remote server to store how you like. None of these are better or worse than local storage, they're just different methods and what works _best_ for you is dependent on your use case.
  5. This is a really tricky question for a generic answer as there are so many variables which _could_ dictate whether your project structure works well or not so well. Personally, I'd take any answers with a pinch of salt i.e. there is no single 'best' structure, like, not at all. Have a think about what the problems you are trying to solve are and how the processes and concepts you employ for organisation are going to solve that problem? To the above question, the answer is usually 'I do not know'. This is fine. With the above in mind it is usually better to follow this sort of process: Start the project. Put stuff anywhere, it does not matter at this stage. Get something working. Keep going. Now you have a working product and you can start to identify what organisational problems you have and think about how to solve them. Until this point you are largely guessing. If you have created several similar projects before your guesses are probably good, if not, then they might not be. It is relatively easy to apply some structure and organisation to a project that doesn't really have one, it can be pretty tricky to change organisational structure (can be, depends on many things again, you certainly should not be afraid to change later on if your current system turns out to be not very efficient). There are some rules of thumb that might help you though: Small files and folders are easier to manage than larger ones i.e. small in scope, not necessarily small in lines of code. Decouple things as much as possible, this makes them easier to work with, and makes organisation easier to change. Tight coupling is a nightmare, avoid at all costs. Uber objects (and, similarly, uber-projects) are hard to manage, this is really the above concern worded differently. Divide and conquer. UI and logic (rendering and smarts) are good things to separate. Avoid logic duplication, if you end up writing similar logic in multiple places, consider generalising and abstracting it. Utility functions can form a huge part of your codebase and is _usually_ a sign of good organisation. MVC is fine for games. As are other methodologies. Go with what you think makes most sense for you (and your team) and the project.
  6. Not a stupid question! This is the web and JS so there are, of course, multiple ways of skinning this cat. here is one way I knocked up. Its a canvas element on the page, with the spinner element also in the DOM. The order of the DOM dictates rendering order, but you could apply z-index via CSS if your DOM structure was different. The CSS is copy-pasted from after a brief google search for CSS spinners, there must be several thousand of these such sites. I've used a couple of set timeouts, down the bottom of the JS file, to control the loading spinner. After a set amount of time I've applied a class to fade it out, then, using a different timeout I've removed it from the DOM. You don't need the fade if you don't want it. You could also use element handlers to get an event when the fade has finished, but, they're unreliable cross-browser and it's easier to just know the length of the transition and use a timeout to deal with the next action you want (in this case, remove the element). Hope that helps.
  7. Have a look at Pixi, it just helps manage drawing to the canvas really quickly. Usage inside React is non-trivial, but there is plenty of help out there. You might find Inler's React-Pixi module helpful, it doesn't officially support v5 of Pixi yet but I've been using it (so far) without issue. You have choices here, try searching npm/github for react-pixi and you'll come across a few implementations. If you really like getting your hands dirty there are a few projects like regl that are fun. Probably not quite what you're after though. You could just go the route of having an uncontrolled React component with the canvas renderer inside, again, try searching if you need help working this out. It's been done and written about a number of times for a few different front-end rendering libraries and with a few different canvas rendering libs. There are options other than Pixi too, try searching for canvas rendering libs. It's fun to play with the canvas API but it's quicker to let someone else create a wrapper around it, i.e. Pixi etc.
  8. Hey @bluewales, welcome to the forums! Demo looks great! Sounds like an awful lot of triangles for that small area, but, very nice looking and was a solid 60fps on my machine (which has a terrible GPU). You've done absolutely the right thing, by reducing your use-case to a POC of the bit you want to test. Yes, trying with some different library choices _can_ sometimes be a good plan, but, it can also be time consuming. Three.js is incredibly well supported and used, try looking for demos or experiments that also are close to your requirements. If you find a couple of demos that are similar to what you want to do and work well, then you have to look at how you can optimise to achieve the same performance. Think of it this way: if you have just picked up Three.js, it is a complex library, you can't expect to know exactly how to use it right off the bat. Now you want to test babylon.js, and you don't know that intimately either, so, POC's are tricky when testing performance, have a look also at some reduced use-cases. For any of these renderers there will be frustrum culling and raw number of triangles demos/tests that you can use to get a gauge on whether things are even possible. An example of an optimisation: You may not need the curved corner geometry for anything other than pretty visuals, you can round/curve corners via a shader and have square corners, if you find that the number of triangles is prohibitive with curved corners then cheat. The browser has one advantage over other platforms, debugging is incredibly easy with the browser and JS. Use the tools, find where any bottlenecks are, this will help you identify if there is an underlying issue or just a library/tech choice one. Bare in mind that the browser has the same access to the GPU as any other application (albeit with a slightly older language spec) so any bottleneck may very well be JS, which is _usually_ slower than other languages that you might use (outside of the browser, you have no choice in the browser).
  9. I try to adapt to the size of the screen, rather than pick arbitrary screen dimensions to lock at.
  10. Start googling. There are so many resources for beginners out there for free, you'll have more problems wading through poor content than you will finding what you want when you're starting out. Beyond that, there are also many paid resources. Things like Udemy, Pluralsight,, all offer paid courses, both written and video content. Then there are things like Treehouse that offer dedicated courses. Further still, there are bite-sized learning opportunities like Codecademy, Code Wars, Codingame, etc etc that let you learn in smaller chunks, these are great supplements to more dedicated learning, and range from free to a small fee. To start though, I'd get googling. Use Stack Overflow to help find answers to specific things, and start to identify some thought leaders in the community you like and find their blogs and twitter feeds. I do not know who these people are for Python, but there will be many of excellent gals and guys out there talking about Python and programming. If you like roguelike gaming then there is a nice Python tutorial at Python is well used and very well liked amongst Roguelike devs. Creating a full blown game of the complexity of your average roguelike is a fairly daunting place to start, but, maybe if you like that sort of thing then it'll keep your attention and I'm sure you'd learn a lot.
  11. I still don't understand. Correct, this is made possible by browsers and hardware manufacturers. Not Unity. Unity is just one method of creating content for that platform and it is far from the most popular way of creating content. Maybe it'll 'take over' in the future, I doubt it, but maybe it will, but you can't say that right now. Unity is incredibly inefficient and clunky on the web, still. It provides tooling that, for some people, lets them create content faster. Think of it this way, a Fiat 500 is going to be built a lot faster than a Ferrari is, and, it'll get you to the shops and to work and back without any issue at all, but, most of us would 'prefer' to go on a fun drive in the Ferrari.
  12. How so? Nothing in saying that webgl is almost universally supported implies that Unity is the platform for creating web games. There is a saying, never bet against JS.
  13. Why are you worried about webGL on phones? All modern phones (and not-so-modern) support webGL. I don't have concrete stats on _how_ well they support it (i.e. performance) but I haven't heard anything particularly worrying about using webGL via the web on mobile devices.
  14. You're totally right to hate ads, almost everyone hates ads, even the people that create them hate ads. Some alternative monetisation approaches: * Free demo, paid game. App stores make this trivial, harder for web. * Pay for things in game. New Amulet of Awesomeness +2, that'll be £2. * Pay for in-game currency. New Amulet of Awesomeness +2, that'll be 200 Mithrilandian Coins. Oh, by the way, if you don't have the coins, you can buy 150 for £2 (never let someone buy the exact amount they need for something, always slightly more or slightly less than required). * Pay for stuff/currency by watching ads. Watch an ad, receive 10 Mithrilandian Coins. This could also apply to 'extra level tries', 'resurrects' or try agains. * Paid DLC. Want your heroes to explore the Mysterious Caves of Vanthrox, just $5 and that stage is unlocked. * Ask politely. Crowd-sourcing, Patreon, Kickstarter, you could direct to any of these sites and just ask for donations. There are probably loads of more inventive ways to get players to part with their cash. I have no experience of an SDK or other tooling to help, I _thought_ that iOS/Android platforms made this relatively straight forward, so that you didn't need a third-party tool to help. No idea for web and/or cordova-plugins.
  15. Not just webgames, any games! Not just games, any applications! The easier you make it for people to just get going, the less friction they have, and the more likely they are to get to the 'am I having fun?'. Games like Dwarf Fortress take a lot of effort to get going, they lose a lot of players before they get to the 'am I having fun?' question. Affordance theory (presented initially by Gibson) is the theory that objects 'project' their usage, the normal example is a door handle, the shape of the handle implies gripping and turning, you can argue whether this is learned or innate but you can not argue that almost every one on the planet knows how to use a door handle without thinking about it. The holy grail is to get your game/UI/app so intuitive that users just naturally fall into a 'pit of success' and are able to perform the actions they need to to meet their goals, i.e. win the game. I'd argue that advanced users might want more information, but, ideally that information should be in-game. The opposite view to this was popularised by Minecraft where players were encouraged to discover mechanics together, usually outside-of-the-game (at least initially) via the internet (youtube, forums, etc etc). Minecraft is a bit of an outlier for many practises though, but, its an interesting game mechanic to explore, of course, you need to player base in the first instance to be able to explore it.
  16. If you absolutely have to provide detailed game instructions, particularly to beginners, you're doing something wrong...
  17. Websockets will be the more elegant solution, and lets you 'push' to clients as state changes rather than 'pull'. Most websocket implementations, such as, will gracefully fall back to long polling for you, for those handful of users stuck on an old browser that doesn't like websockets.
  18. > Anyone has any ideas why the responsive code doesn't work? Because Safari is the new IE6. Seriously, I've had a group of developers waste a load of time on inaccuracies in Safari like this one, with very mixed success. There are so many little problems with developing for Safari. The blue hotspot 'banner' is often invisible to the web, ditto for the task bar at the bottom. Dealing with either is not good, in fact, I'm not convinced you _can_ even deal with the hotspot bar effectively, although, as you've noted, different versions manifest different bugs/inaccuracies so maybe it is more accurate to say that you can't fix things for all your users all in one go; i.e. you have to pick the _least_ annoying problem and some users will just have to live with it, either the least annoying problem or the smallest sub-set of users. Something you could check though, that might help: *Check when resize fires* I think that it can be a little inconsistent (across versions) i.e. sometimes it fires early and you'll be measuring the screen _before_ the resize, sometimes it'll fire late, in your case it sounds like maybe it is firing early and you aren't measuring the screen dimensions you think (and want to be) you are. The only solution for this _early_ firing is to use a small timeout. Of course you don't want to fire it too early and you don't know when the screen will _actually_ rotate so you have to give it a bit more delay than you think, which will be 'flashy' for users, and using timeouts for this stuff is always dangerous because there might be some processing that delays rotation and you get it wrong. You _could_ try to work out the ratio and try to keep track of landscape/portrait to see if you're checking the correct orientation change, but, if you get this wrong (i.e. when the user rotates a lot) then you could get really stuck.
  19. Interestingly, there is a proposed workaround noted in the description of this issue (on a totally different project), Also linked is a bug report to webkit.
  20. On paper, the easy way is to load a tiny JS script, totally decoupled from your main application, and have that power a loading screen. However, as you mentioned, the whole single-threaded thing will typically cause jank, often not too much (depending how exactly you are loading things) but sometimes an unacceptable amount. Just search for CSS loading spinner, such as, then copy-paste one you like if you don't want to create one yourself. Unless your target market is a browser many many many years old, CSS animations get their own thread well away from JS, so they won't jank. You can use JS to control CSS animations or transitions to do a progress bar if you want. The CSS transition that moves the element (or resizes it) will be jank-free and you won't notice when JS is blocked to control that CSS as a loading progress bar is not expected to be smooth anyway. You can even go all fancy and stuff and dump loading in to a web worker, which kind-of gets its own thread, so your main thread can do the animation, which is pretty normal for non-JS platforms. However, depending on what you're doing, this won't always work anyway. Plus, its taking a sledgehammer to stick a tack in the wall. But, it is _an_ option. I don't think the above answer solves your problem, apologies if I'm wrong but, having poked through the code, it looks all JS powered and will be susceptible to block-jank. Also, be aware, your loading operations will be mostly asynchronous (unless you've really mucked things up), you might do some synchronous work to manage the asset after load, but, typically that is a tiny bit of work (edit: oh, you mention world gen, yeah, that'll block things up). Also also, try it under typical conditions. Depending on your visual style, a little bit of jank in a loading screen is often acceptable to a user. The real trick, of course, is to work out a way you don't need that loading screen at all, and, if you can't, make it absolutely as short as it can possibly be. A trick for world gen (again, this sounds like overkill most of the time), or any long-running task, can be to use generator functions and then bail out every 16ms of so to let stuff animating actually animate to 60fps. As crazy as this sounds, React (a popular front-end rendering library) has a scheduler now that basically does this very thing (its called Fiber and I don't think it doesn't use generators, but the architecture and theory is the same to the concept above of 'bailing' out occasionally). I've done this with line-of-sight operations, but, it quickly proved more trouble than it was worth. Still, it is _another_ option.
  21. What host wouldn't support websockets in 2019? In any case, I'm not entirely sure how access rules might muck with websockets after the initial http handshake, I kinda assumed it just used the same port and that, most of the time, so long as that port was open for http (which it will be for a public server) that there would not be an issue. Yeah I just checked, ws work fully over http and ssl ports, so, they'd work with those standard open ports (i.e. 80 and 443 are defaults, the ssh port is a different one which may be locked down for very cheap or very old providers). Do the hosts you normally use explain why websockets might not work? I say all this, I haven't used anything other than a VPS for many years so maybe I'm totally wrong. Documentation on provisioning your own VPS is now superb from all major vendors (I can fully endorse DigitalOcean, docs are top-notch and easy to digest. AWS/Azure/GCP etc, i.e. the big leaders, also have excellent documentation, but its harder to digest as there are so many options). If you're having trouble with however you normally host things, would you consider getting a VPS spun up? It can be very cheap also. There are also services like Netlify, Now, even Apex, which pretty much handle all of this for you. If you haven't seen these tools then there is something very freeing about being able to run `now` and see your application automagically update itself with your latest version/changes.
  22. var arr2d = [ [ {hp: '00'}, {hp: '01'} ], [ {hp: '10'}, {hp: '11'} ] ] Does this help? Now you have nested arrays, which you can access like `arr2d[0][1]` and get back an object? i.e. console.log(arr2d[0][0]) // {hp: '00'} console.log(arr2d[0][0].hp) // '00' Technically you could perform some weird mapping, i.e. [ hp, someOtherVariable ] But, honestly, its just a pain. I'm not even totally convinced it becomes more memory efficient (it looks like it should be, but, JS is weird, I wouldn't bet on it, in any case, the saving would be tiny and you could maybe lose access performance, again, hard to tell). Generally, rather than accessing directly each 'cell' inside your nested array structure, you might make things a little more readable by doing: // Don't do this arr2d[0][0].hp // Try this, more readable var entity = arr2d[0][0] entity.hp // Even better, but, more abstraction function get (x, y, data) { return data[y][x] } var entity = get(0, 0, arr2d) entity.hp Note that `get` is a helper function and note the positions of `x` and `y` very carefully, this is not a typo.
  23. Nice Grelf. I had only tentatively considered performance at this point, so, using 'ids' as object keys was as far as I went. Storing an actual search key (like `x + ' ' + y`) is a great idea. I haven't touched this for a few weeks as I've been off on holiday, but I think my entities have an `x` and `y` field, but my tilemap array has that array of references also. My thinking there is that I want entities to be largely responsible for their own actions, so, I can trigger (for example) an update function, which can inspect itself for [x, y] then request data from the tilemap based on that location. Entities in my simulation are not complex enough to require a memory, but that could be an interesting place to go in the future, where they store sections of the map, or, their own representation of that map, ooooh, now I've written that maybe I do want that sort of thing, ha ha, more work!
  24. I've used snap before, loooong time ago now, but was a good experience.