News:

As a consequence of the forum being updated and repaired, the chatbox has been lost.
However, you can still come say hi on our Discord server!

Main Menu

Open Golden Sun: Open source recreation of the Golden Sun engine

Started by OpenGoldenSun, 15, December, 2014, 11:46:04 AM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

Rolina

Do you have battle examples up yet?  I'd like to see the effect of the screen smoothing there, since the art style is a bit different.

Edit:  Also, been meaning to ask this.  For those of us who wish to add additional statistical values to the games, will we be able to increase the screen size to compensate for the larger menus we'll have to do (to, say, the resolution on a single screen of the DS for instance), or are you committed to the whole VBA-only thing?  Would you have a solution in place in such an instance, perhaps to allow for some menu scrolling so that we can get all the data to the player?

OpenGoldenSun

Quote from: Rolina on 12, January, 2015, 08:53:57 PM
Do you have battle examples up yet?  I'd like to see the effect of the screen smoothing there, since the art style is a bit different.

Edit:  Also, been meaning to ask this.  For those of us who wish to add additional statistical values to the games, will we be able to increase the screen size to compensate for the larger menus we'll have to do (to, say, the resolution on a single screen of the DS for instance), or are you committed to the whole VBA-only thing?  Would you have a solution in place in such an instance, perhaps to allow for some menu scrolling so that we can get all the data to the player?

I'll be posting a video for the battle system hopefully within the next couple weeks.

For your second set of questions, here is what the engine looks like when it's run at an internal game resolution of 256x192 (Nintendo DS):

 

As you can see the menus are larger than normal. Also, you can see more of the map in the second image.

Essentially I can adjust the internal game resolution to whatever I want. Which basically will just show more map, and make more dead space in the menus.


MaxiPower


Rolina

Quote from: OpenGoldenSun on 12, January, 2015, 10:44:29 PM
Quote from: Rolina on 12, January, 2015, 08:53:57 PM
Do you have battle examples up yet?  I'd like to see the effect of the screen smoothing there, since the art style is a bit different.

Edit:  Also, been meaning to ask this.  For those of us who wish to add additional statistical values to the games, will we be able to increase the screen size to compensate for the larger menus we'll have to do (to, say, the resolution on a single screen of the DS for instance), or are you committed to the whole VBA-only thing?  Would you have a solution in place in such an instance, perhaps to allow for some menu scrolling so that we can get all the data to the player?

I'll be posting a video for the battle system hopefully within the next couple weeks.

For your second set of questions, here is what the engine looks like when it's run at an internal game resolution of 256x192 (Nintendo DS):

 

As you can see the menus are larger than normal. Also, you can see more of the map in the second image.

Essentially I can adjust the internal game resolution to whatever I want. Which basically will just show more map, and make more dead space in the menus.

Awesome!  Thanks!  Being able to to generate more space is good for when we run out. 

jjppof

Maybe put a limit on it, could be interesting... some game engines calculate a scale factor based on the stage and viewport width and apply it in the sprites size.

----------------

Looking at that Atrius gif, it seems that Y position of the heroes don't change. The sprite texture and hierarchy change with X variation. The X speed variation at this animation seems to be cos/sinusoidal with zeros near the borders and peaks at the center. But I don't know about your resources, but I think that an easeInOut animation can substitute the cos/sin functions once you call it everytime you need to vary X.

Atrius (He/Him)

Th Y values change.  There's a lot going on there that may not be immediately obvious.

I've remembered more of how I programmed that.

The character's X and Y coordinates are completely different from the X and Y coordinates where their sprites are drawn on screen.  I'll call the sprite coordinates spriteX and spriteY.  As the camera rotates I don't change the values of X and Y, spriteX and spriteY get recalculated based on the camera's new position.  X and Y are located on a plane that extends into the screen, basically they're a location on the ground as it is visible on screen where 0, 0 is at the center.

To calculate spriteX and spriteY you need to perform a rotation on X and Y so:
spriteX = X  * cos(-cameraAngle) - Y * sin(-cameraAngle)
spriteY = Y * cos(-cameraAngle) + X * sin(-cameraAngle)

That's not all though, now spriteX and spriteY need to be translated to screen coordinates.  This also includese scaling the sprite based on spriteY which currently represents how far forward or back they are on the ground, rather than how far up or down they are on the screen.  Unfortunately this is where I have trouble remembering the specifics again, I think some of it was based on math from a raycasting engine...  In the end the fact is you'll be doing a simplified 3D to 2D coordinate conversion, hence raycasting engine math.


Remember, Golden Sun uses a 3D coordinate system for movement in towns/dungeons.  I doubt they took an easier route than what I've described to fake the battles which almost actually look 3D.
[sprite=220,4,0]I'm shaking my head in general disapproval of everything[/sprite]

jjppof

Ok, I don't know how golden sun engine works. But this scene can be made in 2D using resources like scale, hierarchy, sprites texture change and xy coordinates. The effect will be the same and, maybe, done in an easier way. Depending how his engine treats the texture atlas, he only has to concern about the 'real' xy position of the char on the screen making animations become easier to be made.

