Skip to main content

News

Topic: Sphere for Mac: Andromeda (Read 30227 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
  • Rahkiin
  • [*][*][*]
Sphere for Mac: Andromeda
Hi all!

As I have been writing in my hello-post, I am working on a Sphere engine/runtime for Mac OSX (very native) and eventually also for iOS, that would actually be allowed in the App Store (yes to any sphere game running on iPhone!)

The plans are to use as many native frameworks to keep compatibility and dependencies low.

  • Window management and input: Cocoa (Touch)

  • Joystick input: IOKit

  • Graphics: CoreGraphics and OpenGL (SE)

  • Audio: CoreAudio, libogg+libvorbis

  • JavaScript: JavaScriptCore (comes native now, in ObjC package!) V8, with my ObjC wrapper called L8!



I build my system using a bunch of frameworks, so I can share code with my development toolkit later on.

A couple of new features:

  • More and better event based networking. And also game announcement and discovery using Bonjour (zero-conf).

  • More object-orientated library (with shim for compatibility)

  • Game libraries for nice packaging for code of others. This might use ES6 modules later on.

  • Game packaging into .apps with custom everything! Publishing your game will be awesome!

  • SQLite 3 Databases



I want to note that Bonjour is also available for Windows and Unix.

I have a couple of questions for the community:

  • Is there anyone who ever used (and is still using) a joystick for Sphere games? IOKit is a PITA.

  • How much is JNG and MNG used in practice?

  • What new Sphere features do you want to see and could I build into Sphere for Mac?

  • What existing Sphere features have you never used?



Radnen has given the idea for base/shallow map system to give more options to advanced users, and isomorphic maps.


Love to hear from you guys!

// Rahkiin
  • Last Edit: April 14, 2014, 12:32:05 pm by Rahkiin

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere for Mac <insert fancy name here>
Reply #1
Oh, I got an idea! This may add a new dependency, it may not, but could you add SQLite support? I can think of various things such as item and monster databases for RPG games. It seems to make the most sense. I myself may add such support in my engine, but the more projects with that support the better.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Rahkiin
  • [*][*][*]
Re: Sphere for Mac <insert fancy name here>
Reply #2
There is actually an SQLite library (libsqlite3.0) within OSX, so it would not add a dependency.

Can you suggest some API for it? Would you want to go very DB, Table, Row -like style, or more like this:


Code: (javascript) [Select]
database.query("select * from players") => [{'name':'Rahkiin','score':10},{'name':'Radnen','score':1}]

  • Rahkiin
  • [*][*][*]
Re: Sphere for Mac <insert fancy name here>
Reply #3
I just discovered that my own V8 JavaScript bridge has more features than JavaScriptCore has to WebKit :( This is quite bad... My bridge cannot be trusted memory wise though...

Code: (javascript) [Select]

var c1 = new Color(255,255,255);


Can't now actually be called when simply doing this in ObjC:

Code: (objective-c) [Select]

context[@"Color"] = Color.class;


Which is ridicilous (the fact it was not implemented). It is now, with single-init acceptation, but come-on.... Even I implemented it more awesome. It would actually look at the number of arguments :D

I will find a workaround...

EDIT: Fixed in nice and easily, with a nice hack :)

// Rahkiin
  • Last Edit: March 06, 2014, 08:47:11 pm by Rahkiin

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere for Mac <insert fancy name here>
Reply #4

There is actually an SQLite library (libsqlite3.0) within OSX, so it would not add a dependency.


Good, it's been awhile since I've looked at the internal 'dependency' list for OSX, I thought SQLite was in it, which is why I recommended it.


Can you suggest some API for it? Would you want to go very DB, Table, Row -like style, or more like this:

Code: (javascript) [Select]
database.query("select * from players") => [{'name':'Rahkiin','score':10},{'name':'Radnen','score':1}]



If you can do it like that code piece it would be great, I've always liked object-relational approaches. But that's for getting data back, how about storing data?

Code: (javascript) [Select]
database.insert("table-name", { 'name': 'Test', 'score': '15' });


And correct me if I am wrong, but doesn't SQLite use a single table?
  • Last Edit: March 06, 2014, 09:27:22 pm by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Rahkiin
  • [*][*][*]
Re: Sphere for Mac <insert fancy name here>
Reply #5

If you can do it like that code piece it would be great, I've always liked object-relational approaches. But that's for getting data back, how about storing data?

Code: (javascript) [Select]
database.insert("table-name", { 'name': 'Test', 'score': '15' });


And correct me if I am wrong, but doesn't SQLite use a single table?


You are wrong. It is a single database, single user, single process, single thread. But multiple tables.

Selection will indeed be the easiest. I think your insert idea will work.

For update, I think the easiest approach is this:

Code: (javascript) [Select]

database.update("users",{'name':'Radnen'},{'score':15});

This code snippet updates the user Radnen in the table users, giving you a score of 15. So: update(tablename,whereCond,update). Maybe update(table,update,where) is better.

OR

We could take a functional approach, like I have used in CodeIgniter:

Code: (javascript) [Select]

database.where('name','Rahkiin').orWhere('name','Radnen').get('users') => {/*...*/};
database.where('name','Rahkiin').update('users',{'score':15}) => 1 /* affected rows */;
database.delete('users',{'name':'N E O'});


// Rahkiin

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere for Mac <insert fancy name here>
Reply #6

We could take a functional approach, like I have used in CodeIgniter:


I like the functional approach because it reminds me of my Link library. :)





