[SOLVED]Access gamedatas (and tables loaded) in actions/game

Game development with Board Game Arena Studio
Post Reply
User avatar
Rudolf
Posts: 566
Joined: 24 December 2011, 23:04

[SOLVED]Access gamedatas (and tables loaded) in actions/game

Post by Rudolf »

Hi ... a new miss today (long time not using this environment and ajax :) )
I would like to access gamadatas loaded previously in game.php
something like :

Code: Select all

//////////////////////////////////////////////////////////////////////////////
//////////// Player actions
//////////// 
	
	function placeSat($r,$y)
	{
		self::checkAction( 'placeSat' );
		// obsolete test if Sat is available in player reserve.
		$player_id = self::getActivePlayerId();
		$nbsat= --$this->gamedatas['players'][$player_id]['nbsat'];
		$color=$this->gamedatas['players'][$player_id]['colorid'];
		$sql = "UPDATE token SET token_location='SPACE',token_sublocation=$r_$y WHERE token_sublocation=$color$nbsat"; // sublocation style likes that means on board 
		self::DbQuery( $sql );
		// Notify all players about the card played
        	self::notifyAllPlayers( "satPlayed", 	clienttranslate( '${player_name} played Satellite on ${y}' ), 
			array('player_id' => $player_id, 'player_name' => self::getActivePlayerName(), 'y' => $y,'square'=>$color.$nbsat));

		// Then, go to the next state
            	$this->gamestate->nextState( 'playSat' );	   
	}
I need a field that i've put in 'players' table player_colorId and a field 'nbsat' that i have calculated loading the table, and stored in gamedatas['players']
what is the correct way to do this... is there a function self::getPlayerField?
Don't remember... I will check studio doc again, but if you know, don't hesitate :)
Last edited by Rudolf on 11 August 2015, 22:10, edited 3 times in total.
User avatar
pikiou
Posts: 389
Joined: 03 October 2011, 05:36

Re: Accessing gamedatas (and tables loaded) in actions/game

Post by pikiou »

I didn't know there was a $this->gamedatas. Is it generated in your constructor, in material.inc.php?
It can't be from getAllDatas, right, as it is called for a specific player when the game page is loaded or refreshed by a player's browser...
User avatar
Rudolf
Posts: 566
Joined: 24 December 2011, 23:04

Re: Accessing gamedatas (and tables loaded) in actions/game

Post by Rudolf »

Yes last game dev I did like that, I copied complete gamedatas in a this-> gamedatas...
Because I could not find any other solution!
But this time I would like to do it "proprement" ... I suppose there is a function already defined that gives back extra player fields ? like self::getActivePlayerName() ?
User avatar
Rudolf
Posts: 566
Joined: 24 December 2011, 23:04

Re: Accessing gamedatas (and tables loaded) in actions/game

Post by Rudolf »

But... I stay in a galere!

Code: Select all

    protected function getAllDatas()
    {
        $result = array( 'players' => array() );
    
        [................]	

        $this->gamedatas=$this->arrayCopy($result);
$this->log(1,$this->gamedatas['players']);
	return $result;
    }

function arrayCopy( array $array ) 
    {
        $result = array();
        foreach( $array as $key => $val ) {
            if( is_array( $val ) ) {
                $result[$key] = $this->arrayCopy( $val );
            } elseif ( is_object( $val ) ) {
                $result[$key] = clone $val;
            } else {
                $result[$key] = $val;
            }
        }
        return $result;
    }
function placeSat($r,$y)
	{
		self::checkAction( 'placeSat' );
		// obsolete test if Sat is available in player reserve.
		$player_id = self::getActivePlayerId();

		$this->log(2,$this->gamedatas['players'],$player_id);
		$nbsat= --$this->gamedatas['players'][$player_id]['board']['nbsat'];
		$color=$this->gamedatas['players'][$player_id]['colorid'];
		
		$sql = "UPDATE token SET token_location='SPACE',token_sublocation=$r_$y WHERE token_sublocation='$color$nbsat'"; // sublocation style likes that means on board 
		self::DbQuery( $sql );
		// Notify all players about the card played
        	self::notifyAllPlayers( "placeSat", 	clienttranslate( '${player_name} played Satellite on ${y}' ), 
			array('player_id' => $player_id, 'player_name' => self::getActivePlayerName(), 'y' => $y,'square'=>$color.$nbsat));

		// Then, go to the next state
            	$this->gamestate->nextState( 'satPlaced' );	   
	}

