Posts Tagged ‘smartfoxserver’

Unity project – what to do next, part 1

August 31, 2014

A while ago, I had a bit of a think about what I should do next, subsequent to completion of my initial foray into using mysql and a smartfoxserver extension to handle persistence in a unity game world.  So in this post I will outline these ideas, however, this is not what I intend to focus on next in my project based on my current thinking.  That will instead be the focus of part 2.

Database considerations – inventory, equipment, etc.

Certainly it would be good to implement an inventory table in the database and an inventory manipulation interface in the game client.  Then, once this was done, I would like to create an “equipped” table, and allow a player to equip items, and for the state of what is equipped and what is not to persist.  Furthermore, I would like the appearance of various items to be displayed on the character, and for this to be transmitted to other players in the game via the smartfoxserver extension, so that the appearance of the player to themselves, and to others, was consistent with their current equipped / non equipped status.I think this would be a good next step to take this game project, albeit a rather conventional one.  Doubtless later on I will be able to do certain things that are a bit more surreal and slightly off the beaten track.

In terms of obtaining models, etc, to use as inventory, I learned from this video that there is a site, turbosquid, that specialises in 3D models, and many of the resources there are free.  So this is an additional resource of items in addition to the Unity asset store that I could use.

Character customisation / appearance of models

In terms of character customisation, there is already a certain amount of information and discussion on the web regarding how to modify the mesh of a character and swap in / out various items / armours etc, rather than clipping them all on the same model and merely hiding the ones not in use.  It is possible to do this, of course, but is not recommended – in an environment where one has say even a moderate amount of players running around, a game world will take a considerable performance hit.

In particular, there are these discussion threads, all on the Unity forum message boards:

In particular, the last thread points to an out of the box character customisation system for Unity, albeit for Unity Pro, which is by no means a cheap or ready to hand solution.  But nonetheless interesting that the solution exists – maybe in a year or two, Unity free might support something like this?

In terms of criticality of getting something like this working, though, although fascinating and definitely somewhere I’d like to get to eventually, this is not really what I’d like to target next.

Interface and gameplay

The third subfocus I had was to start working on the user interface, as well as gameplay, in particular:

  • health bars
  • skill bars / skill & spell books
  • equipment and character equipment slots
  • icons for skills and equipment, and empty character equipment slots
  • a skill system for skills, spells, etc
  • an action system for combat / player movement
  • better avatars / monsters
  • a minimap
  • gameplay
  • access to local events only on the client – though the server should keep track of all events (albeit, as representative data, of course)