You are wrong. It is a single database, single user, single process, single thread. But multiple tables.


Oh, that's good to know. I thought everything went into one giant table, but I guess it's just a single user database. But I know for a fact SQLite is multi-threaded; or can be used in a multi-threaded app since I have seen that before.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Sphere for Mac <insert fancy name here>
Reply #7


I want to note that Bonjour is also available for Windows and Unix.



Please don't make me set up Bonjour on my Linux.

  • Rahkiin
  • [*][*][*]
Re: Sphere for Mac <insert fancy name here>
Reply #8

I like the functional approach because it reminds me of my Link library. :)

I just saw you made an update on that. So will make a design for it then.


Oh, that's good to know. I thought everything went into one giant table, but I guess it's just a single user database. But I know for a fact SQLite is multi-threaded; or can be used in a multi-threaded app since I have seen that before.

Ok, multithreaded then, but MT is messy :) I myself don't use multithreading at all because I use kqueue (libdispatch -> RunLoops).


Please don't make me set up Bonjour on my Linux.


There are all sorts of tools to help you with that :P http://www.mono-project.com/Mono.Zeroconf and http://www.opensource.apple.com/source/mDNSResponder/mDNSResponder-320.10.80/mDNSPosix/

But I am not forcing you to also use it in your TurboSphere. It would be cool though.


// Rahkiin
  • Last Edit: March 07, 2014, 08:37:39 am by Rahkiin

  • Rahkiin
  • [*][*][*]
Re: Sphere for Mac <insert fancy name here>
Reply #9
The SQL functional approach:

Code: (javascript) [Select]


var db = new Database("/path/to/db.sqlite");


class Database {
/**
* Creates a new database object given the sqlite file
*
* If file is not found, a file is created
*
* @param path path of sqlite file
* @return Database. null on failure
*/
function Database(path);

var tables; // Array of Strings

/**
* A function to make an empty query or a query with
* given SQL query.
*
* @param sql SQL query
* @return Query
*/
function query([sql]);


/**
* Gives the number of rows in given table
*
* @param table tablename
* @return Number with number of rows
*/
function countAll(table);

/**
* Truncates given table
*
* @param table Tablename
* @return true on success, false on failure
*/
function truncate(table);

function createTable(table,fields);
function dropTable(table);
//function renameTable(table,newName);
//function addTableKey(table)
//function addColumn()
//function dropColumn()
//function modifyColumn()
}

