Skip to main content

News

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Rhuan

31
Projects / Re: Project Zelda [MiniSphere 5 Beta]
That's a pretty hefty typo...
Fixed...
32
Projects / Re: Project Zelda [MiniSphere 5 Beta]
So, using miniSphere, v2 api? Any chance I can persuade you to use some of my new scripts? (MapEngine, Sprite Engine and HUDSystem)

I know they're not 100% ready but they're pretty close and having someone else use them would help them get polished.
33
OK updates:

1. Everything is written in ES6 style now pretty much
2. It works again
3. I've added handling for person scripts
4. I've added an extensible input handler

2 key things I still need before I can release a working demo now:
1. A method for loading person scripts from a file
2. A decent talk function to show how it works... :P

One further thing before I can publish this as ready for use:
- documentation
34
Projects / Re: Project ZeC (My Zelda-esque Clone)
Does that BindKey trick work in miniSphere?  Thinking about how the input code in map_engine.c looks, it might not.
Honestly I have no idea, I've hardly used the "default" mapengine in years.
35
Projects / Re: Project ZeC (My Zelda-esque Clone)
In attempting to eliminate diagonal player movements (based on Original LoZ, only 4 movements n, s, e, w) the movement systems I've attempted so far have in fact eliminated the diagonal movement but in the process broken other essential game functions. Might be good movement systems for future projects but not ZeC.
To eliminate Diagonal movement whilst taking advantage of various "normal" features of the sphere v1 map engine you have to.

