Page 1 of 2
complex moves : client side vs server side
Posted: 16 April 2020, 17:59
by Lunalol
(By advance, sorry for my level in English and thanks to google translation.)
I'm developing a wargame on BGA (very crazy project, big complexity).
Movements of the parts are really complex (movement points, terrain, rivers, control zones ...).
I want to manage that on the client side (no server overload, no network lag...) in Javascript.
But i need to valid moves on the server side (no cheating).
So computer code is duplicated (php on server-side, JS on client-side).
- Is there another way to do this ?
On my first try, I just use server-side. Valid moves was passed to client by arg method in machine state conf.
But it was really hard to cancel move and and give the player a chance to change his mind.
Thanks.
PJL
Re: Need advice.
Posted: 16 April 2020, 22:31
by vincentt
Hi,
If you want to manage those kind of things in the JS and only then validate it with the server, you can use client states, it is easier when you implement this.
Victoria_La put some things in the cookbook and you can look at her code on various games on the studio.
However, yes, it means that you will need to code the logic twice, once in the JS and once in the PHP. you could "cheat" and trigger an action in the JS to recover information sent by a notif, but I think it may be a bit farfetched.
Maybe Een has another solution
Cheers
Vincent
Re: Need advice.
Posted: 17 April 2020, 13:04
by fafa-fr
Hi,
About cancelling move:
Lunalol wrote: ↑
But it was really hard to cancel move and and give the player a chance to change his mind.
Don't know if it'll help for your game, but on the game (no name here, it's a surprise) I'm working on (at least I 'm trying to ... I should have more time soon), this is what I did to let players undo their turn. It's possible to do this in this game because during a player turn, no secret information is revealed and no random action is triggered. And it can happen that a player gets to take quite a lot of actions, so the possibility to change one's mind is very useful in my opinion, even if it's complicated and requires a lot of carefulness. I'd be happy to hear comments about this.
- At the beginning of each turn, DB tables are duplicated (tiles -> tiles_backup, and so on, and also some columns of 'player' table, including player score, of course!).
- All changes during a turn are commited to the standard (not backup) tables. Notifications are sent only to the active player, and stored in a 'temp_notifs' table (they will be sent to other players only when the turn is validated). All game pieces that move are stored in a 'moved_pieces' table (only the first time they move), with their original location.
- If a player undoes their turn, pieces that have moved are placed back to their original location (this can be tricky depending on the UI), tables are resetted with the values in backup tables. Depending on your implementation, you must be very careful about some details that also need to be resetted, like global variables on client side, etc., and of course player scores and various counters.
- If a player reloads the game page, the tables used by getAllDatas to send datas are the standard ones for the active player, and backup ones for other players.
- When a player confirms their turn, notifications from temp_notifs are sent to other players
EDIT: this doesn't work because notifications are not sent to spectators, I'm working on it.
, stats are updated (not during a turn, so that cancelled actions are not counted in stats), backup tables are emptied.
- Players are NOT given extra time until they have validated their turn!
Hope I didn't forget anything.
Re: Need advice.
Posted: 17 April 2020, 13:26
by Fritz
A slightly simpler example than yours can be found in the bga-sharedcode project:
https://github.com/elaskavaia/bga-sharedcode. This implementation includes client states (in contrast to the game state machine states on the server side), which allow you to move tokens around and update counters. The method cancelLocalStateEffects() undoes all local state changes and resets all tokens and counters to the server state.
Look at the file sharedparent.js for the client side implementation, but beware: the implementation is quite complex and spread throughout many functions. So it might take you a while to read and understand how it all works.
Side note: You might want to edit the title of the thread, to make it easier for others to see what it is about (for example "Complex moves on the client side" or something like that).
Re: complex moves : client side vs server side
Posted: 17 April 2020, 15:10
by Lunalol
Thanks for all fast anwers.
Yesterday, I started to use clientState, that's a good solution.
But, I copy PHP code from server side to client side in JS (have to erase $, change => to :, and change array or dict methods, no sprintf in JS

).
I tried to found if ajax is allowed beetween server and client (except for legal actions), but it seems no.
It should be interesting for client to ask server for some reason.
Thanks for all.
PJL
Re: complex moves : client side vs server side
Posted: 17 April 2020, 15:23
by vincentt
Re: complex moves : client side vs server side
Posted: 17 April 2020, 17:03
by Fritz
Lunalol wrote: ↑17 April 2020, 15:10
But, I copy PHP code from server side to client side in JS (have to erase $, change => to :, and change array or dict methods, no sprintf in JS

).
Well, here's a very crazy idea: You could try to automate this process for some subset of PHP, for some helper functions. Here's how you could go about it:
- Load PHP code from the server side (readfile 'modules/SomeHelperFunction.php';)
- Do the replacements you did manually, using string.replace(), etc.
- eval(transformedCode) on the JavaScript side
You would have to be careful only to write PHP code that can be transformed automatically, nothing fancy like classes, annotations, etc. And even then there are thousands of ways this could go wrong... but at least you don't have to maintain the same code (and fix the same bugs) in two places.
Or you could try to find a way to run some scripting language that can run both on the server and on the client. For example, find a Lua interpreter written in Javascript and a Lua interpreter written in PHP... but that's probably even crazier.
Re: complex moves : client side vs server side
Posted: 17 April 2020, 21:21
by RicardoRix
Very simple view, of course there are always valid exceptions:
The complete set of rules must be checked and enforced server side. To avoid duplication you don't need to do this JS client side aswell. Your main game logic should be server side. The client side should be component interaction.
JS should or could allow a player to make all kinds of moves and submit them to the server, server raises a BgaUserException if a rule is broken. If the client accepts possible illegal moves then so be it, this raises the question of computer aided play which can be argued either way if it's right or wrong.
There is the possibility the client only wants to show relevant 'possible moves', if so then it gets this information from the server.
Re: complex moves : client side vs server side
Posted: 17 April 2020, 22:27
by DrKarotte
Fritz wrote: ↑17 April 2020, 17:03
3. eval(transformedCode) on the JavaScript side
I might be wrong, but eval must not be used. I works fine in studio, but will cause an error when building the production version (caused by the JS optimization process).
Re: complex moves : client side vs server side
Posted: 20 April 2020, 19:47
by Een
Please keep a cool head about crazy ideas guys
Some people have done clever "frameworks above the framework" things along the years. Guess what? It always breaks at some point with the main framework evolving

And often, the clever developer has moved on to other things... and their games stay broken.
That's why we have this guideline:
http://en.doc.boardgamearena.com/BGA_St ... otic_stuff
About the topic, I would mention some options:
- display all possible moves client side and validate server side (as mentioned previously, in that case limited help is provided to the player, there are arguments pros and cons providing not enough or too much assistance, I won't enter this debate here as there is no absolute answer)
- pass possible moves from the server side to the client side as a state argument (that's what is done for a lot of games, for example Terra Mystica)
- if there is a complex chain of actions, each one depending on the previous needing complex algorithms to propose possible moves, consider having multiple server states, and use the framework undo to snapshot the initial state and revert to it later in case the user decides to cancel at a later stage (if and only if the player stays the same all along this chain of actions).
In some rare cases, you may still have to write the same functions server side and client side, but it will be quicker and more robust long term than getting around it in a clever but complex way. That's my advice