class Query {

/**
* Adds column selection. If never specified, '*' is used.
*
* @param columns 1) An array of column names, 2) a column name. Multiple possible.
* @return Query
*/
function select(columns, ...);

/**
* SELECT MAX(field) portion of the query
*
* @param name of the column
* @return Query
*/
function selectMax(column);

/**
* SELECT MIN(field) portion of the query
*
* @param name of the column
* @return Query
*/
function selectMin(column);

/**
* SELECT AVG(field) portion of the query
*
* @param name of the column
* @return Query
*/
function selectAvg(column);

/**
* SELECT SUM(field) portion of the query
*
* @param name of the column
* @return Query
*/
function selectSum(column);

/**
* Runs the selection query and returns query result
*
* @param table Name of the table. Can be omitted when from() is used.
* @param limit Limited number of rows
* @param offset Offset within the result
* @return Result
*/
function get([table [, limit [, offset]]]);

/**
* Specify the table to select from
*
* @param table Name of the table
* @return Query
*/
function from(table);

/**
* Adds a where condition
*
* Using multiple where() calls results in an AND concatenation.
*
* @param key column name
* @param value value of the column
* @param object Object containing multiple column/value combinations
* @param custom_query A custom where query such as "name='Joe' OR score='15'"
* @return Query
*/
function where(key, value);
function where(object);
function where(custom_query);

/**
* Same as above but with OR concatenation
*/
function orWhere(...); // Same as above

/**
* Adds a join portion to the query
*
* @param table name of the table to join
* @param condition Join condition. If none specified, a natural join is used.
* @param type Type of join. Possible values are left, right,
* outer, inner, left outer, right outer.
* If none specified, defaults to SQLite default.
* @return Query
*/
function join(table[, condition[, type]]);

/**
* Adds a WHERE field IN (item, item) portion joined using AND
*
* @param column Column to compare to
* @param values Array of values
* @return Query
*/
function whereIn(column, values);

/**
* Adds a WHERE field IN (item, item) portion but joined using OR
*
* @param column Column to compare to
* @param values Array of values
* @return Query
*/
function whereIn(column, values);

/**
* Adds a WHERE field NOT IN (item, item) portion joined using AND
*
* @param column Column to compare to
* @param values Array of values
* @return Query
*/
function whereNotIn(column, values);

/**
* Adds a WHERE field NOT IN (item, item) portion joined using OR
*
* @param column Column to compare to
* @param values Array of values
* @return Query
*/
function orWhereNotIn(column, values);

/**
* Adds a LIKE clause, joined with AND
*
* @param column name of column
* @param value value to match for
* @param wildcard Wild card option: before, after, both (default)
* @return Query
*/
function like(column, value [, wildcard]);

/**
* Same as above, but with column-value object
*/
function like(object);

/**
* Like the like() function, but joined with OR
*/
function orLike(...);

/**
* Like the like() function, but as NOT LIKE statement
*/
function notLike(...);

/**
* Like the notLike() function, but joined together with OR:
*/
function orNotLike(...);


/**
* Adds a GROUP BY portion
*
* @param column name of a column
* @param columns array of column names
* @return Query
*/
function groupBy(column);
function groupBy(columns);

/**
* Adds DISTINCT keyword to the query
*
* @return Query
*/
function distinct();

/**
* Like the where() function, but then HAVING clause
*/
function having(...);

/**
* Like the having() function, but joined together with OR
*/
function orHaving(...);

/**
* Adds an ORDER BY portion
*
* @param column Name of column
* @param direction ORDER BY direction: either asc or desc
* @return Query
*/
function orderBy(column[, direction]);

/**
* Adds LIMIT and OFFSET clause to query
*
* @param limit Number of rows to return
* @param offset Offset to start from in result set
* @return Query
*/
function limit(limit[, offset]);

/**
* Performs an INSERT query
*
* @param table name of table
* @param data Key-value object containing the data in column-value order. If not supplied, set() is neccesary
* @return Number with insert id, or 0 if no insert id, -1 on failure
*/
function insert(table[, data]);

/**
* Sets a value for insertion or update
*
* @param column Name of column
* @param value value for column
* @param object key-value store
* @return Query
*/
function set(column, value);
function set(object);

/**
* Executes an UPDATE query.
*
* Can be used with WHERE etc clauses, and with set()
*
* @param table name of table
* @param data key-value store of data
* @return Number of affected rows, 0 on no change, -1 on failure
*/
function update(table[, data]);

/**
* Executes a DELETE query
*
* Can be used with the WHERE etc clauses
*
* @param table Name of the table
* @return Number of deleted rows, 0 on no deletion, -1 on failure
*/
function delete(table);
}