--------- edit

To make this scene, you had to adapt to the golden sun base engine, but I don't think that's the way the programmers took. Perhaps they used a framework.

Atrius (He/Him)

The end result was made in 2D using resources like scale, hierarchy, sprites, and xy coordinates.  The complexity of the math is so that you can change some of the variables and it will still behave correctly.

If you use the real math behind the effect you want, and make it so all you have to do is move the camera and everything else behaves correctly it's a lot easier to create hundreds of attacks that can move the camera in different ways.

If you fake the math, it probably won't behave correctly and you may have to fake it a hundred different ways to make your hundred different attacks look right.


--edit--

I should also mention that the math may sound complex, but it ended up being less than a dozen lines of code to calculate the screen xy coordinates and scale of a single sprite.  It wasn't particularly hard on the processor either, each individual particle from the magic effect in the image I posted had to go through the same algorithm.  (Though, I think the real Golden Sun's particles were strictly 2D calculations)
[sprite=220,4,0]I'm shaking my head in general disapproval of everything[/sprite]

jjppof

Actually, with 2d calcs, you won't need to do hundreds of attacks since you create a standard, so you can pass just few parameters (or only the type of attack... physical, summon, psy... then the algorithm does the animation). That's how recent 2D engines do these things, like starling and cocos2d. They are told 'easy to use' cause they treat things in this way.

I know this math isn't complex, but once you can avoid, why not? And I don't think this is fake math, It's just another way to deal with this.

Of course, this things I'm talking is only possible if his engine gives support to it.

Daddy Poi's Oily Gorillas

Um... Would it be worth having both methods?

