Updating a client-side Javascript game viewport - javascript

I am writing a javascript web game that has a 3 x 3 viewport similar to the one Urban Dead uses. The "world map" is stored as a 100 x 100 2D array server-side (nodejs), each pair of coordinate defines a "room". So, the 3 x 3 viewport shows the name and content of 9 of the rooms.
User's location are stored server-side as coordinates. E.g. Bob = { x : 2, y : 3 }. So Bob's x-coordinate is Bob.x. The client (browser) can retrieve this and work out the coordinates of the other 8 rooms, and asks the server for the content of those rooms. These are then displayed in the viewport. This is suppose to look like the viewport in Urban Dead (top left corner).
Question
How should I think about making the viewport "refresh" or update? I am thinking of doing it this way...
1) When the player moves from coordinates (2,3) to (1,3). The client asks the server about the content of the 9 rooms again and re-draw/display everything.
2) When the content of one of the room changes, the server (nodejs) runs a client-side function that tells it to ask the server for the content of the 9 rooms and re-draw/display everything.
Being new to programming, I wonder if this implementation would be too naive or inefficient?

The former option would be the best imo, purely for the reason that as your map expands it will be easier for you to set-up trigger regions that cause your client to load specific areas of the map. You could even only load the rooms that they can see or have access to.
This would also be of benefit, for example, if you were to have multiple characters. Imagine you have your main character in one location, and a secondary character elsewhere. It would be far better for client to know where they are and to understand what each character can see and only request this information from the server. This is a much more expandable solution than having the server just constant broadcast all room information to whoever is listening.
With regards to changes in room content, this could be flagged as an event from the server to all clients - but based purely on room co-ordinates and minimal data. If this event covers one of the rooms the client can currently see, a request by that client for the room information can occur. So in part this involves something of your option two, but shouldn't broadcast much.
As an analogy, this is more akin to having clients/users requesting only the resources they want from a website at the time they want them and possibily signing up to mail alerts about content that's interesting to them. Rather than having the user sign-up to an RSS feed and being notified when anything changes on the site. The former is more optimal and can be controlled in specific ways, the latter is better if your user is interested in overviewing the whole content of the site (which is not the case usually in games -- unless you're designing bots that have to cheat).
Overall, after talking it through implementing part of both approaches would be useful. But if it's a choice the first one will give you more control.

I wouldn't worry about too naive or inefficient solution. The difficult part is to make game playable and fun - optimize later.
Looking at the example, the amount of data to transfer doesn't look very big. You should be able to fetch full 9 room set for update.
Are you pulling the data from server with intervals (polling) or are you somehow pushing changes from server to client?

The question is do you care of AFK being notified, and how important is information about next room.
If you think a strategy can change if a room is updated ? In this case update every time a update is done.
If a player don't care then change are done when pass to next room.
A middle way solution is to ask a "delta" update ( just element who have been modified ) every 10s or 30s depending of the game. In this case us a central clock can be funny ( multiple player will update a same time ), and this create a turn-style gameplay.
As a RPG player ( paper RPG ) I will think the third is a good way. You can even mix solution : short time update for current room, and perception based time ( a bling and deaf will update exterior room only at major event ).

Related

JQuery loop (php + sql)

I've built a very basic game around an 50ms gameloop (setinterval) and I've been considering how to fetch player positions. So far I've had the idea to use ajax to post the player position to a php script which will update a sql database, then select all player positions and pass them back in the return. However i'm concerned that this may hit a race condition or that the entire action will simply take to long >5ms, it also feels wasteful to repeatedly poll the sql database for the same data (player positions). Is there a more effective way to achieve this? I've started looking at caching and sharing objects between php instances but not found much info
It probably is not needed to write this to your database all the time. Use an extension like APCu. You could still write the player's positions to the database at regular intervals with a background process.
It probably is also not needed to return all user positions, but only those that are nearby. From your comment I understood that your game has different worlds, so you would only need to return the user positions that relate to the world the player is in. And even then you could limit it further based on distance, if the player's view on that world only covers a part of it at any time.

Is preloading data into session variables with AJAX upon login a good idea?

