This is a documentation for Board Game Arena: play board games online !

Difference between revisions of "Troubleshooting"

From Board Game Arena
Jump to navigation Jump to search
(Added navigation)
Line 20: Line 20:
  
 
Calling self::incStat() with second parameter which is an empty string
 
Calling self::incStat() with second parameter which is an empty string
 
  
 
=== Unexpected error:  Propagating error from GS 1 (method: createGame): Fatal error during yourgame setup: Error while processing SQL request: INSERT INTO stats ... ===
 
=== Unexpected error:  Propagating error from GS 1 (method: createGame): Fatal error during yourgame setup: Error while processing SQL request: INSERT INTO stats ... ===
Line 104: Line 103:
 
(can copy from row 5 for example).
 
(can copy from row 5 for example).
  
== Other Errors ==
+
== Type conversion / juggling errors ==
 +
 
 +
=== On php side I get a number instead of string I expect ===
 +
 
 +
$num = 3;
 +
$meeple = "meeple_" + $num; // <-- suppose to be "meeple_3"!
 +
 
 +
When you switch between JS and PHP it easy to type this and not notice the +. Plus sign (+) in php does not mean string concatenation (in javascript does!),
 +
in php + means integer arithmetic. So change + to . (dot)
 +
 
 +
=== On php side my string comparison does not work ===
 +
 
 +
  if ($color == '4baae2' || $color == '000000') {
 +
  }
 +
 
 +
Apparently you should not be using '==' in php to compare strings! You should use '==='. The (==) operator will typecast the strings
 +
to numbers then do comparison!
 +
Its not very apparent because usually you can get away with it, but not when strings resemble numbers like hex 'colors'.
 +
 
 +
=== Integer columns in the database are returned as strings ===
 +
 
 +
This is normal PHP behavior. All fields are returned as string type, regardless of their actual type in the database. This also applies to global variables accessed via getGameStateValue(), since they are stored in a database table.
 +
 
 +
You can use type-casting to convert them to the correct type after they come out of the database.
 +
 
 +
  $myValueInt = (int)self::getGameStateValue(GLOBAL_ROUND_NUMBER);
 +
 
 +
or
 +
 
 +
  $sql = "SELECT my_int_column FROM my_table WHERE my_condition";
 +
  $myResult = self::getUniqueValueFromDB($sql); <-- this is a string
 +
  $myResultAsInt = (int)$myResult;
 +
 
 +
https://stackoverflow.com/questions/5323146/mysql-integer-field-is-returned-as-string-in-php
  
 +
== Other errors ==
  
 
=== When I do a move, I got "Move recorded, waiting for update ..." forever ===
 
=== When I do a move, I got "Move recorded, waiting for update ..." forever ===
Line 170: Line 203:
 
   $this->gamestate->nextState ( 'last' ); // <-- here is missing else, so it will cause double state transition
 
   $this->gamestate->nextState ( 'last' ); // <-- here is missing else, so it will cause double state transition
 
  }
 
  }
 
=== On php side I get a number instead of string I expect ===
 
 
$num = 3;
 
$meeple = "meeple_" + $num; // <-- suppose to be "meeple_3"!
 
 
When you switch between JS and PHP it easy to type this and not notice the +. Plus sign (+) in php does not mean string concatenation (in javascript does!),
 
in php + means integer arithmetic. So change + to . (dot)
 
 
=== On php side my string comparison does not work ===
 
 
  if ($color == '4baae2' || $color == '000000') {
 
  }
 
 
Apparently you should not be using '==' in php to compare strings! You should use '==='. The (==) operator will typecast the strings
 
to numbers then do comparison!
 
Its not very apparent because usually you can get away with it, but not when strings resemble numbers like hex 'colors'.
 

Revision as of 11:40, 6 June 2020


Game File Reference



Useful Components