1. AttachInput to your character. (otherwise OnActivateTouch and related thigns don't work.

2. Use BindKey to overwrite the functionality that AttachInput has given to KEY_UP, KEY_DOWN, KEY_LEFT and KEY_RIGHT e.g.
Code: [Select]
BindKey(KEY_UP,"""");
BindKey(KEY_DOWN,"""");
BindKey(KEY_LEFT,"""");
BindKey(KEY_RIGHT,"""");
3. Implement new movement - normally done by setting an update script that handles it.
36
@Rhuan That first link is a 404.
It had taken the bracket with it, fixed.
37
Sphere General / Re: Promoting Sphere?
Collision algorithm built into my work in progress map engine, I could add more shape types in the future - for now does rectangles and circles:
Code: [Select]
	static polysCollide(x, y, _one, two)
{
let result = false;
let one = {x: _one.x + x, y:_one.y + y, type: _one.type, w:_one.w, h:_one.h};
if(one.type === 0)
{
if(two.type === 0)
{//circle with circle
result = (((one.x - two.x) * (one.x - two.x) + (one.y - two.y) * (one.y - two.y)) <= ((one.w + two.w) * (one.w + two.w)));
}
else if(two.type === 1)
{//circle with rect
let x_d = one.x - two.x - two.w /2;
x_d = x_d < 0 ? -x_d : x_d;
let y_d = one.y - two.y - two.h /2;
y_d = y_d < 0 ? -y_d : y_d;
if((x_d > (two.w/2 + one.w)) || (y_d > (two.h/2 + one.w)))
{//distance between centres > radius + half width or height of square
result = false;
}
else
{
if(x_d <= two.w/2 || y_d <= two.h/2)
{//distance between centres < half width or height of square (combined with check above)
result = true;
}
else
{//final check pythag
x_d = x_d - two.w/2;
y_d = y_d - two.h/2;
result = ((x_d * x_d + y_d * y_d) <= one.w * one.w);
}
}
}
else
{
CEngine.error ("Unknown polygon type given to collision engine, valid types are 0 or 1, supplied type was " + two.type);
}
}
else if(one.type === 1)
{
if(two.type === 0)
{//circle with rect
let x_d = two.x - one.x - one.w /2;
x_d = x_d < 0 ? -x_d : x_d;
let y_d = two.y - one.y - one.h /2;
y_d = y_d < 0 ? -y_d : y_d;
if((x_d > (one.w/2 + two.w)) || (y_d > (one.h/2 + two.w)))
{//distance between centres > radius + half width or height of square
result = false;
}
else
{
if(x_d <= one.w/2 || y_d <= one.h/2)
{//distance between centres < half width or height of square (combined with check above)
result = true;
}
else
{//final check pythag
x_d = x_d - one.w/2;
y_d = y_d - one.h/2;
result = ((x_d * x_d + y_d * y_d) <= two.w * two.w);
}
}
}
else if(two.type === 1)
{//rect with rect
result = (
(one.x <= (two.x + two.w)) &&
((one.x + one.w) >= two.x) &&
(one.y <= (two.y + two.h)) &&
((one.y + one.h) >= two.y));
}
else
{
CEngine.error ("Unknown polygon type given to collision engine, valid types are 0 or 1, supplied type was " + two.type);
}
}
38
Google tells me that RPG Maker is running on NodeWebkit version 0.12.3 (reference: http://endlessillusoft.com/rpgmaker-mv-es6-feature-list/ )

The NodwWebkit github's changelog tells me that this would be running on Node.js version 0.11.13 (https://github.com/nwjs/nw.js/blob/nw25/CHANGELOG.md )

The node.js website tells me that this would be v8  version 3.24.35.22 (https://nodejs.org/dist/v0.11.13/docs/changelog.html) which per V8 github is the 10th February 2014 version of v8 (https://github.com/v8/v8/blob/master/ChangeLog )

Performance wise that will be a dog compared to a current gen Javascript engine; there's been a LOT of performance related innovation in javascript engines in the last 2 years; also obviously that was early days for ES6 - before the spec was actually agreed... so it would have a few early features more there as an experiment/for testing than seriously implemented.

That said the list in the first article I linked is longer than I'd expect.
39
Projects / Re: Project ZeC (My Zelda-esque Clone)
A bit tired to set up a full conversion for you right now - here's an RMP loader - with some comments pointing out the key stuff you'd need to write the bits you want back out again - if you can't work it out I could set it up for you another day, maybe saturday.

Basic idea to write it will be the following - note this is a starting point a working write function will be about 40 lines.
Code: [Select]
//make the output file
let outputFile = new DataStream(fileName.replace(".rmp",".js"), FileOp.Write);

//write out the strings
//you'd need to add the names and brakcets etc to them first
//the loaded versions will be function bodies only
outputFile.writeStringRaw(string1, string1.length);

Note this requires the latest beta of miniSphere 5 to run as it uses some new tricks.
Here's the RMP reading function - this takes an RMP fileName as an input loads the file and then returns an object containing all the data from the file - note you can't skip the read functions you don't need as the data is stored sequentially and each read moves you along in the file  - if you just need the map scripts it will be easier - the entity scripts are further down but the below does load them all.
Code: [Select]
import {DataStream} from "sphere-runtime";

function loadRMP(fileName)
{
let inputFile = new DataStream(fileName, FileOp.Read);

if(inputFile.readStringRaw(4) !== ".rmp")
{
throw new Error("rmpLoader provided with file that is not an rmp file filename is " + fileName);
}
inputFile.position = inputFile.position + 3;//skip version number (always 1) and type which is meaningless

let numLayers = inputFile.readUint8();

inputFile.position = inputFile.position + 1;//skip reserved byte

let numEntities = inputFile.readUint16(true);

//skip startX, startY, (Uint16s) startLayer, startDirection (Uint8s) <- not used with MEngine
inputFile.position = inputFile.position + 6;
let numStrings = inputFile.readUint16(true);

let numZones = inputFile.readUint16(true);

let repeating = inputFile.readUint8();
inputFile.position = inputFile.position + 234;

/*  -strings are all currently ignored, they are:
0 - tileset file (obsolete)
1 - music file
2 - script file (obsolete)
3 - entry script
4 - exit script
5 - north script
6 - east script
7 - south script
8 - west script*/
let mapStrings = new Array(9);
for(let i = 0; i < numStrings; ++i)
{
mapStrings[i] = inputFile.readString16(true);
}

let width = 0;
let height = 0;

//load main Layer data - 1st key output
let layers = new Array(numLayers);
for(let i = 0; i < numLayers; ++i)
{
layers[i] =
{
width       : inputFile.readUint16(true),
height      : inputFile.readUint16(true),
flags       : inputFile.readUint16(true),
parallaxX   : inputFile.readFloat32(true),
parallaxY   : inputFile.readFloat32(true),
scrollX     : inputFile.readFloat32(true),
scrollY     : inputFile.readFloat32(true),
numSegments : inputFile.readUint32(true),
reflective  : inputFile.readUint8(),
zones       : [],
triggers    : []
};
width = Math.max(width, layers[i].width);
height = Math.max(height, layers[i].height);
inputFile.position = inputFile.position + 3;//skip 3 reserved bytes
layers[i].name = inputFile.readString16(true);
layers[i].tiles = inputFile.read(2 * layers[i].width * layers[i].height);

layers[i].segments = new Array(layers[i].numSegments);
for(let j = 0; j < layers[i].numSegments; ++j)
{
let x = inputFile.readUint32(true);
let y = inputFile.readUint32(true);
layers[i].segments[j] = new Polygon(1, x, y, inputFile.readUint32(true) - x, inputFile.readUint32(true) - y);
}
}

//load entity data 2nd key output
//and load trigger data - attached into layer objects from above
let entities   = [];
for(let i = 0; i < numEntities; ++i)
{
let x     = inputFile.readUint16(true);
let y     = inputFile.readUint16(true);
let layer = inputFile.readUint16(true);
let type  = inputFile.readUint16(true);

inputFile.position = inputFile.position + 8;//skip 8 reserved bytes

if(layer > numLayers)
{
throw new Error("layer number " + layer + "for entity" + i + " but total layers in rmp are " + numLayers);
}
if(type == 1)
{
entities.push(
{
x          : x,
y          : y,
layer      : layer,
name       : inputFile.readString16(true),
sprite     : inputFile.readString16(true),//.replace(".rss",".ses"),
sripts     : new Array(5)
});
inputFile.position = inputFile.position + 2;//skip reading number of scripts as always 5
entities.scripts[0] = inputFile.readString16(true);
entities.scripts[1] = inputFile.readString16(true);
entities.scripts[2] = inputFile.readString16(true);
entities.scripts[3] = inputFile.readString16(true);
entities.scripts[4] = inputFile.readString16(true);

/* inputFile.position = inputFile.readUint16(true) + inputFile.position;//burn the scripts I don't want them
inputFile.position = inputFile.readUint16(true) + inputFile.position;
inputFile.position = inputFile.readUint16(true) + inputFile.position;
inputFile.position = inputFile.readUint16(true) + inputFile.position;
inputFile.position = inputFile.readUint16(true) + inputFile.position;*/
inputFile.position = inputFile.position + 16;//skip the reserved bytes
}
else if (type == 2)
{
layers[layer].triggers.push(
{
x      : x,
y      : y,
name : inputFile.readString16(true)//note per spec this is script - but no name and need an ID
});
}
}

//load zone data - attached into layer objects from above
for(let i = 0; i < numZones; ++i)
{
let x1 = inputFile.readUint16(true);
let y1 = inputFile.readUint16(true);
let x2 = inputFile.readUint16(true);
let y2 = inputFile.readUint16(true);
let layer = inputFile.readUint16(true);
let steps = inputFile.readUint16(true);
inputFile.position = inputFile.position + 4;
let name = inputFile.readString16(true);//script field re-purposed as a ref
layers[layer] = {
poly : new Polygon(1, x1, x2, x2 - x1, y2 - y1),
steps : steps,
name : name
};
}

if(inputFile.readStringRaw(4) !== ".rts")
{
throw new Error("Tile signiture not found either .rmp file is corrupt/out of date or there's an error in the reader script");
}
inputFile.position = inputFile.position + 2;//skip version number - always 1
let numTiles = inputFile.readUint16(true);
let tileWidth = inputFile.readUint16(true);
let tileHeight = inputFile.readUint16(true);
let tileSize = tileWidth * tileHeight;

inputFile.position = inputFile.position + 244;//skip 3 reserved bytes then 1 byte "has_obstructions" then 240 reserved bytes
//has_obstructions is aassumed to always be true

//load rawTile data 3rd key Output
let tileData = inputFile.read(numTiles * tileWidth * tileHeight * 4);

//load and process tile properties 4th key output
let tiles = new Array(numTiles);
for(let i = 0; i < numTiles; ++i)
{
inputFile.position = inputFile.position + 1;//skip 1 reserved byte
let animated = inputFile.readUint8();
let nextTile = inputFile.readUint16(true);
let delay = inputFile.readUint16(true);
inputFile.position = inputFile.position + 1;//skip 1 reserved byte
let obsType = inputFile.readUint8();
let numSegments = inputFile.readUint16(true);
let nameLength = inputFile.readUint16(true);
inputFile.position = inputFile.position + 20;//skip 20 reserved bytes

let tileName = inputFile.readStringRaw(nameLength);

let tileObs = [];
if(obsType == 1)
{
for(let j = 0; j < tileSize; ++j)
{
if(inputFile.readUint8() === 1)
{
tileObs.push(new Polygon(1, j % tileWidth, Math.floor(j / tileHeight), 1, 1));
}
}
}
else
{
for(let j = 0; j < numSegments; ++j)
{
let x1 = inputFile.readUint16(true);
let y1 = inputFile.readUint16(true);
let x2 = inputFile.readUint16(true);
let y2 = inputFile.readUint16(true);

let x_ = Math.min(x1, x2);
let y_ = Math.min(y1, y2);


tileObs.push(new Polygon(1, x_, y_,
Math.abs(x1 - x2),
Math.abs(y1 - y2)));
}
}
tiles[i] =
{
name     : tileName,
animated : animated,
nextTile : nextTile,
delay    : delay,
obs      : tileObs
};
}

return {
width      : width,
height     : height,
repeating  : repeating,
layers     : layers,
mapStrings : mapStrings,
entities   : entities,
numTiles   : numTiles,
tileWidth  : tileWidth,
tileHeight : tileHeight,
tileData   : tileData,
tiles      : tiles
};
}

class Polygon
{
constructor(type, x, y, w, h)
{
this.type = type;
this.x    = x;
this.y    = y;
this.w    = w;
this.h    = h;
}
}
40
Sphere General / Re: Promoting Sphere?
Focus on minisphere, make sure there's really only 1 sphere to work with and make it blatantly clear that 1.5x is legacy and not supported for future development.

That's what I keep telling people, but they insist on writing new code against the Sphere v1 API anyway.  I guess it doesn't help that most of our active members are still old-timers and there's no Sphere v2 map engine yet (though @Rhuan is slowly working on one).  The classic map engine just isn't conducive to writing idiomatic Sphere v2 code, and the divide has widened even further with ES6 being supported in the beta.
I think the absence of a v2 map engine is a pretty major issue, I'm trying to fix that but getting it right is taking time (plus I was away for almost a month since starting it which delayed me quite a bit).

Also the v2 API still feels a little new/untested, it's not a stable 100% there definitely good to go platform yet, it's getting there and when it's finalised it will be great just needs a little bit longer IMO.

Still think a rpg template would go a long way in bringing in people, use xp stuff "everybody does..." just put a disclaimer for assets use *can not be used for commercial projects.   I'm also thinking about moving my rpg project from unity I was going to use RPG Maker MV only because I could do entire 5hr story arks in a month or 2, Dragon Ball currently has 10 so the game would be around 50hrs "the Future trunks ark is going to be 10+ only because I love Black <3"  So imagine doing a project like that in Unity especially with how scenes are organized... even tho I have most of my Zelda kit done it was quite a pain in unity "especially the room transitions...". 
I'd love to make a full RPG template - just taking a while on the map engine; I have a full time job and other things in my life + recently have just been writing too much code both in and outside of work, been making my brain spin and I've had to slow down/do simpler stuff.

So you've got a project you're thinking of moving from unity? What do we need to do to persuade you to bring it to miniSphere?
41
Game Development / Re: The Screenshot Thread
Did you use SSj or SSj Blue to help you develop that?  Because that would be incredibly appropriate.  :P

The funny thing is, I probably don't even know how to use those to their full potential! I'm like an RPG Maker creator who stumbled upon Sphere by mistake. My code for this project is one big mess at this moment but somehow I manage to make things work. :P
I'd love to help you re-code it if you're interested?

But not until my map engine is done - so not for at least a few weeks.
42
Game Development / Re: The Screenshot Thread
Can I post a video?
I'm gonna post a video.
Using a screenshot.
Wow, this is some good work.
43
Projects / Re: Project ZeC (My Zelda-esque Clone)
I'm going to attempt to port the project maps to use the persist functionality. At over 400 maps this could take some time. I think the levels will be the most time consuming to port over.
I could pull all the scripts out with a script I have if you want me too... Let me know if you want the help.
44
Projects / Re: Project ZeC (My Zelda-esque Clone)
You have to have a comma after each function definition in the map script (other than the last one), like in the attached.
45
Projects / Re: Project ZeC (My Zelda-esque Clone)
Can you post the map script you're using?

The line 403 error is persist.js forcing an error as it can't run the code from the map script you've given it. (It has internal error handling designed to give you more sensible error messages)