I've created a subscription-based system that deals with a large data-set. In its first iteration, it had semi-complicated joins that would execute, based on user-set filters, on every 'data view' page. Each query would fetch anywhere from a few kilobytes to several megabytes depending on the filter range. I decided this was unacceptable and so learned about APC (I had heard about its data-store features).
I moved all of the strings out of the queries into an APC preload routine that fires upon first login. In the same routine, I am running the "full set" join query to get all of the possible IDs for the data set into a $_SESSION variable. The entire set is anywhere from 100-800Kb, depending on what data the customer is subscribed to.
I convert this set into a JSON array and shuffle the data around dynamically when the user changes the filters. In creating the system I wanted it to seem as if the user was moving around lots of data very quickly, with minimal page loading (AJAX + APC when string representations are needed), as they played with the filters.
My multipart question is, is it possible for the user to effectively "cancel" the initial cache/query routine by surfing to another page after the first login? If so, can I move this process to an AJAX page for preloading, or does this carry the same problem? Or, am I just going about all of this in the wrong way? I came up with the idea on my own and I'm worried that I've created an unusable monster.
Also, I've been warned that my questions suck and I'm in danger of being banned. Every question I've asked has come from a position of intelligent wonder, written as well as I knew how at the time, and so it's really aggravating when an outsider votes me down without intelligent criticism. Just tell me what I did wrong and I will quickly fix the problem. Bichis.

Javascript Multiplayer Game - Server Side Validation.

I'm starting my hand at creating a multi-player game using HTML 5 / Javascript.
I'm currently doing some prototypes on different ideas on how to stop people from cheating. Now I know I need to do everything server side and just have the client sending "actions".
My issue is I can't workout the best way to store the game state for each player.
So just looking at something basic; Two players running round a empty map.
Currently my idea is
Both clients(sockets.io) send their actions to a Node.JS server that then responds with a X/Y coord. This is fine. But obviously both clients need to know where the other player is.
I thought about doing this by creating a new database table for each game and having the game state stored in there so the two node.js connections can talk to eachother.
My question is, is this the best way to interact between two node.js connections, would it be fast enough? Or is there a design patten for this specific task that I'm missing?
thanks
Creating a new table per game is generally considered a Terrible Idea.
If you don't need persistence -- ie. in the case your Node.js server croaks, a game may be lost -- you can simply store the games in memory, in an object, let's say games, which might contain an object that has an array of players, each of which might contain x and y coordinates, etc.
var games = {
123019240: {
players: {
123: {x: 1, y: 1, name: 'Joe'},
456: {x: 2, y: 2, name: 'Jimbob'}
}
}
};
If you do need persistence, though, you really should probably look into some other databases than SQL -- for instance Redis might be a good choice for the task.
In any case, SQL feels like the wrong tool, and creating new tables on demand even more so. (If you are using SQL, though, consider a table layout with game_id, player_id, x and y and be sure to have an index on game_id :) )
The approach you need to take is the following:
Each client sends it's coordinate to the server at specific intervals (using emit). The server checks this position for validity and stores it the db. It then uses a broadcast message (http://socket.io/#how-to-use - Broadcasting messages) to send this position to all the clients.
Each client in turn will update the displayed position of the character/player that moved.
You cannot create a direct connection between two players because they are using a browser. Each connection must pass through a single node.js server.
You can view some tutorials here:
http://www.nodejs-news.com/nodejs-tech/Nodejs-Socketio-Building-HTML5-game/
(They use the Impact engine but the principles are the same)
In my experience, if you have users interacting with each other in a clustered server environment, its best to have them interacting on the same server.
Example:
5 game servers, people create games together in a lobby. A game contains a max number of people. With this scenario, it is much much much easier to keep the game on one server, and make all users connect to that one game server. This prevents needed convo between servers, and keeps game state consistent and fast!
Eve Online is a great example of this. Each 'region' is it's own server, and when you travel far enough through the universe, you are transparently moved to another game server. That way if you're fighting somebody, chances are they're on the same server. Then the game server is free to periodically write data to the DB. This is the best way, as the user never has to wait for the DB. They communicate directly with the game server, game server communicates with DB every once in a while. At most, your user would lose only a few seconds of data (and so would everyone else on that game server).