For all of these, save the last two (the second last which is contingent on sensible synthesis of many of the rest), I identified assets on the Unity Asset store I could (and can) use / adapt to my purposes.  I’ve also found another site that sells quite interesting character and monster models (including a dragon!), which has also piqued my interest .  This will probably be a good next step.  Furthermore, I could in particular work to tie in of all these features to

  • a sensible database schema and messaging system, both in the local game client and on the server ( I already have solutions that exist for this and work quite well – C# messenger extended locally and smartfox for the client server messaging)
  • full multiplayer functionality

Abstract / surreal environments and game logic

The fourth idea that I thought would be interesting to focus on was incorporating a heavy surreal element into what I am trying to build.  This is something that I think is good to aim for in games, since it is in such that there is this tremendous opportunity to suspend the laws of reality and physics as we understand them, and flip them on their head.

Gameplay is also quite important, so I also had in mind looking into combat (magic & melee).

And then, consequent to this step, and prior to doing advanced project work on meshes / customisation of characters, I thought it would probably also be good to focus more on multiplayer functionality, eg, grouping, chat.  And maybe minigames, as well as some sort of quest system.  This is probably where I’d like to start diverging from the standard, and start exploring a somewhat more abstract and idiosyncratic game world and game logic – like Another World, or Abe’s Oddysee / Oddworld, or even, more prosaically, the Link games / Super Mario World universe.  Something a bit unusual.  I’d also like the gameplay to allow for a certain degree of freedom in terms of actions / animations, eg, dodge and roll, etc.

Artificial intelligence frameworks and embodiment

The final discarded item in the string of ideas I thought would be interesting to consider (and which I may eventually return to) is artificial intelligence.

In particular, I’d be very interested at some point starting to look into using OpenCog for embodiment of intelligent agents in a Unity game world, and somehow also incorporating that into the game.  This would be an extremely interesting thing to do – not least of which is that it seems that the community team behind that project seems to be starting to get some traction with their ideas.  Certainly at the very least I’m interested to see how things progress on that front over the next few years – as, if their current roadmap is even to be half believed, there could well be some fairly interesting behaviours one could instantiate in agents within a game world circa 2015+ or so, through use of the OpenCog framework.   Something that would be worth doing by someone on that project in particular might be to write tests; certainly, if I had unlimited amounts of time and energy I would do so myself, but I consider this extremely unlikely at the moment given my current priorities.

Experiences in deployment of my Unity application to Amazon EC2

June 22, 2014

In this post I will document my experiences of attempting to deploy my Unity application to the cloud.

First of all, I decided that I would use RightScale, and Amazon EC2, as I had succeeded in using this combination in the past to deploy smartfoxserver2x-Unity prototypes.  Of course, in this instance, there was a new dimension – interaction with the database.

In the end, I adapted the smartfoxserver template by adding a couple of my own rightscripts.  In particular, I was interested in doing the following things on boot of the server in addition to installation of the SmartFoxServer2X instance:

  • download extension jar files from dropbox
  • download a shell script from dropbox
  • download a mysql representation of my database from dropbox
  • install mysql server 5.5 and start the server
  • load the database file into an appropriate table
  • editing the log4j.properties file for smartfoxserver to allow trace logging (via log4j)
  • editing the xml document for the appropriate room to reflect desired configuration options for the extension jar file (optional, see below)

And finally

  • an operational rightscript that would redownload the database and the extension jar file to the correct location
  • an operational rightscript that would copy the server logs to my dropbox (wput)

Admittedly, the first three are not hyper-secure in terms of data-security, but as I am primarily interested in just getting things to work, and relatively cheaply, this seemed like a good compromise – particularly as for a t1.micro server (that I eventually plan to use, in lieu of an m1.small) – the only way to configure the thing is on boot.  I eventually opted for a RightImage that was an Ubuntu 12.04 machine.

Additional things I needed to do involved:

  • configuration of the smartfoxserver admin to enable the extension jar file
  • management of the appropriate security groups to include ports for MySQL

Eventually I managed to get all of this to work (after much in the way of abortive attempts with seeking to jump straight past MySQL 5.5 to upgrade to MySQL 5.6 which I did not need)*, but still was not able to validate / log into the application. This led me to investigate using log4j within my extension jars to capture / trace behaviour at that end – however it turns out that even this was not necessary, since the server should still have been logging what was going on with the program.

*As a minor aside, MySQL is quite easy to install – indeed, I found that the following was sufficient for my purposes:

export DEBIAN_FRONTEND=noninteractive
apt-get -q -y install mysql-server

At this point, somewhat dissuaded by an apparent lack of progress, I decided to focus on other things for a number of months.  Finally I returned to the problem of cloud deployment of this project relatively recently, and finished addressing the remaining roadblocks.  Essentially the key things still left unfinished were:

  • The fact that the smartfoxserver version was out of date.  I fixed this by altering the rightscale scripts that initially performed a wget on a file in Amazon S3 to a zip file in my dropbox, which I then instructed the server on boot to unpack.
  • UDP configuration in SFS2X/config/server.xml.  It was necessary to provide the server with access not only to TCP but also to the UDP protocol.  I had previously opened up the ports with an appropriate security group but for some reason I hadn’t arranged for the server.xml file to be configured correctly.
  • Basicexamples.zone.xml.  Running locally, I was able to configure this without hazard from the admin page, but due to permissions on the virtual machine this didn’t work properly in the cloud.  I managed to get around this by editing the file manually from the terminal (sudo pico).  In particular what needed to be modified was:
    • Setting the custom login flag to true
    • Adding a reference to the appropriate extension jar class
  • Capitalisation in one of the scripts for creating a room leading to the server not being able to recognise the room extension – I think this was either an operating system thing (less brittle on Mac than Ubuntu), or it might have been rendered less fragile in SFS2X 2.8 (the one I can run locally) but in 2.7 I needed to be more careful.  Regardless, changing the name of the configuration parameter from lower to upper case fixed this issue.

Fixing all these items had the net consequence that, for one thing, I was finally able to see my print / debug statements from my jar files in SFS2X/logs/smartfox.log while the server was running.

More importantly, the end result of all this was that I was able to log in into the world and obtain similar location persistence as I did here.  In other words, I was able to move in the world, log out, and then log back into the world at the same spot, but rather than things running locally, I was connecting from my client to a server and database running on Amazon EC2.  Neat.

__________

So that’s my report as to my experiences with Amazon EC2.  It took a few months, but I got there in the end.

In terms of next steps:

I’ve been giving some thought to how to keep track of the movements of creatures (eg, mobs and npcs) as well as persistent world events (such as weather, day / night cycle) in the application.  This is an issue because although I have managed to obtain persistence of player characteristics (eg, potentially level, stats, equipment, friends list, and, of course, what I have implemented so far, namely position and rotation information) if two players log in and run all the creatures / weather /etc on their clients, then they will have different views of the environment than each other.

To get around this, one would need to have I suppose what might be aptly named as an instance of the game running on the server, with say a vector of transforms / spawn points representing creatures (as opposed to a singleton transform & spawn point for each player), and timers for the day / night cycle, etc, all sent to the server program, which in turn would synchronise with the database and any other player clients connected.  There is really no getting around the need for a separate client running on the server, since creature movements would be too complex to model properly if merely say updated in a java program, for instance.

However, more in terms of a more concrete roadmap and action plan, I am fairly interested in refactoring this project in preparation for Unity5, as then perhaps I might be able to take advantage of Unet, a perhaps more sensible networking framework to use than SmartFox, if I am going to be developing in Unity.  It is also important that I find a good way to simplify my project layout – although I finally have the thing under version control, the project structure is a mess and contains a great deal of assets that I don’t need or am not using, or are not in a particularly sensible structure.  One of the things that I’d like to do, for instance, which sadly is not the case now, is to have a clear separation between source assets and project files, in particular, scripts.

Furthermore, I have been thinking a bit more in terms of a general roadmap going forward.  I’ve decided that aiming to empower players to create dungeons, etc, in a way that is easy to put something together rapidly, might be a good way to go.  I know that Neverwinter Foundry already does this sort of thing, but the angle that I had in mind was to go for a more of a 3D version of Roll20 – where players could have tools / templates to be empowered to create worlds, and run dungeons and dragons sessions in such mockups.  Then the emphasis / focus would be more on providing tools for a good dungeons and dragons experience, rather than so much as building a complicated combat, leveling, and itemisation system.  In this way, I would seek a slightly different path than the one trodden by many of the more formulaic hack’n’slash MMORPGs that are all over the place these days.  Less action, more emphasis on old school role playing.

Anyway, I guess it is something to think about.

The future of Unity networking, and some investigations with Cocos2D

May 17, 2014

I’m very interested and slightly excited by the recent announcement on the Unity blog that there would be potential implementation of multiplayer capability into Unity.  In particular, this seems to me to be excellent news, for a few reasons:

  • although Photon and SmartFoxServer are under active development still, I suspect that the codebase of either hasn’t been significantly altered within the last ten years.  This leads to concerns about code rot (particularly with the ongoing / various updates) and also whether or not they are suited to modern game development.
  • the cost of licenses to use most of the multiplayer server technology (beyond the basic plan) in terms of CCU (concurrent users) for the most accessible and easiest to set up and run technologies out there.  SmartFoxServer in particular will hit your wallet hard if you want to move beyond the 20 CCU (unbranded) or 100 CCU (branded) free license.  To be more specific, were one to want to have a 500 user license on 5 servers, say, one would have to pay for 5 licenses, one for each server, which would set one back 750 british pounds per license.  Which is ok for established game studios, but perhaps not suitable for the indie developer, or hobbyist programmer / developer.  And these prices seem relatively standard across the industry, currently, for this sort of out of the box capability.  UNet has the potential to change all of that.
  • the people who are working with Unity to make this happen have previously worked on some of the most recent hugely successful game titles in the industry, such as World of Warcraft, Ultima Online and Lord of the Rings Online.

So I’m certainly quite looking forward to this development – in particular the potential for uncapping the user limit on my experiments, which seems like a relatively likely outcome.

One consequence of the announcement is that I will, at least for now, cease my initial investigations into uncapping the user count through looking into coupling Unity with Multiverse, a project that was originally a commercial undertaking instigated in 2004, but which is now owned by the Multiverse Foundation.

In other news, I did some investigation recently regarding Cocos2D, a game development engine for writing 2D games suited probably most for phone or tablet.  In particular I looked at Cocos2D-x, the port to C++ of the original Objective-C based engine, and Cocos2D-js, the wrapper of Cocos2D-x that allows one to write applications in javascript.  I found that this, or rather this, helped me immeasurably with getting things set up and configured.  Like Unity, it appears that Cocos2D supports deployment to many different environments – such as Android, iOS, Windows and OSX, or even to the browser.

Anyway, I haven’t forgotten my promise to complete my series on setting up MySQL-SmartFoxServer-Unity – to be more precise, how to use stored procedures in MySQL to support data persistence etc.  I’ll probably eventually write that post.  But currently, my main goal is to figure out how to deploy what I’ve done to Amazon-EC2 via RightScale.  That will most likely be the subject of my next journal entry.

MySQL, Unity, and SmartFoxServer – location persistence in the game world

January 24, 2014

(In this penultimate of a four part series of posts I will complete my sketch on how I built a working implementation of simple database persistence in a Unity MMO type game, leaving the final post for afterthoughts and other meanderings.)

Greetings,

In this post I continue from the previous two posts:

I will first describe my attempts to read a login location for a player from the database I am using, and then I will describe my attempts to write a new login location when the player exits the game / the smartfoxserver instance is terminated.

First of all, I found that I was able to modify the standard extension jar (not the login extension jar from Part Two) with the following scripts:

package com.spinningcat.mysql.access;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import java.util.List;
import java.util.ArrayList;

public class TransformMySQL {
private Connection connect = null;
private Statement statement = null;
private PreparedStatement preparedStatement = null;
private ResultSet resultSet = null;

public List<Float> getTransformFromDataBase(String username) throws Exception {
try {
// This will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// Setup the connection with the DB
connect = DriverManager
.getConnection("jdbc:mysql://localhost/rpg_mmo_smartfox?"
+ "user=root&password=");

// Statements allow to issue SQL queries to the database
statement = connect.createStatement();
// Result set get the result of the SQL query
resultSet = statement
.executeQuery("select x_position, y_position, z_position," +
"                x_rotation, y_rotation, z_rotation" +
" from rpg_mmo_smartfox.player where name ='" + username + "';");
resultSet.next();
String x_pos = resultSet.getString("x_position");
String y_pos = resultSet.getString("y_position");
String z_pos = resultSet.getString("z_position");
String x_rot = resultSet.getString("x_rotation");
String y_rot = resultSet.getString("y_rotation");
String z_rot = resultSet.getString("z_rotation");

float x_position = Float.parseFloat(x_pos);
float y_position = Float.parseFloat(y_pos);
float z_position = Float.parseFloat(z_pos);
float x_rotation = Float.parseFloat(x_rot);
float y_rotation = Float.parseFloat(y_rot);
float z_rotation = Float.parseFloat(z_rot);

List<Float> result = new ArrayList<Float>();

result.add(x_position);
result.add(y_position);
result.add(z_position);
result.add(x_rotation);
result.add(y_rotation);
result.add(z_rotation);

return result;

} catch (Exception e) {
throw e;
} finally {
close();
}

}
}

And, in the main class called on instantiation of the player in the game world:

package dk.spinningcat.fps.simulation;

import java.util.List;

import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.spinningcat.mysql.access.*;

// Player class representing an individual soldier in the world simulation
public class CombatPlayer {

public CombatPlayer(User sfsUser) {
this.sfsUser = sfsUser;

//used to determine where to spawn the player based on their location in the database
String username = sfsUser.getName();

//extracts the player position, based on their username, from the database
TransformMySQL mysql = new TransformMySQL();
List<Float> result = null;
try{ result = mysql.getTransformFromDataBase(username);}
catch (Exception e) { e.printStackTrace();}

//sets the value of combatplayer to the corresponding position rotation information from the
//database, so that the player is spawned at said position and rotation when instantiated
this.transform = new Transform(result.get(0), result.get(1), result.get(2),
result.get(3), result.get(4), result.get(5));

//this.transform = new Transform(850, 10, 1054, 0, 0, 0);
/*this.transform = Transform.randomRPG();*/
/*this.collider = new Collider(0, 1, 0, 0.5, 2);*/
}

}

Initially, I tested this general functionality by checking that I could access passwords in the database when I fed the program a username string “bob”.  Next I checked that I could access bob’s transform and rotation information.  Finally I made a minor tweak to the above script so that the program used as username the player’s username on login.

Ultimately, these actions were successful.  The end result of these efforts is documented in the following clip, where I demonstrate for two users, “bob” and “charlie”, both with password “alice”, that their spawn locations are dependent on their transform information in the database.

This leaves as a final step in this exercise to determine how to update information in the database on logout.  Consequently the game world should then experience true persistence of player location information.

I was not able to implement this on exiting play mode of the client application, since the username information was no longer accessible to the extension and therefore the correct row in the database could not be written to.  As a quick fix / kludge, however, I determined that writing to the database each frame would do the trick for the time being.  However this is ultimately unwieldy, particularly if there were, say, 100 players accessing the server concurrently – which is possible under the permissions of the free SmartFoxServer 2X license I am using.

Consequently ultimately I will need to do one of two things – either implement a quit button, or to modify the on player exit event, to write the transform of the player (stored as a temporary variable in the CombatPlayer class on the server) to the database – this will be in part 4 of this series.

In the mean time, though, you can see for yourself the successful implementation of my original goal for this mini series in the following video:

The code required to get this to work was, on the client side:

    /// <summary>
/// Send local transform to the server on logout
public void SendTransformDatabase(NetworkTransform ntransform) {
Room room = smartFox.LastJoinedRoom;
ISFSObject data = new SFSObject();
ntransform.ToSFSObject(data);
ExtensionRequest request = new ExtensionRequest("sendTransformDatabase", data, room, true); // True flag = UDP
smartFox.Send(request);
}

and on the server side:

public class RpgExtension extends SFSExtension {

@Override
public void init() {
// Subscribing the request handlers
addRequestHandler("sendTransformDatabase", SendTransformDatabaseHandler.class);

And the handler:

package dk.spinningcat.fps.handlers;

import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.extensions.BaseClientRequestHandler;

import dk.spinningcat.fps.simulation.Transform;
import dk.spinningcat.fps.simulation.World;
import dk.spinningcat.fps.utils.RoomHelper;
import dk.spinningcat.fps.utils.UserHelper;

import com.spinningcat.mysql.access.OnLogout;

import java.util.Date;
import java.util.List;

public class SendTransformDatabaseHandler extends BaseClientRequestHandler {

	@Override
	public void handleClientRequest(User u, ISFSObject data) {
		// The transform we received from player
		Transform receivedTransform = Transform.fromSFSObject(data);
		String username = u.getName();
		OnLogout onLogout = new OnLogout();
		try{ onLogout.updatePlayerPositionInDatabase(receivedTransform, username); }
		catch (Exception e) { System.out.println("Username and password combination incorrect.");
				//e.printStackTrace();
		}

	}

}

And the java mysql code:

package com.spinningcat.mysql.access;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;

import dk.spinningcat.fps.simulation.Transform;

public class OnLogout {

private Connection connect = null;
private Statement statement = null;
private PreparedStatement preparedStatement = null;
private ResultSet resultSet = null;

public void updatePlayerPositionInDatabase(Transform transform, String username) throws Exception {
try {
// This will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// Setup the connection with the DB
connect = DriverManager
.getConnection("jdbc:mysql://localhost/rpg_mmo_smartfox?"
+ "user=root&password=");

// Statements allow to issue SQL queries to the database
statement = connect.createStatement();

Double x_pos = Math.floor(transform.getX());
Double y_pos = Math.floor(transform.getY());
Double z_pos = Math.floor(transform.getZ());
//System.out.println(transform.getRotx() + "," + transform.getRoty() + "," + transform.getRotz());
Double x_rot = Math.floor(transform.getRotx());
Double y_rot = Math.floor(transform.getRoty());
Double z_rot = Math.floor(transform.getRotz());

// PreparedStatements can use variables and are more efficient
preparedStatement = connect
.prepareStatement("UPDATE rpg_mmo_smartfox.player SET x_position = ?," +
"y_position = ?, z_position = ?," +
"x_rotation = ?, y_rotation = ?, z_rotation = ?" +
"WHERE name = '" + username + "';");

preparedStatement.setDouble(1, x_pos);
preparedStatement.setDouble(2, y_pos + 0.5);
preparedStatement.setDouble(3, z_pos);
preparedStatement.setDouble(4, x_rot);
preparedStatement.setDouble(5, y_rot);
preparedStatement.setDouble(6, z_rot);
preparedStatement.executeUpdate();

} catch (Exception e) {
throw e;
} finally {
close();
}

}

// You need to close the resultSet
private void close() {
try {
if (resultSet != null) {
resultSet.close();
}

if (statement != null) {
statement.close();
}

if (connect != null) {
connect.close();
}
} catch (Exception e) {

}
}
}

Finally, some more code on the client side to instantiate the player rotation properly:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// Spawns player and items objects, stores them in collections and provides access to them
public class PlayerManager : MonoBehaviour {

public GameObject playerPrefab;

private GameObject playerObj;

private static PlayerManager instance;
public static PlayerManager Instance {
get {
return instance;
}
}

public GameObject GetPlayerObject() {
return playerObj;
}

public void SpawnPlayer(NetworkTransform ntransform, string name, int score) {
//instantiate the player and move the camera
playerObj = GameObject.Instantiate(playerPrefab) as GameObject;

//adjust the camera to point in the right direction
Camera.main.transform.eulerAngles = ntransform.AngleRotation;

//edit the player position and euler angle coordinates
playerObj.transform.position = ntransform.Position;
playerObj.transform.eulerAngles = ntransform.AngleRotation;

playerObj.SendMessage("StartSendTransform");
}

There were another couple of client side fixes required.  One was to do with the third person controller not functioning correctly – essentially it did not register on spawn that the player was always falling slightly (I needed to delta the y coordinate that player position was stored / persisted at so at respawn the player would not fall through the world).  Anyway, this led to a puzzling difficulty in persisting euler angles of rotation for the player; finally, after debugging by force setting the height of the player to 400 on spawn, I figured out that it was something to do with the OnGrounded() function call in the third person controller.  Long story short, it was an easy one line code fix job, and it would serve no real educational purpose to provide the code itself.

Hence this concludes the bulk of this series of posts.  In the fourth and final post, I will perform some minor fixes.  One will be to delete the waypoints that the guard uses to patrol; for some reason these spheres are not disappearing in my mini multiplayer rpg, though they did disappear in my guards vs skeletons example!  So some investigation is required.

The second fix, mentioned already, will be to either implement a quit feature, or alter the OnUserGoneHandler to write the last known transform of the player to the database; the latter is simpler to implement and therefore is the preferred solution, if possible.    In particular, I will only be writing to the database once on exiting the game, rather than writing certain information to the database constantly – something which, I am sure, would put severe load on the database were there a large number of users accessing the server.  Furthermore, since, ultimately, I am potentially interested in running this server on a small cloud instance – whether that be Amazon EC2 or whatever else – it is unlikely that such is likely to have huge amounts of computational resources to spare.

Finally, I am interested in investigating stored procedures in MySQL, and calling these from the server when certain events occur.  Stored procedures offer various advantages, many of which are documented here.  The main ones of interest to me, however, are security and performance.  Security, since stored procedures allow one to more finely control who has access to do what in the database.  Performance, since a stored procedure lives in the database, and hundreds of lines of SQL code can be called by a short command of the form “Run [stored procedure name] with [specified variable values]”.

MySQL, Unity, and SmartFoxServer – implementing the functionality

January 9, 2014

(In this second of a four part series of posts I will aim to continue to develop my remarks on the foundations of simple database persistence in a Unity MMO type game.)

Hello again,

If one recalls where I left off last time, I had placed both client and server side code under subversion, and also created a simple database, with a single row of data.

The next step is to do something like what is mentioned in this forum post, which is targeted to SFS2X and MySQL specifically.  More broadly, the specifics of this post seem also like a good place to start trying to learn how to interact between the SFS2X extension jar and my MySQL database, or, also, perhaps, this post.

Subsequent to completion of this task, in terms of tidying up and improving upon my implementation, I think it might also be good practice to assign another user other than root to access to the database I created; in practice I’d probably not want to have the root user connecting all the time!

First, however, there is the matter of setting up elementary communication between an sfs extension, running on the server, and the client program written in unity.

In such vein, I followed the instructions in the tutorial by Lars Vogel (linked above), namely:

  • I created a new schema “feedback” in my default instance and a table within that schema, “comments” with the specified data structure
  • I copied the code in Lars’ tutorial to a new eclipse project
  • I downloaded the platform independent version of the connector-J driver from the mysql site, and linked it as an extension jar to the project
  • projectstructure
  • I then adapted the code but so that it would work with the location specific information in the table I created in Part I.
public void readDataBase() throws Exception {
try {
// This will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// Setup the connection with the DB
connect = DriverManager
.getConnection("jdbc:mysql://localhost/rpg_mmo_smartfox?"
+ "user=root&password=");

// Statements allow to issue SQL queries to the database
statement = connect.createStatement();
// Result set get the result of the SQL query
resultSet = statement
.executeQuery("select * from rpg_mmo_smartfox.player");
writeResultSet(resultSet);

// PreparedStatements can use variables and are more efficient
preparedStatement = connect
.prepareStatement("UPDATE rpg_mmo_smartfox.player SET x_position = ?," +
"y_position = ?, z_position = ? WHERE idplayer=1;");
// "myuser, webpage, datum, summary, COMMENTS from FEEDBACK.COMMENTS");
// Parameters start with 1
//preparedStatement.setString(1, "0");
//preparedStatement.setString(2, "0");
//preparedStatement.setString(3, "0");
preparedStatement.setString(1, "850");
preparedStatement.setString(2, "10");
preparedStatement.setString(3, "1054");
preparedStatement.executeUpdate();

preparedStatement = connect
.prepareStatement("SELECT * from rpg_mmo_smartfox.player");
resultSet = preparedStatement.executeQuery();
writeResultSet(resultSet);

} catch (Exception e) {
throw e;
} finally {
close();
}

}

Everything worked perfectly well; I found that I was able to edit and update information in my database perfectly well from this script.

So, with that done, I saw the next step as to figure out how to get a username and password type communication happening between Unity, SmartFoxServer, and mysql.  There is a post here that I found useful in this regard.  Further information regarding programming client side is here (search for OnExtensionRequest); server side programming is covered here.

First of all, as I discovered, it is necessary to set the room in question on the server for SmartFoxServer to use a custom login – so that the extension handler is used rather than the system handler.

Consequently, there is a need to write a secondary extension jar for handling the custom login – on top of the existing extension jar for the game itself (there may well be a way of having both in one jar file, but this has stumped me for the time being).

To set things up, one needs to add an event listener in Init() for the server extension:

public class RpgLoginExtension extends SFSExtension {

@Override
public void init() {

// Subscribing the request handlers
addEventHandler(SFSEventType.USER_LOGIN, LoginHandler.class);
//might not be necessary but maybe necessary when deploy to server online and
//room does not already exist
//addEventHandler(SFSEventType.ROOM_ADDED, RoomAddHandler.class);

trace("RPG Login extension initialized");
}

}

Next, one needs to write a LoginHandler script.  Note: this discussion proved quite informative regarding security for a custom login.

package dk.spinningcat.rpg.login.handlers;

//import dk.spinningcat.fps.RpgExtension;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Statement;

import com.smartfoxserver.bitswarm.sessions.ISession;
import com.smartfoxserver.v2.entities.data.SFSArray;
import com.smartfoxserver.v2.core.SFSEventParam;
import com.smartfoxserver.v2.core.ISFSEvent;
import com.smartfoxserver.v2.exceptions.SFSException;
import com.smartfoxserver.v2.exceptions.SFSLoginException;
import com.smartfoxserver.v2.exceptions.SFSErrorData;
import com.smartfoxserver.v2.exceptions.SFSErrorCode;
import com.smartfoxserver.v2.extensions.BaseServerEventHandler;
import com.smartfoxserver.v2.extensions.ExtensionLogLevel;

import java.util.Date;

public class LoginHandler extends BaseServerEventHandler {

public void handleServerEvent(ISFSEvent event) throws SFSException
{
String username = (String) event.getParameter(SFSEventParam.LOGIN_NAME);
String password = (String) event.getParameter(SFSEventParam.LOGIN_PASSWORD);

ISession session = (ISession)event.getParameter(SFSEventParam.SESSION);

//get crypted password from client login request
String cryptedPass = (String) event.getParameter(SFSEventParam.LOGIN_PASSWORD);

//get plain password from database
//String plainPass = SomeDBManager.getPlainPassword();
String plainPass = null;
try {
plainPass = getPasswordFromDataBase(username);
} catch (Exception e) {
e.printStackTrace();
}

trace("Plainpass is: " + plainPass);

//after compare them via api:
if(!getApi().checkSecurePassword(session, plainPass, cryptedPass))
{
//trace("passwords do not match");
SFSErrorData data = new SFSErrorData(SFSErrorCode.LOGIN_BAD_PASSWORD);
data.addParameter(username);
throw new SFSLoginException("Login failed for user: "  + username, data);
}
else
{
trace("passwords match! hooray!");
}

trace("username and password: " + username + "," + plainPass);
trace("Login successful, joining room!");
}

private Connection connect = null;
private Statement statement = null;
private PreparedStatement preparedStatement = null;
private ResultSet resultSet = null;

public String getPasswordFromDataBase(String username) throws Exception{
try {
// This will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// Setup the connection with the DB
connect = DriverManager
.getConnection("jdbc:mysql://localhost/rpg_mmo_smartfox?"
+ "user=root&password=");

// Statements allow to issue SQL queries to the database
statement = connect.createStatement();
// Result set get the result of the SQL query
resultSet = statement
.executeQuery("select password from rpg_mmo_smartfox.player where name = '" + username + "';");
resultSet.next();
String password = resultSet.getString("password");

return password;

} catch (Exception e) {
throw e;
} finally {
close();
}

}

// You need to close the resultSet
private void close() {
try {
if (resultSet != null) {
resultSet.close();
}

if (statement != null) {
statement.close();
}

if (connect != null) {
connect.close();
}
} catch (Exception e) {

}
}

}

Then, subsequent to compiling the jar (NB: it must have a name of the form [yourfavouriteprefix]Extension.jar) one needs to log in to the server (localhost:8080/admin, user/pass “sfsadmin”), then click on the modules, goto the zone configurator, and make sure that custom login is checked.  Consequent to this, select zone extensions, and select [yourfavouriteprefix] from the allowable extensions.  You will also need to select the main class of this extension (in the above example, RpgLoginExtension).  More on this process can be found here.

selectextension

(An alternative approach to all this might be to directly modify the smartfoxserver xml files, but I’m not sure where to copy files to update the version of the login extension jar that the server sees as the ‘current’ jar).

Also, one needs to copy the mysql connector j jar file to the library folder of the smartfoxserver application (since otherwise the server will not see it).  An alternative approach would be to add this jar to the classpath.

Also, too, every time one recompiles the jar file, it is essential to refresh its instantiation in the sfs administration panel as above.

But after these adventures, one should finally obtain something like the following (evidently with your own custom print statements):

smartfoxlogin

Consequent to this, it is a matter of simplicity to disallow login if the username, password combination provided does not match a user in the database.

This wraps up this post.  To summarise, I have learned how to communicate between Unity, a SmartFoxServer login extension, and a mysql database, in order to validate login information.  Hence the foundation is laid for further work, namely, persisting user location in the game world – as a first step in using databases.To possibly reiterate what I’ve mentioned before, naturally one could do many other things with the techniques I’ve started to cover in this post, and will continue to cover in the next – such as inventory, experience, talents, specialisations, reputation, equipped items, friend lists, etc.  Not to mention databases for monsters, storekeepers (limited amount of items in stock, with limited respawn rate, and things like auction houses, or simply shops that keep track of what players have placed on the listings or sold.

In the penultimate part of this series for this mini-project, I will break the task into two pieces.  The first will be, building on the above, to learn how to set the player’s default starting position to the (x,y,z) coordinates in the database that are assigned to the player’s name.

Secondly, it should then be reasonably straightforward to adapt the code to allow one to persist the player logout position (by writing to the database) and then use the final step of this part to read the player’s position on login.  In this part, I might also try and see if I can set up a different server-side user for the database other than root.

Ideas as to things I should probably look into doing next

May 27, 2013

Hi folks,

In addition to some of the things mentioned in the last post, I’ve had a bit of a further play, and have identified to a better degree as to what I would like to try to implement next.

Namely, I have been having a look into MecAnim to a greater or lesser extent – in particular finding this tutorial quite useful.  I’ve since accumulated a bit of a library of basic animations, and a few models, old and new.  In addition to this, I’ve been looking into patrol pathing for the creatures in question, sandboxing this work within a new scene.

Essentially what I would like to achieve is to have a group of friendlies – guards, on a set patrol path, and a group of enemies – skeletons, also on a set patrol path (inspired by this resource). When the two come within sight radius of each other, I want them to close for melee combat.  Upon attack, I would like the other creature to sense this and also join combat.  Creatures will have to face in the correct direction and be within a certain range for combat to be permissible.  In addition, I would like each creature to have a set number of hit points.  When this reaches zero, I would like an appropriate animation to play – then a moderate delay prior to destroying the prefab.  Then I would like a replacement enemy / guard to spawn and start walking along the original patrol path until it sees an enemy / guard, then charges to initiate combat, etc.

In terms of animations, I would like a walking animation to play while the creatures are walking, maybe a pause and idle animation at each waypoint, or certain specific waypoints, and if an enemy comes into sight radius / arc I would like the model to charge until within melee distance – at which point it is to stop and play an attack animation.  For a more convincing experience, I might also like to build in a “morale” stat, which determines at what health % the enemy / guard is likely to break and run in a random direction, at reduced speed.

I would also like the player to be able to join combat on one side or the other, most likely in favour of the guards.

For a bonus feature, I would like to have a button on the player HUD that allowed the following effect to occur – random spawning of large boulders falling from the sky, at say 5 or 6 (or maybe 10?) fixed and predetermined spawn points for the purpose.  ie so that at every predetermined time interval (allowing for delta time so that the implementation is hardware agnostic), a random number (say 1 to 3) spawn points are randomly selected.  Prior to impact I would like there to be an obvious red glowing marker at the location that the boulder will fall.  Then I would like the boulder to spawn and fall at some predetermined speed, and autocrush any avatars beneath, forcing respawn.  Subsequent to impact I would like the boulder to decay after some period of time, maybe with a lifetime of 1 minute  (In the intervening time I would like it to be treated as a wall for pathing purposes, as according to the particular AI script I will be using).

I would then be interested in implementing a dive and roll animation into the player controls, and possibly introduce a stat “reactions”/”reflex” to guards / skeletons, which make it more likely that they will detect imminent impact and also dive out of the way, even if they are in combat.  I would also like to be able to switch this effect off from the player HUD at will.

Later, time and resources permitting, ideally I would like to introduce missile combat animations (bow and arrow, and/or crossbow, sling, etc), and magic combat animations, to allow for guard / skeleton variants that can engage in combat at range.

So that’s my animation plans.  For the time being, as mentioned above, I intend to sandbox this activity, since converting the work to something that is synchronised in a SmartFoxServer might make things harder to build initially; I can do the legwork for that later.

The second thing I am interested in doing, and will probably take much longer to figure out, is to determine how to integrate a MySQL database with a SmartFoxServer application.  The ultimate goal of this will be to implement an architecture wherein I can store player specific login names, passwords (so, for instance if this was a licensed game, they would need to transact, or at least register to obtain a name and password), together with a table containing the set of all that player’s characters and their names, together with a table that, for each character name (uniquely specified for the server (for chat considerations)), contains the information as to health, stats, and inventory.  Inventory would be a string that contained a list of words, eg, potion, wand, leather armour, broadsword, that would presumably be read by the SFS extension jar file and allow the server to transmit to the client the data that relates to the items they have.  That sort of idea, anyhow – so that the data, related to persistence of character state, for the collection of characters each player has, is stored on the server.

So that’s the goal.  I do not expect implementation to be easy, particularly since documentation seems relatively scarce regarding such.  However, this post looks like a good place to start on said matter.  In particular, it is indicated how one might set up a custom SmartFoxServer via the RightScale platform if one wanted to deploy the server in the cloud, say on Amazon EC2, via the 12th point of the recipe (one can directly modify files while booting up/setting up a virtual machine on RightScale).

Game Development #4 – Shop, basic dialogue, and game state persistence

May 26, 2013

I’ve made some further progress with my unity game.  Here is the latest demonstration video:

Previous videos in the series, in reverse order of appearance:

Bridge Battle

Animation and multiplayer demonstration

Transmission of player location via smartfoxserver

In this video, I demonstrate essentially integration of some functionality from a package from the Unity asset store into my game.  The features added are

  • an action HUD, with “examine”, “use”, “talk”, and “focus” as allowable actions.
  • the ability to shop a store
  • basic dialogue (managed as a state machine) – together with the option to switch from english to afrikaans
  • game state persistence
  • basic inventory and ability to equip items

The things that I would like to look into next would be, in no particular order:

  • The option to choose an avatar (or save game) on entry.  Perhaps allow multiple avatars per player, but have persistence of their state (like in a standard MMO).  Allow for different characters to be played (ie, different avatar appearance) but synchronise the chosen avatar across smartfoxserver so that all players see the same thing; this could be done, for instance, by indexing a set of prefabs which was the allowable avatar form list.  Use MecAnim to standardise animations across all avatars, so that there is no ambiguity when it comes to making a call to a player animation in order to do something in particular (eg walk, strafe, jump, run, fight (melee), fight (archery), fight (magic) ).  [This is in fact a great strength of the current incarnation of Unity, the ability to essentially map animations to different character frames]
  • NPC guards on a patrol path.  I thought I might be able to use Rain{Indie} for this, although that might be slightly over the top.
  • A better inventory system.  Allowing one to have object representations for items and mouseover text, if possible.
  • A character representation for item placement.  Allowing one to drag and drop items to particular locations on the character’s frame, or, alternatively, to be able to select an inventory slot and equip / unequip whatever is available in character inventory.
  • Monsters vs NPCs, with spawn points for both – for an ongoing pitched battle.

Unity Game – Bridge Battle

April 14, 2013

Hi folks,

So I have a new progression in my “mini-MOBA” series, here.

Previous videos in the series:

In the first video I demonstrated the starter town, avatars, and multiplayer transform sync.  In the second video I took things slightly further and included synchronisation of animations.

In this newest installment I do a few things.  First, I introduce tab targeting.  It is not demonstrated in this video but I can tab between multiple targets ordered by distance.  As part of the targeting procedure I change the appearance of the targeted on the client machine from white to green.  I also display the name of the character.  Finally I display the target’s health in the top right corner of the screen.

Second, I allow for use of the esc key to deselect a target.

Next, I implemented a messenging system (based on the bergzergarcade tutorial #44) on the local client that updated the target’s health bar (and the avatar / prefab’s hp) every time an allowable attack (within 2.5 units, and facing the correct direction) was made on it.  Consequent to this I implemented a secondary messaging system to send the information to the server, and tweaked the server code so that the target’s client would have the updated information for their health bar.  This is demonstrated in the video by my pitched bridge “battle” where as you can see hit points are being decreased over time on the other screen when I make an attack on one client relative to the other.

Finally, I made a hodgepodge attempt at attack animations.  This entailed alteration of the state machine for the thirdpersoncontroller script.  The results were not perfect; the entire animation does not play prior to returning to CharacterState.Idle and the animation synchronisation information has not been transferred.  These are minor matters to be fixed.

Also another bug which is not shown in the video, was that I haven’t altered my code to allow for the logoff or disconnect of another player, which might cause difficulties.  I will deal with this matter prior to the next step in the project, or eventually, anyway.

Learnings from this work were firstly, the DoNotDestroyOnLoad for a gameobject – I found out that all the Start() functions of gameobjects are called even in scenes that have not been loaded yet.  I guess the alternative is to use an Awake() function?!, but I found that one of my gameobjects was being initialised and then being destroyed when I loaded the very scene that it was in! – very frustrating.  But when I found out what object it was (the health bar) the fix was surprisingly easy.

A second learning was the power of the statemachine in terms of driving object behaviour – this is still something I need to become more adept in.

Thirdly, it was very informative to really examine the workings of the server code, in terms of introducing my own messaging functions to implement health synchronisation / modification consequent to a melee attack.

Next on the agenda, after fixing the bugs:

  • fix the attack animations
  • allow for player logoff / dc

These would be:

  • Allow mouseover target skin modification and mouseclick targeting
  • Respawning (destroy playerobject & recreate when appropriate)
  • GameHUD update
  • Implement NPCs as “SpawnNPC” script managed by the server (don’t want multiple copies of same NPC per client instance!)
  • Implement inventory for players
  • Implement “shops” – I probably will not require currency at this stage but just allow them to be storehouses / other inventory screens
  • Allow for player chat (global)

Then, further afield:

  • Allow for conversation with NPCs
  • Monsters
  • Quests
  • Advanced HUD (mini-map in top right hand corner)
  • More trees, buildings, environmental features and places to explore
  • Leveling system
  • Character screen
  • Quest log
  • Inventory screen
  • Stat system
  • Item buff system
  • Basic missile combat
  • Basic magic combat
  • Currency (game) for items from NPCs
  • Cooperation / group adventuring
  • Arena zones only for player-player combat (default atm is global)

And in the very distant future (subject to a great deal of change):

  • Freemium implementation
  • Special effects for magic / melee
  • Special moves (melee eg whirlwind, charge)
  • Special ranged attacks (fireball, lightning, …)
  • Customised key bindings
  • Customised blender models and animations …

Anyway I’ll see how I go with this.  Very early days as yet.  I might well return to the bergzergarcade tutorials if my progress starts to slow considerably.  Alternatively there is something to be said for putting this project on hold, and instead looking again at Google App Engine.  I have a few ideas there that I’d like to investigate further.

Further progress with Unity Game

April 10, 2013

Hi folks,

I’ve made a bit more progress with my Unity game, as per this video here, which I recorded using QuckTime.  Essentially I’ve succeeded in getting three animations to sync across the server to other player screens – an idle animation (when the avatar(s) are still), a walking/running animation, and an ‘axe-slash’ animation (attack & jumping).

In the video I also demonstrate how the game can theoretically support more than 2 players at once – to be more precise, I show three (although I haven’t figured out how to use the same browser to host more than one login at once without crashing – it may be something silly that is port-related or somesuch).  I am using a Chrome window, a Firefox window, and the Unity development window.

Finally in at least part of the video I show some of my method, in terms of debugging within the server trace – when a message for ‘GoodIdle’, ‘GoodWalk’, or ‘AxeSlash’ is sent to the server it pops up in the monitoring window.  I found that invaluable when figuring out how to get the thing to work – in particular I discovered that the reasons I wasn’t able to get the Idle animation to play at first was because I required that the velocity of the avatar be precisely zero to trigger the change in the state machine, and this became clear when ‘GoodWalk’ was the last message passed to the server according the the log, even when on my client the avatar was still.  Sure enough, I found that on another client, the walking animation of the other avatar was still looping on the spot, which was not what I wanted!  The reason for the bug was because computers are approximate in floating point calculation so this was never going to work – instead I found that setting the absolute speed to be less than 0.1 units for the Idle animation to trigger was what was required.

Consequent to this success, my next order of business will be to determine how to figure out remote targeting, ie targeting of another player’s avatar by server messaging, as well as figure out how to build global chat into the game.  Consequent to building global chat I will see if I can construct a local analogue, ie, that can only be read within a limited range of the individual in question.

Then, following that order of business, I would like to handle combat damage, respawning, and combat / noncombat zones.  And also allow for player groups.  Wish me luck.

Structs in C++, Unity game, and other musings

March 18, 2013

Hello, again,

Yes, as per my previous discussion, it is a bit of a shame that I’ve since lost the posts I had here earlier.  Alas, the perils of not fully testing deployment / upgrade options on a remote service!  Still, the benefits of having this service far outweigh the minor inconveniences caused by the dropping of some data.  And I can still remember most of what I posted.

I’ve looked into the concept of taking backups with dotcloud, I’ve made some progress in this regard, but in terms of the whole backup / recovery approach I think I’d much rather keep hard copies on my computer; so that is what I am now doing.  Certainly using S3 as a backup mechanism gives me the heebie jeebies, since the cost of something going wrong could be a problem.  There are apparently two other approaches that one can take – ftp and ssh.  I may see if ssh is doable at some stage.

In terms of the Unity game I’ve been constructing, the links to the videos in question are first video, second video.

In the first video, I demonstrate logging into the Smartfoxserver 2x FPS example deployed to an Amazon EC2 instance using the RightScale overlay.  I view this as quite an achievement and feel rightly proud of being able to build the project as it stands in this video, even though the code is not my own.  The cost to me of this project was $2 / day, since I deployed on an EC2 small server (I have since decommissioned this, once I had established the utility of the concept).  The cost to use RightScale is nothing for up to 5 of these, since they use 300 of what are known as “RightScale Compute Units”.  One only starts to get charged in excess of 2000 RCUs.  However of course the Amazon instances, or RackSpace, or other service configured with your RightScale account – you have to pay for these.

I kept the default configuration in this example (4 players per game, and a fairly coarse update rate).  Boosting the update rate for the server could lead to a more playable experience (ie less apparent latency / “lag” – in addition to the real latency, of course!). As for the server itself, it can support up to 100 connections at a time – more than this requires a licence from SFS (their profit model). Of course, much more than that might well overload a small Amazon EC2 instance regardless.

The second video demonstrates my progress with pulling the technologies used in the first to a project I have been building, following the BergZergArcade RPG tutorials (quite a resource!).  It shows two screens logged into a local SFS 2X server running on my machine.  In the video I move one of the characters, and, lo and behold, the transform of the character updates on the other screen.  I was very happy with that achievement.

The way that a SFS-Unity game works is essentially one runs the client (which may sit in the web folder of the server, and downloads to the machine of a player if run in the browser – or as a standalone executable), and the client speaks to the extension jar sitting in the server (which is written in java).  The extension jar handles messaging between player clients.  Quite intricate and hard to debug.  But very interesting.  Certainly if there is a more practical way of managing client / server code snippets and source control I’d be very interested in learning of it.

Regardless, I’ve made a bit of progress narrowing down the issue I’m having with animations not syncing (which is apparent in the second video).  Turns out it is an issue with the controller script; I am going to have to rewrite the third person controller script that ships with the standard asset package from javascript to c#.  Apparently it is bad practice to mix the two in a single project, and there is a necessity to modify the script slightly to call functions from auxiliary c# classes.   After that, I think I’d like to try to knuckle through the problem of targeting another player.  Consequent to this I’d like to make mobs for one player the same as mobs for another.  Following that I’d like to start working on the basic combat mechanics, damage, pk, mob despawn, respawn, etc.

On a slight tangent I’ve also started looking at structs in C++.  I’ve found adapting the neural net struct was useful for dealing with higher dimensional tensors.  However this poses problems for anything practical, such as if one wants a mesh of 1000 x 1000 x 1000 with a 3 x 3 tensor, for instance.  Not practical to compute.  Nonetheless, here is the basic idea:

struct coord_t{
int       m_NumInputs;
vector<double> t;
//ctor
coord_t(int NumInputs): m_NumInputs(NumInputs)
{
for (int i=0; i < NumInputs; ++i)
t.push_back(0.0f);
};

};

struct coord_z
{
int       m_NumNeurons;
vector<coord_t> z;
coord_z(int Num1_Neurons,int Num0_Neurons) : m_NumNeurons(Num1_Neurons)
{
for (int i=0; i < Num1_Neurons; ++i)
z.push_back(coord_t(Num0_Neurons));
};
};

Then, in main, one simply declares coord_t p(4), or coord_z q(4,4).  To set a value one writes

q.z[2].t[3] = value.

However, to reiterate, this turns out to be quite inefficient and impractical.  The script will hang at runtime if the arrays are too large – ie there are computability issues.  So my next idea is to instead take a page from the existing book and, instead of allowing say a metric to be assigned to each point in a space so I can compute, say, geodesics via the non-uniform geodesic equation, I would instead take a big array (say only for spatial, 250 x 250 x 250), and then take as final array a coarser subarray (say on average 100 x 100 x 100).  So that the “twisting” of the metric can be arranged by allowing cells in the x, y, z directions to be identified for intervals from 1 up to 10.

In other words, I would have a uniform base array, and then on top of that array pick out a subset of points, to define a non-uniform array containing metric information.  The metric that I had in mind to use as prototype would be the random matrix Rand(0,1) = ((r, r, r), (r, r, r), (r, r, r)), where r = rand(0,1), a function that randomly assigns a value between 0 and 1, provided that the random matrix is non degenerate.  And this is to be computed (effectively) point wise.  And with the convention that the smaller the value the larger the distance between points should be, and that “infinity” or “1/0” is 10 units.

Anyway something to look into.  Evidently I still need to figure out how to represent metric information in terms of construction of non-uniform sub-arrays, but an approximation algorithm certainly seems achievable.  And should be computable.

Consequent to this, the idea would be to apply a finite difference equation to the total array, bearing in mind that the subarray would be the points where the output array is to be read off.