I could see it useful for educational purposes, and so that people have more choices. (Including even altering the formula itself.) :)  (Assuming it's not as hard as it sounds, and the method differs enough for it to be worth considering.)

One version could be Golden Sun Original Method, the other version could be "WIP" whatever you want it to be.

---
QuoteTo calculate spriteX and spriteY you need to perform a rotation on X and Y so:
spriteX = X  * cos(-cameraAngle) - Y * sin(-cameraAngle)
spriteY = Y * cos(-cameraAngle) + X * sin(-cameraAngle)
I remember seeing two angle values in RAM.... But you make it sound like there's just one?
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

jjppof

A suggestion would be use the Tiled Map Editor http://www.mapeditor.org/, or something like it. It's very simple to use and exports files like JSON, CSV, XML etc, that you can adapt your engine to use.

I searched at google images 'golden sun tileset', got this http://img.photobucket.com/albums/v48/psgels/psgels-Ruins-Exterior-01.png, set white as transparent color and easily made the image below.It will be very nice to build maps. And It's free! An example of JSON file is also attached.

Luna_blade

"Hear the sounds and melodies
Of rilets flowing down
They're the verlasting songs
Whispering all the time
As a warning that behind some rocks
There's a rigid grap even
Oreads fear the tread"

OpenGoldenSun




MaxiPower


Luna_blade

That's a good start. It's also nice to see progress again.
"Hear the sounds and melodies
Of rilets flowing down
They're the verlasting songs
Whispering all the time
As a warning that behind some rocks
There's a rigid grap even
Oreads fear the tread"

OpenGoldenSun

Quote from: Atrius on 14, January, 2015, 07:30:08 PM
Th Y values change.  There's a lot going on there that may not be immediately obvious.

I've remembered more of how I programmed that.

The character's X and Y coordinates are completely different from the X and Y coordinates where their sprites are drawn on screen.  I'll call the sprite coordinates spriteX and spriteY.  As the camera rotates I don't change the values of X and Y, spriteX and spriteY get recalculated based on the camera's new position.  X and Y are located on a plane that extends into the screen, basically they're a location on the ground as it is visible on screen where 0, 0 is at the center.

To calculate spriteX and spriteY you need to perform a rotation on X and Y so:
spriteX = X  * cos(-cameraAngle) - Y * sin(-cameraAngle)
spriteY = Y * cos(-cameraAngle) + X * sin(-cameraAngle)

That's not all though, now spriteX and spriteY need to be translated to screen coordinates.  This also includese scaling the sprite based on spriteY which currently represents how far forward or back they are on the ground, rather than how far up or down they are on the screen.  Unfortunately this is where I have trouble remembering the specifics again, I think some of it was based on math from a raycasting engine...  In the end the fact is you'll be doing a simplified 3D to 2D coordinate conversion, hence raycasting engine math.


Remember, Golden Sun uses a 3D coordinate system for movement in towns/dungeons.  I doubt they took an easier route than what I've described to fake the battles which almost actually look 3D.

It would definitely be useful to see what you built for that.

Atrius (He/Him)

I responded to your PM, but I'll post it here too cause it's good information other people might want as well.


Quote from: OpenGoldenSun on 02, March, 2015, 10:42:34 PM
Hey Atrius,

When you have a chance, can you expand on this? Specifically how the sprites are positioned and how you are translating the recalculated coordinates back to screen coordinates?

Sorry I haven't been on in a while.

I'll go over it all, but I'm working it out in my head from what I can remember of the process so forgive me if I make any mistakes.

QuoteThe character's X and Y coordinates are completely different from the X and Y coordinates where their sprites are drawn on screen.  I'll call the sprite coordinates spriteX and spriteY.  As the camera rotates I don't change the values of X and Y, spriteX and spriteY get recalculated based on the camera's new position.  X and Y are located on a plane that extends into the screen, basically they're a location on the ground as it is visible on screen where 0, 0 is at the center.

Perhaps a better way to explain the X, and Y coordinates are that they're as though you were looking down on the battle from directly above it.   



QuoteTo calculate spriteX and spriteY you need to perform a rotation on X and Y so:
spriteX = X  * cos(-cameraAngle) - Y * sin(-cameraAngle)
spriteY = Y * cos(-cameraAngle) + X * sin(-cameraAngle)

That's not all though, now spriteX and spriteY need to be translated to screen coordinates.  This also includese scaling the sprite based on spriteY which currently represents how far forward or back they are on the ground, rather than how far up or down they are on the screen.

spriteX and spriteY still represent a top down view at this point, but it's been rotated so that the spriteY axis is the direction the camera is pointing, and the spriteX axis is perpendicular to it.  At this point you could use the spriteY values to sort your sprite drawing order.


Note that 0, 0 is still located at the center of the grid, this will be important later.


Now, for the next step it's important to know how perspective works.  There are two variables to consider when calculating how large the sprites should appear on screen: their distance from the camera, and the camera's field of view.  Since the camera, rather than just being a single point in space, can be considered a flat viewing plane parallel to the spriteX axis we can ignore spriteX when calculating distance to avoid weird fisheye distortion effects leaving us with just spriteY for the calculation.  The camera is NOT at the center of our coordinate system though so you'll have to use an offset to represent the camera's location on the spriteY axis. This offset is equal to the camera's distance from the center of the battlefield, so I'll call it "cameraDist"

distance = cameraDist - spriteY

Note that a negative distance value would mean the character is behind the camera, and should not be drawn at all.  On second thought, also include 0 in that.  So less than or equal to zero means they're not drawn, we wouldn't want to go dividing by zero later on.


Now, as for field of view and how it affects the scaling of the sprite on screen, it's all a matter of ratios.  Think of the field of view as a cone that extends out from the camera, the size of this cone increases at a fixed ratio (scaleRatio) as the distance increases.  The size a character appears to be on screen is proportional to the amount of that cone they fill, so their sprite's scale will be inverse to scaleRatio multiplied by their distance from the camera.

scale = defaultScale / (scaleRatio * distance)

When initialized defaultScale (normally 1) should be multiplied by (scaleRatio * cameraDist) replacing cameraDist with your camera's default/neutral distance if you want to make the camera distance variable.



scaleRatio is a fixed value as long as the Camera's field of view (cameraFOV) doesn't change.  If you take your field of view cone, and split it in half you get two lines with slopes of Sin(cameraFOV/2) so:

scaleRatio = 2 * Sin(cameraFOV/2)

You'll have to find a value you like for cameraFOV on your own, just make sure it's greater than zero and less than 180.  Around 60 would probably be a good starting point, and since it has a scaleRatio equal to 1 it would allow for more optimized code.



Now, this scale value isn't just the sprite scale, keep in mind that this is the scale of ALL measurements inside the camera's field of view at that distance.  Since our spriteX axis is parallel to the camera's viewing plane we can simply multiply spriteX by scale to get our on screen spriteX coordinate.  The camera is looking directly down what our spriteY axis currently is so it doesn't actually factor into our on screen spriteY coordinate at all.  So where do we get our on screen spriteY value?  Well, there's one axis left we haven't touched this entire time, the Z Axis!  Much like the spriteX axis, it's also parallel to the camera's viewing plane, albeit rotated 90 degrees around our current spriteY axis so a simple multiplication by scale will do for it as well.  If all of the characters are standing on the ground we can assume their Z coordinate is 0 which seems awfully boring, we'll have to move the camera up a bit by giving it it's own Z value (cameraZ, I don't know a good default value) to make things more interesting.  I don't know about you, but I like my positive Z values toward the sky, and negative Z's into the ground so that's how I'll arrange the calculation assuming screen coordinates are such that higher Y values are more toward the bottom of the screen.

spriteX = spriteX * scale
spriteY = (cameraZ - Z) * scale

I know I said these were the on screen coordinates, but there's still one little problem.  The 0,0 location hasn't moved from the center of the battlefield so add half of your screen's width to the x coordinate and half of it's height to the y coordinate to center the battlefield on screen.



Ideally sprites should be drawn in such a way that the spriteX, and spriteY coordinate we have now is at the center of the character's feet.
[sprite=220,4,0]I'm shaking my head in general disapproval of everything[/sprite]