What are the best practices for making online high score lists in JavaScript based games? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
[I know there have been similar questions about preventing cheating on high score lists, but no answer didn't really help me for JavaScript based games, so please try to think about my question, before telling me about similar posts. I ask about best practices because the JavaScript is always visible for the user and therefore it is not possible to prevent cheating completly, I just want to make it harder.]
I'm developing a JavaScript based game that works in the browser. I want to make a high score list that contains the user name and the score of all users. To achieve that the browser sends the username and the score to my server (via AJAX).
Submitting fake scores to this list would be fairly easy: One could take a look at the AJAX requests and then make an own AJAX request with a faked score. Using something like a token that has to be send with the other data is pointless, as it will be easy to discover.
My only approach, that would prevent cheating, would be to send a description of every user action to the server and calculate the score there. But this is not really practicable as it would be too much for the server.
I accepted an answer, but in case anyone has other ideas about how to make cheating harder, please create another answer!
I like to play cheat the cheater - something like using a token to authenticate the score that changes every time the update is called... but I accept the cheat score that gets posted using a duplicate token. Then I display that cheat score to only the cheater, so it appears that it worked, but now the cheater is seeing his results in a sandbox.
You pretty much answered your own question. If you want to really make it harder for users to cheat, send game log to the server, where you'll calculate the score.
You don't have to send all the events, just ones that affect result score.
There are some techniques, though, that may help you:
include signature in your request. Something like MD5(secret_key + params). Although, "secret key" will have to be in JS source, it will effectively protect you from simple request interception (see Tamper Data and Charles)
if it's a multiplayer game, accept scores calculated by clients and compare them. Cheaters will be pretty visible (assuming that the majority of users are honest).
you can set a score cap, an "unreachable" result. Everyone who posts score higher than this is a cheater. For example, speed typing game: no one can type correct text at 1500 chars/minute, even 700 is pretty damn hard (though achievable).
On score submit:
Request some token from the server, this should be time based and only valid for about 2 seconds
Only accept submits that include a valid hash of this token, some salt and the score.
This prevents manual tampering with the request as it would timeout the score. If you want to account for high-latency give it a little more time until the timeout.
The hashing function:
Scramble the hashing function inside packed code (http://dean.edwards.name/packer/ really produces nasty to read code) if you use jQuery or some other library just drop the hashing functionality inside the library file and it gets pretty bad to find, escpecially if you use a function name like "h" :)
Handling the score-variable itself:
Well everybody with a debugging console can change the variable on runtime when doing this but if you encapsulate your whole Javascript inside a function and call it nothing is in the global namespace and it's much harder to get to the variables:
(function() {
//your js code here
})();
I have had lots of thoughts about it and, eventually, decided to only have local individual highscores, so cheating is not really beneficial for player and not harmful to others. Yet my game is just a simple minesweeper, and there were people who complained about the lack of competitive table.
Option 2, is approach taken by WebSudoku - to show your place "among the people of internet". So you will not see any other results, and people wont see your results - but you can compare yourself to crowd.
p.s: And seriously - any kid with Firebug/WebInspector can easily hack your JS game and, eventually, to be able to reach very high score.
If you are relying on the client to send the final score to the server, then there is no way (afaik) to prevent a genius from cheating. But I think you might be able to prevent stupid people (and honest people) from cheating, so that only geniuses and their friends will dominate your leaderboards.
There are two ways I can think of
1.) "security through obscurity."
Come up with an algorithm that transforms simple scores into something else (and to transform them back). Then obfuscate it. Complicate it. Write a function that multiplies it by q and divides it by ralph. Apply a bunch of functions to it, and among the 5-15 functions that do random stuff to it, include one that multiplies the number by 19 ( a prime number ). On your server, check to make sure every incoming number (or letter) is divisible by 19, and decode
You have to write a bunch of complex code that transforms simple scores into something crazy-looking. You have to write a series of functions in the least-efficient, most spaghetti-code fashion possible. Use
One thing you cold do is to have a set of disallowed values. I.e., perhaps all points awarded are even. If anyone tries to submit an odd number, they are obviously cheating (and very stupid).
2.) time
You should be able to know when the user started the game. You should have a session started and record when they requested the page. Then you should also be able to tell when they submitted their score. And you should also know what the time series is for max points. I.e. can you get 5 points per minute, 100 per minute, minute^3, etc... If user submits more points than are possible during that time, they are cheating.
You could also strike a balance between server and client processing and make the client should send progress update every x minutes by ajax. And if it fails to report, you assume it's been compromised (much like in Bond movies, when he's infiltrating the enemy's lair and he snaps some guard's neck. When the guard doesn't respond to his next 10-minutely check-in, the alarms will go off).
If you've ever played Zynga Poker, you've probably seen what happens when someone at the table has a slow internet connection.
Depending on the nature of the game, you could use other players to verify the results. In simple games this works great, on others you have to be clever and develop many aspects around this feature. E.g. sometimes is possible to replay and verify results based on logged actions. This trick works specially well for Human versus AI, as long as the model is deterministic.
Another option is redefining the score concept to be more user-centric, this is pretty easy to implement, but tends to be hard to devise, and only applies to a few categories of games.
Purely speculative approaches are also possible, it's sometimes pretty easy to know when some parameters don't fit. It would not avoid cheating, but would moderate it a lot.
The most complicated part is getting a small enough replay log, but since most data isn't random (except for player actions, which, actually aren't that random because depend on the game) it's essentially a matter of getting the design right.
Also, if gameplay is extended enough, for action games and the like you can get a lot of compression from doing some approximation, merging (e.g. motion vectors), and clipping uninteresting stuff.
Ideally you would send your entire event log to the server for checking. Perhaps you can implement a heuristic so you can easily determine if the score is within a set of bounds. For instance, if the total game time is 5 seconds you might expect a much lower score than with a much longer game time.
Alternatively, you could choose to manually check the event log for really high scores (the overall top-X, which should be fairly stable).
You will need a seeded random number generator if you're doing anything with randomness (like random events). Which might be tricky if you hadn't already thought of it.
You can find many more resources but it really just boils down to server-side checking. JavaScript is not unique in this, but likely easiest to exploit because you not only see the client-server communication but also the client-side source code!
HTML5 Multiplayer Game Security Solutions
http://lanyrd.com/2011/jsconf/sfggb/
Games like Starcraft only record the mouse clicks and key presses. The actual commands are then simulated. I expect 'Worms Armageddon' to do something similar but their random events (like the bounciness of bananas) aren't seeded properly so in the instant replay you might get a different result.
You could imagine something similar for MMORPGs. The server calculates your position based on the keypresses, the client merely tries to give a good early interpretation but you may warp around when you're lagging because the server will place you elsewhere on the map because it didn't get the keypress events timely.
If you attack something, the server will check if you're close enough and how much damage you can expect to deal with current stats and equipment.
Record key points in game, then score is submitted with these key points. When people look high scores, they can also see overview of played game, if it looks like it is impossible to play like that without cheating, then people can report these suspicious scores to admins.
I used a system using a time based request having 3 parameters
req number, curr time, score
The req number is returned from server in the response to the update score request , each time this is a new random value.
The curr time is calculated not from computer clock but from start of game and is synced with server using an ajax request.
Update score request is sent after short intervals (around 30 sec max).
Following checks are applied on the server
Time is within 10 seconds range from the server clock.
there has been not more than 40 seconds since the req number was sent.
the score change sent after 30 seconds is possible (within 2 x humanly possible range)
Score is updated only if the above checks are passed or the user gets a disconnection message :(
This is simpler than most methods and works out to eliminate all casual hackers (well, unless they read this and want to go to the trouble of updating score quickly or making a script of their own).
If not cheating is more important than the game itself, try to construct and present your game in a way that it looks like finding the solution to a math problem. So the server will give an instance of the problem to the client (example A: a chess board about to be won in 3 moves, example B: a geometry dash randomly generated level) and the user will have to solve it and post back a solution (example A: the winning moves, example b: the exact timestamps and intensity of jumps to avoid obstacles)
With this approach, it is key that the server doesn't send the same level twice, or else the cheater can plan and "design" his solution in advance. Also, the game information must be randomly generated in the server and not sent via seed, or else the cheater can fake the seed and design his solution with time.
The given time for valid submissions must be also tracked in the server so that they will only have "playing" time and no "designing" time. If the cheater is good enough to design a solution as fast as honest players can win the game, then they are talented enough to win the game honestly and deserve their points.
Back in the server, you will need to check that the submitted solution is valid for that instance.
Of course this approach requires lots of extra work: More instances of games (ideally infinite and non repeating), server side generation, server side validation of submissions, time caps, etc.
Note: I know these approach was already suggested in multiple solutions some years ago, I wanted to add my humble contribution.

ajax safety in javascript games

In my JavaScript game (made with jQuery) I have player position stored in a database. When character is moving, i just send request to specyfic URL, I.E. mysite.com/map/x1/y3 (where a character's position is x=1, y=3).
That url send coordinates to the database and checks to see if any other players are near ours. If yes, it sends also JSON object with name and coords of that players.
And here is my question - how to secure it? Some one could look into my JavaScript code and prepare url looking like mysite.com/map/x100/y234, and it will 'teleport' him into some other side of map.
Any data/computation processed in JavaScript in the browser will be insecure since all the code runs on the local machine. I would recommend to list all the parameters critical to a fair experience of play, such as the player position, score, resources... and compute the management of these parameters on the server-side. You would only gather user inputs from the browser and send the updated state to the browser for display.
Even if you choose to compute some values on the browser side to avoid latency, you should not take them into account for the global state shared by players, and you should resynchronize the local state with the global state - always in the direction global to local - from time to time.
Like in a typical form handling, you should also check that the values sent by the browser for user inputs fall into reasonable bounds, e.g. relative movement in one second is less than a certain distance.
You could obfuscate your javascript source code. That will at least deter casual cheats, however there's probably no way to make it completely secure using javascript.

Categories