class Result {

/**
* Get the full dataset in an array
*
* Array-item per row. A row is a key-value object.
*
* @return Array of objects or null on failure
*/
function result();

/**
* Returns the result as a single row. If result has more than
* one row, only first row is returned.
*
* @param row Number of the row to return, default 0
* @return Object with key-value data
*/
function row([row]);


/**
* Gets the number of rows in the result
*
* @return Number of rows
*/
function numRows();

/**
* Gets the number of fields (columns) in the result
*
* @return Number of fields
*/
function numFields();
}


Comments so far?

// Rahkiin

  • N E O
  • [*][*][*][*][*]
  • Administrator
  • Senior Administrator
Re: Sphere for Mac <insert fancy name here>
Reply #10
How many sugar methods will be in the Query class, as many as possible or just the most common functions used for filtering?

  • Rahkiin
  • [*][*][*]
Re: Sphere for Mac <insert fancy name here>
Reply #11
In my post above, I actually just looked at the CodeIgniter manual. And it is all of them.

It includes nearly all possibilities for the 95% of all queries, and 99% of queries used by not-advanced DB users. (These are just guesses). Some are kind of sugar yes, such as whereIn(), whereNotIn(), orWhereIn(), orWhereNotIn(). In implementation this can be a single function with some arguments to change the behaviour. But when method chaining it is nice to have it like this, instead of a whereIn(...,'not','or') and whereIn(....,'not','and'), etc.

We could of course remove some or restrict some. For example, instead of allowing both where(column, value) and where(object), we could restrict to where(object) because JS has these short notation for objects: where({column:value}). That would make the list of 'aliases' smaller.

Since I had a more advanced DB course, and as I, when doing real database stuff, do many joins and advanced stuff, I often write my queries by hand using transactions, sql switch cases and that kind of funny stuff. I would never use orWhere(), orNotLike(), notLike(), etc, myself because then it is easier for me to just write the query. But I am not sure about the less advanced game developers around.
The advantage of all these methods is that they should protect against attacks by escaping values etc.

On an update on my engine: currently tackling an awful problem in the JavaScriptCore that is shipped in iOS7 and OSX10.9: trying to hack around it now, or else import JSC from the WebKit repo. (If I have to import, I will not be able to do any iOS testing or publishing until there is iOS8 with an updated JSC).

// Rahkiin

Re: Sphere for Mac <insert fancy name here>
Reply #12
A Bonjour plugin for TurboSphere would actually be cool. Makes me wish I had a newer Mac to build it with.

  • Rahkiin
  • [*][*][*]
Re: Sphere for Mac <insert fancy name here>
Reply #13

A Bonjour plugin for TurboSphere would actually be cool. Makes me wish I had a newer Mac to build it with.


How old is your Mac that you can't? A PPC?

Is there need for UDP transfers? Isn't it very useful for most games? Not sure how useful it is in the games made in Sphere.

// Rahkiin

  • Rahkiin
  • [*][*][*]
Re: Sphere for Mac <insert fancy name here>
Reply #14
Even though the JSC ObjC API should be mature, it is not. The changes made since the release of OSX and iOS are quite major (security, memory and correct functionaility wise).

Result: I can't have correct classes :D
Temporary solution:
Code: (javascript) [Select]

var fs = new __FileSystem();
FileSystem.createDirectory("a");


Constructors need an underscore prefix...

Be right back, crying in a corner...

(edit - fixed code tags ~neo)
  • Last Edit: March 08, 2014, 01:43:08 am by N E O