Official

  • Deck: a PHP component to manage cards (deck, hands, picking cards, moving cards, shuffle deck, ...).
  • Draggable: a JS component to manage drag'n'drop actions.
  • Counter: a JS component to manage a counter that can increase/decrease (ex: player's score).
  • ExpandableSection: a JS component to manage a rectangular block of HTML than can be displayed/hidden.
  • Scrollmap: a JS component to manage a scrollable game area (useful when the game area can be infinite. Examples: Saboteur or Takenoko games).
  • Stock: a JS component to manage and display a set of game elements displayed at a position.
  • Zone: a JS component to manage a zone of the board where several game elements can come and leave, but should be well displayed together (See for example: token's places at Can't Stop).

Undocumented component (if somebody knows please help with docs)

  • Wrapper: a JS component to wrap a <div> element around its child, even if these elements are absolute positioned.

Unofficial



Game Development Process



Guides for Common Topics



Miscellaneous Resources

Describing common errors which is hard to understand and debug

Contents

Game does not start at all

Undefined offset: 0 in table/table.game.php on line 830

You are likely calling self::getActivePlayerName () during setupNewGame()

Unexpected error: Wrong formatted data from BGA gameserver 1 (method: createGame): ...

This is generic message usually followed by exact position in your source code, and usually its syntax error in one of yours php script

Unexpected error: Propagating error from GS 1 (method: createGame): Fatal error during yourgame setup: Not logged

Calling self::getCurrentPlayerId () or using $g_user from 'args' state function, see also below

Unexpected error: Propagating error from GS 1 (method: createGame): Fatal error during yourgame setup: Unknow player statistic:

Calling self::incStat() with second parameter which is an empty string

Unexpected error: Propagating error from GS 1 (method: createGame): Fatal error during yourgame setup: Error while processing SQL request: INSERT INTO stats ...

Fatal error during yourgame setup: Error while processing SQL request: INSERT INTO stats (stats_type, stats_player_id, stats_value) VALUES ('10','2300663','0'),('10','2300662','0') Duplicate entry '10-2300663' for key 'stats_table_id'

Why? In the stats.inc.php you declared two keys with the same integer "id"

Fatal error during creation of database ebd_quoridor_389 Not logged

Check that you didn't use $g_user or getCurrentPlayerId() in setupNewGame() function or in an 'args' function of your state.

As these functions are not consequences of a user action, there is no current player defined.

As a general rule, you should use getActivePlayerId() and not getCurrentPlayerId(). See the presentation on the game state machine for more information.

Warning: Invalid argument supplied for foreach() in table.game.php

  Warning: Invalid argument supplied for foreach() in /var/tournoi/release/tournoi-151226-1240-gs/www/game/module/table/table.game.php on line 129 
  Fatal error: Cannot unset string offsets in /var/tournoi/release/tournoi-151226-1240-gs/www/game/module/table/table.game.php on line 143

That appears when your arg* function that suppose to return array of state arguments returns a scalar (a non-array) value

The server reported an error

During table creation: "The server reported an error" error shown and nothing else.

If you cannot even create a table - there is syntax error in gameinfos.php, check it, reload it from management panel. If still no luck copy clean version from template https://github.com/elaskavaia/bga-sharedcode/blob/master/gameinfos.inc.php

Predefined server errors

Unexpected error: Unexpected final game state (XX)

The action function does not transition to any state, i.e.

 function selectField($field) {
   self::checkAction ( 'selectField' );
   if ($field!=0) $this->gamestate->nextState ( 'next' );
 }

Here if $field is 0 there is no transition

This game action is impossible right now

Check the game log. Usually your state does not define the action you trying to perform in 'possibeactions' array.

Unexpected error: This transition (playerTurn) is impossible at this state (42)

This is pretty self explanatory. Function nextState() takes transition name not a state name, so you probably did not define this transition that the given state

Game interface hangs during reload or on start

Showing "Application Loading..."

Javascript error: During pageload undefined no_stack_avail Script:

This error usually has no useful data, but it means you called somes API that require a callback and did not define callback function, i.e in dojo.connect, this.connectClass, dojo.subscribe, etc

     this.connectClass('field', 'onclick', 'onField'); // <-- onField is not defined

Other errors with "Application loading..."

You probably have a syntax error in your Javascript code, and the interface refuses to load.

To find this error, check if there is an error message in the Javascript console (F12).

If there is really nothing on the log, it's probably that the system was unable to load your Javascript because of an syntax error that affect the structure of the Javascript file, typically a missing "}" or a missing "," after a method definition.

If you have "Uncaught ReferenceError: bgagame is not defined" you have major syntax error in your js file, you should see some other clues in the log where the errors is.

Unexpected Syntax Error:

No further details in the log. When log is filling with some social connect errors.

Possible Reason: Syntax error in of the php script which is loaded before the start, such as gameoptions.inc.php, gameinfos.inc.php and such.

Game interface spins in a loop throwing error

Errors is something like "Cannot read property 'is_ai' of undefined". Cannot restart the game because cannot access UI to stop. Likely you get in actplayer state with player id == 0. The only way to fix it is to edit database, globals index == 2 set player id to one of your test dudes (can copy from row 5 for example).

Type conversion / juggling errors

On php side I get a number instead of string I expect

$num = 3;
$meeple = "meeple_" + $num; // <-- suppose to be "meeple_3"!

When you switch between JS and PHP it easy to type this and not notice the +. Plus sign (+) in php does not mean string concatenation (in javascript does!), in php + means integer arithmetic. So change + to . (dot)

On php side my string comparison does not work

  if ($color == '4baae2' || $color == '000000') { 
  }

Apparently you should not be using '==' in php to compare strings! You should use '==='. The (==) operator will typecast the strings to numbers then do comparison! Its not very apparent because usually you can get away with it, but not when strings resemble numbers like hex 'colors'.

Integer columns in the database are returned as strings

This is normal PHP behavior. All fields are returned as string type, regardless of their actual type in the database. This also applies to global variables accessed via getGameStateValue(), since they are stored in a database table.

You can use type-casting to convert them to the correct type after they come out of the database.

  $myValueInt = (int)self::getGameStateValue(GLOBAL_ROUND_NUMBER);

or

  $sql = "SELECT my_int_column FROM my_table WHERE my_condition";
  $myResult = self::getUniqueValueFromDB($sql); <-- this is a string
  $myResultAsInt = (int)$myResult;

https://stackoverflow.com/questions/5323146/mysql-integer-field-is-returned-as-string-in-php

Other errors

When I do a move, I got "Move recorded, waiting for update ..." forever

"Move recorded" means that your ajaxcall request has been sent to the server and returned normally.

"Waiting for update" means that your client interface is waiting for some notifications from the server that correspond to the move we just did.

If this message stays forever, it is probably that your PHP code does not send any notification when the move happens, which is abnormal. To fix this: add a notifyAllPlayers or a notifyPlayer call in your PHP code.

When I do a move, I get "Sending move to server..." the nothing and game resets to state before the move

Its possible that server code get into infinite loops or thinks too much, in which case it will timeout and will be aborted without any extra logs (and any db transaction you saw in the log won't be committed). You will usually see "Unable to connect to server" message on console in this case. You have to put more logging into server to trace where it hangs.


Some player action is triggered randomly when I click somewhere on the game area

You probably used "dojo.connect" on a null object. In this case, dojo.connect associate the event (ex: "onclick") to the whole game area.

Most of the time it happens in this situation, when my_object element does not exists:

   dojo.connect( $("my_object"), "onclick", this, function() {
     ...
   }

To determine if this is the case, place "alert( $("my_object") )" before the dojo.connect to check if the object exists or not.

Javascript does not know how to sum two numbers

Be careful when you manipulate integers returned by notifications: most of the time, Javascript considers they are Strings and not Integers.

As a result:

    var i=1;
    i += notif.args.increment;  // With notif.args.increment='1'
    alert( i );                 // i=11 instead of 2 !! Javascript concatenate 2 strings !

To solve this, you should use the "toint" function:

    var i=1;
    i += toint( notif.args.increment );  // With notif.args.increment='1'
    alert( i );                 // i=2 :)

Javascript: do not use substr with negative numbers

To get the last characters of a string, use "slice" instead of "substr" which has a bug on IE:

    var three_last_characters = string.substr( -3 );   // Wrong
    var three_last_characters = string.slice( -3 );    // Correct

Game "spontaneously" transition to a new state without user input

Make sure on php side you have no code after $this->gamestate->nextState(...) code. Because if you do accidentally have code that goes to another state it will cause another state transition without user interaction.

function selectField($field) {
  self::checkAction ( 'selectField' );
  if ($field!=0) $this->gamestate->nextState ( 'next' );
  $this->gamestate->nextState ( 'last' ); // <-- here is missing else, so it will cause double state transition
}