the result of log is strange:
log 1: array ( 2243090 => array ('id' => '2243090', ...
etc

but log 2:
2, NULL, 2243090


gamedatas semble perdre ses données entre le moment 1 et le moment 2... je ne comprends pas pourquoi... et quelle solution?
User avatar
pikiou
Posts: 389
Joined: 03 October 2011, 05:36

Re: Accessing gamedatas (and tables loaded) in actions/game

Post by pikiou »

There is no official function to load the content returned from getAllDatas.
You can get basic player information using $this->loadPlayersBasicInfos() but it won't have the 'nbsat' property you need.
In setupNewGame you should set a global (See the USE GLOBALS paragraph in http://en.studio.boardgamearena.com/#!d ... e.game.php.) or a new MySQL table with your globals.

I have my own ugly way. I serialize various php variables containing all the data I need to run the game. It makes everything rather simple and as optimized.
In dbmodel.sql:

Code: Select all

CREATE TABLE IF NOT EXISTS `vardb` (
  `name` varchar(250) NOT NULL,
  `value` VARCHAR( 7000 ) NOT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Then in yourgame.inc.php:

Code: Select all

function varFromDB() {
   $names = Array();
   foreach (func_get_args() as $nameList) {
      $names = array_merge($names, (array)$nameList);
   }
   $nameConditions = Array();
   foreach ($names as $name) {
      $nameConditions[] = "name='" . mysql_escape_string($name) . "'";
   }
   $variables = self::getCollectionFromDB('SELECT name, value FROM vardb WHERE ' . implode(' OR ', $nameConditions), true);
   $vars = array_fill_keys($names, null);
   foreach ($variables as $name => $value) {
      $vars[$name] = unserialize($value);
   }
   return $vars;
}

function varToDB($variables) {
   foreach ($variables as $variable => &$value) {
      $value = "('" . mysql_escape_string($variable) . "', '" . mysql_escape_string(serialize($value)) . "')";
   }
   unset($value);
   self::DbQuery('REPLACE INTO vardb (name, value) VALUES ' . implode(', ', $variables));
}
In setupNewGame:

Code: Select all

$game = Array('endOfGame' => false, 'blueTokensLeft' => 8);
$playerList = self::loadPlayersBasicInfos();
foreach($playerList as $player_id => &$player) {
   $player = Array(
      'deniers' => 0,
      'boardPieces' => Array(),
   ) + $player;
}
unset($player);
$this->varToDB(compact('game', 'playerList'));  //Saved $game as well as $playerList in the database
And anytime I need $game or $playerList I just fetch them from the DB:

Code: Select all

extract($this->varFromDB('game', 'playerList'));
//Do whatever with $game and $playerList, let's say we modified $game
$this->varToDB(compact('game'));  //I only save $game


To answer your last post:
getAllDatas() gets called when someone loads the table for the first time after its start, or refreshed his browser. Just like the content of yourgame.view.inc.php
Once the request is answered, $this is destroyed.
When a user sends an action, a new request is formulated and $this is constructed again. Only this time there is no call to getAllDatas() so your data is gone.
1) getAllDatas() is only meant to send data for the browser interface to show the state of the game.
2) if you want persistent data, the answer is above (globals or DB).
Last edited by pikiou on 13 August 2015, 13:05, edited 1 time in total.
User avatar
Rudolf
Posts: 566
Joined: 24 December 2011, 23:04

Re: Accessing gamedatas (and tables loaded) in actions/game

Post by Rudolf »

Thanks Pierre, I like this, very useful.
Hope it spent not so much time accessing like this during the game.
User avatar
Rudolf
Posts: 566
Joined: 24 December 2011, 23:04

Re: Access gamedatas (and tables loaded) in actions/game

Post by Rudolf »

... But it does not explain why my own variable $this->gamedatas ... something that I've created and memorized à a T instant ... is erased...
because the only two access are on log 1 and log 2...
User avatar
pikiou
Posts: 389
Joined: 03 October 2011, 05:36

Re: Access gamedatas (and tables loaded) in actions/game

Post by pikiou »

When a request is made, your game object $this is created, populated, then destroyed when the response is sent. So nothing in $this remains from one HTTP request-response to another.
getAllDatas() fills $this->gamedatas when the page is loaded at the game start, but it's then destroyed.
placeSat() tries to access $this->gamedatas when a player sends an action and another request is made, but $this was destroyed already.

The only way so save data from one request-response to another is through the DB (globals actually use the DB as well).
Last edited by pikiou on 12 August 2015, 00:30, edited 1 time in total.
User avatar
Rudolf
Posts: 566
Joined: 24 December 2011, 23:04

Re: Access gamedatas (and tables loaded) in actions/game

Post by Rudolf »

The "this" in javascript, I understand, but "$this->" in php... also present in material.inc.php
I still donot understand... I don't speak about "this.gamedatas"... I speak about an init of an array that I could have named "$this-> myarray" instead of $this->gamedatas in material.inc.php .... And I lose its values between log1 and log2... maybe my copy is not well done and work with references (that are lost?) ? Others global arrays don't lose their datas ... I think it's just a pb the way I transfer data from php function to php function (I dont' care about javascript)?
(but I agree... your db solution is useful)

... I think that I get it ... it sounds like we had two game.php? ther first one don't care about material.inc.php, and the second does?
As if they were called differently?
User avatar
pikiou
Posts: 389
Joined: 03 October 2011, 05:36

Re: [SOLVED]Access gamedatas (and tables loaded) in actions/

Post by pikiou »

I meant $this->gamedatas instead of $this.gamedatas, sorry.

material.inc.php is called at each request to fill up $this with constants. It's called by the constructor of Table, a class which your game class extends.

Which "others global arrays [that] don't lose their datas" are you talking about?
Post Reply

Return to “Developers”