1

(3 replies, posted in MODs)

I like the idea of getting the bricksets from the competition mode in Sonic 3 and making complete levels from them. I like both the Desert Palace and Endless Mine. And the Desert Palace at night is an awesome recolor!

It is good to see there is people making nice levels with Opèn Surge. smile

2

(7 replies, posted in MODs)

Since you are doing your stuff in 0.1.4, you can make the bosses simply as:

state "hit1"
{
    //move the boss doing its stuff
    //if receives a hit by Sonic, change to state hit2
}

state "hit2"
{
     //This function is exactly the same as hit1, but leads to hit3 when hitted
}

state "hit3"
{
    //Same as hit1 and hit2, but leads to hit4... and so on.
}

In the last hit, you simply destroy your object. However, for future projects, consider switching to 0.2.0. If you want to have Sonic & Co there, simply copy the Sonic sprites, as well as the files that define the images in 0.1.4 to the correspondent folder in 0.2.0. Tails and Knuckles will lose their skills, but you can find scripts here in the forum. Moreover, in 0.2.0 you can customize the characters with different stats such as jump height, speed, etc.

For boss stuff, in 0.2.0 you can use variables,  so making a boss becomes easier:

hits = 8 //Or whatever the syntax is for declaring variables, I don't remember now.
state "do_stuff"
{
      //here comes the stuff done by boss
     //If boss gets a hit, make hits = hits - 1
      //If hits = 0, then kill the boss
}

Sorry for the pseudoscripts, but last time I did stuff in Open Surge was a pair of years ago I remember nothing about the syntax. roll

3

(61 replies, posted in General)

G.E.R. wrote:

Is this script necessary for levels with a large map and a large number of objects?
I think It can be tested in a virtual machine with Windows 98 or 2000.

I don't think so. Open Surge runs well even in old computers, and once the map is loaded you should have no problem. It is more useful to test algorithms inside the new SurgeScript.

Alexandre wrote:

Advanced features
A very nice feature of object-oriented programming languages is called a functor (or function object). It allows you to have objects that behave like functions.

In SurgeScript, you can do really powerful programming using functors. In the example below, we have an object called Benchmark that can measure the performance of any code/object that you provide

Granted, it's an advanced feature.

Nice addition. My only criticism is that the functor has not a very clear syntax. At least for me it is diffiicult to understand, only reading the code, what is exactly the black magic behind it. In C++ for example the functor is done overloading (), which is way easier to understand. However, it may be matter to get used to it.

I see that the scripting is getting really complete. I think it is time to integrate it with the Open Surge engine to test it in the wild. I really want to get my hands dirty with it.

Happy new year to everybody, BTW.

4

(61 replies, posted in General)

I can see that the development of SurgeScript does not stop. The progress is awesome. Having such tool as the scripting engine inside Open Surge is going to make it really powerful.

When will be integrated?

5

(9 replies, posted in General)

So sad. I like a lot Jobro's composing style, and I have to say that it inspired me a bit when I was younger and I joined the forum. My kindest regards from here.

6

(61 replies, posted in General)

Alexandre wrote:

SurgeScript will work out-of-the-box. Simplicity for everyone!

That is music to my ears. Please keep us updated!

7

(61 replies, posted in General)

Alexandre, I have been checking SurgeScript and it looks AWESOME.

It really combines the power of a real programming language with the easy things of the state machine. In my opinion, it is a very good add-on for allowing the user to create content and scripting in a easy-yet-powerful way.

Cannot wait to see it working in Open Surge cool I only have one question. For now, if I want to use the language I have to compile it from the sources in GitHub. Is it going to be this way also for Open Surge?  Windows users could have a hard-time compiling it. I think the best thing would be to have everything compiled and ready for Windows users. I'm currently one of them, but not for a long time tongue

8

(61 replies, posted in General)

I am going to give you also my feedback in the things.

-- One of the biggest problems with the old API was the scope of variables. For example, I thought once to make a game with different routes. Also I tried to implement special stages/emerald collection. Though the first two can be done workarounding a lot with the load_level thing, I found no solution for the emeralds. I think there is no way to say to game, "Hey, write this variable, and KEEP IT, even when I quit the game and enter again".
In my opinion this is one of the easiest things to fix with an object-oriented engine. There should be an object dedicated to save/load permanent data, in a fashion of Android or other game engines. I don't know the new syntax but I imagine something like this:

object "end_level_sign"
{ 
       fun apply_end()  //Called when the player touches the sign
       {
                  IOhelper ioh();
                  ioh.write_var(int, "Rings", get_current_amount_rings()) 
                  //Creates a var, with name "Rings", of tipe integer, and we assign the number of rings to it.

                  float space_walked = ioh.read_var("Km") //Reads the value of the existing variable "Km"
                  //Edit the variable Km:
                  ioh.edit_var("Km", space_walked + get_km_walked_in_this_level() ); 

                  ioh.flush() //Write all data to savefile and closes it
       }
 
}

In this code you can see how I save, for later use, the number of rings at the end of the level. Also, you can see how can I get again the value of stored variable and edit it in memory. This allow me to keep track, in this particular example, on the amount of space travelled by the player... in the whole game!
There is a lot of possibilities to a complete save/load engine to store custom variables. Want to include non-linear level routes? No problem! RPG equipment and statistics? Easy to do!

Finally it would be good to do this not from scratch, but using something like XML, so we could, for example, store information of an object as sub-items of a big item, to maintein all the info organized.

-- KZR suggestion about editing variables of objects is very good in my opinion. I think that he is pointing out something like this:


object simple_enemy
{
    speed = 2.0;
    able_to_jump = true;
    hp = 3;
}

So now imagine you go to editor and create three of this objects. They, of course, are going to have the same characteristics. But you now can enter into "Properties mode" and when you click a guy, you can see the properties and edit them individually.

Of course, with this concept also privacy should be implemented, so public variables can be seen and edited in Properties Mode, but not private ones. If you want to modify a private variable of certain object, then it should be done in-code using getters/setters for safety.

-- About the thing of collision boxes, now they would be a private variable of every object, so you can modify it changing the value in the player object source file.  In addition to that, player characteristics should be properties of the player object, so they can be modified by objects, accesing the values in-code as I suggested. That can give us new exciting objects, such as a shoe that modifies your speed to a... Oh wait tongue Talking seriously, imagine objects that change for a time your jump height, the slope, the gravity (do you want to make that cool effect of reversing gravity?), or even that change the action triggered by the double jump.  New universe of possibilities!

-- Finally, as KZR also pointed out and as I have said in many topics, after finishing this GREAT new code the effort should focus in applications to deal with the creation of bricksets and sprites, as well as a level editor with enhanced capabilities. Putting all the blocks one by one is painful xD  Group creation should be even easier with the object concept, but still it is important to make easier level creation. And also the time needed to get bricksets and backgrounds working is horrible. Making this easy we would attract more people who simply wants to create their levels, and do not care about scripting new objects or items.

PS. Thanks for your message Alexandre. I hope to see new developments in this soon! Keep us up to date smile

9

(61 replies, posted in General)

Hey Alexandre,

It would be wonderful if you keep us up-to-date with the news of Surge Script. Do you have any idea of when will be it ready and integrated into Open Surge?

Also, I wonder what happens then with the Allegro 5/mobile stuff you were working on a while ago.

Thanks for the info!

10

(61 replies, posted in General)

Moving the repos to GitHub is a good idea. Maybe it is possible to find more coders able to add features to the game there.

Also, the Surge Script thing looks very promising. I want to see more of it soon!
I love the state-machine way for the objects, in my opinion is very intuitive for non-programmers. I hope the new script will be able to get the best of the SM concept with more general programming tools.

Also, a way to inter-change communication between levels would be nice.

11

(32 replies, posted in General)

Any updates? Lot of months since my last login here and there is nothing new relative to the development of OS hmm

12

(6 replies, posted in MODs)

Seeing the screenshots, looks like Tails' flotaing on the grass. I've had also this problem when I used a Green Hill brickset. See the discussion about zindex I had with Alexandre here: http://opensnc.sourceforge.net/forum/vi … php?id=349

13

(4 replies, posted in General)

Also there's  topics for this in the Game Assets section. You can find some Tails and Knuckles scripts there.

14

(19 replies, posted in General)

S32X wrote:

I've had two issues while using this program

1). When you save your work to a .brk file, any further changes you make and save don't get overwritten to the .brk file, even though if you make changes the program doesn't prompt you to save changes. I first saved it when I made brick 34 and then proceeded to make about 150 more bricks, and none of them got written to the file even though I did Ctrl+S multiple times, and I'm kind of pissed off by that.

2). Opening existing .brk files made with JBlocks doesn't do anything. (i.e., going to File>Open>example.brk closes the file window but doesn't load the brickset)


1). If I remember well, I haven't added ANY shortcuts to the app, so Ctrl+S currently does nothing. You have to File > Save any time you want to save.

2). Really? I'm sure I proved that feature carefully. I'll give another look to that, but I need some time to do it.

15

(15 replies, posted in Off-topic)

In my opinion the controls aren't the worst thing. The main difficulty with them is to adapt the control to the touchscreen, but the code is not a problem usually.

However, resultion IS a main problem on Android devices. On the computer, you can set the resulotion to fixed windows size and set the position of the objects absolute. But in Android you have a wide variety of screen resolutions: this forces you to work with relative pos and a well designed layout. 

Also, I think it will be neccesary a "OpenSurge Asset Repo" or something similar to download content directly from the phone/tablet. Managing folders can be a bit tedious, specially from mobile.

I can't wait to see the changes...! tongue

PS. Glad to see SilverstepP again n.n

16

(0 replies, posted in Game assets)

I've found an interesting page with lots of ripped soundfonts from games, and also imitating system, like the Megadrive (which played music in a different way).

You can find it here.

This SFs can be useful to make Open Surge music. You also can try to download Sonic MIDIs and then play with this SF to make them more "real".
Hope you enjoy the material. big_smile

17

(6 replies, posted in Game assets)

I have proved it and it works perfect for me in 0.2.0.

The problem, if you look at the API reference, is this:

add_lives
Syntax: add_lives number_of_lives
Available since: 0.2.0
Adds number_of_lives to the number of lives of the player. number_of_lives may be positive or not.

You cannot add_lives in 0.1.4.  So in that version you cannot do the "invisible life box" since you cannot add lives to the player. Port your content to the 0.2.0 and everything will work fine.

18

(6 replies, posted in Game assets)

First of all, you should change to new 0.2.0 version, which is more flexible big_smile This is not going to be a problem with this object, but it has a lot of possibilities.

Second, this object I've written has nothing to do with the built-in item (this cannot be modified). This is a NEW custom object. And my code could have an error (as I've said, I've written it without checking). 
Read the code carefully and make sure you understand it. What I do is to create a new object. In the main state, I assign a sprite to the object (you might want to use the item box graphics to make sure it has the same size). After that, I change the state to a wait. The object will be in this state until is attacked (this is, jumped on or spindashed) by the player. If this happens, the state changes again. The "add_lives" command increases the life in 1, and then the object is destroyed so it's not usable anymore.
The "hidden_unless_in_editor_mode" makes the object invisible.

So this is not a life box. It is a custom object that acts like a life box, but it's invisible. And it has nothing to do with the built-in life box.

This code is really, really simple. If don't catch it, try to play more time with the API, the case studies until you're familiar with the scripting. Some things need time smile Once you catch it, you'll realize this is easy.
And feel free to ask any doubts.

PS. If you want to make it work in 0.1.4, change the "requires 0.2.0" to "requires 0.1.4". Also be sure that every script command you're using works in 0.1.4. In practice, you should change, as I've said, to 0.2.0.  You can port all yours 0.1.4 scripts to 0.2.0 simply by copy-paste. Same with Sonic sprites and other stuff

19

(6 replies, posted in Game assets)

If I remember well, "hide" won't affect other events so you can use it as usual. For your example, I would do something like

object "extra_life"
{
        requires 0.2.0
        hide_unless_in_editor_mode

        state "main"
        {
                  set_animation "BOX_ANIMATION" //Necessary to stablish object's size. 
                  change_state "wait"
        }

         state "wait"
         {
                  on_player_attack "one_up"
         }

         state "one_up"
         {
                   add_lives "1"
                   destroy
         }
}

I have written up this code now, I haven't proved it. However it should work. Note that I've used "hide_unless_in_object_editor" instead of "hide". This is the same as hide, but if you want a permanent invisible object, this allows you to see them in the level editor, even if the sprite is also transparent.
You should use hide/show when you don't want a permanent invisibility, in my opinion.

20

(6 replies, posted in General)

Added in the Game Assets forum the files I've used to do that. I think that if the special quests have more than one level it also works, but I've not checked it.

As I have said, the files are useless to load a new quest in the middle of a level and then go back to it, but you can open a quest between two levels in a quest A, play the quest B , close the quest B and continue in the next level of quest A. big_smile

21

(2 replies, posted in Game assets)

This objects allows you to implement a special stage in your games. If you finish the level with 50 or more rings, it will load a special stage. It's neccesary to create a "special stage object" for every special stage.


- Level config

//Object for special stage 1
object ".1tspecial"
{
    requires 0.2.0
    always_active
    state "main"
    {
        let "$_special = 1"
    }
}

//Object for special stage 2
object ".2tspecial"
{
    requires 0.2.0
    always_active
    state "main"
    {
        let "$_special = 2"
    }
}

//Object for special stage 3
object ".3tspecial"
{
    requires 0.2.0
    always_active
    state "main"
    {
        let "$_special = 3"
    }
}

//ADD MORE IF YOU NEED

//Launcher
object "special_launcher"
{
    requires 0.2.0
    always_active

        //Check which special will launch
    state "main"
    {
        if "$_special == 1" "t1"
        if "$_special == 2" "t2"
        if "$_special == 3" "t3"
                //ADD MORE IF YOU NEED
    }

        //Launchers for every level
    state "t1"
    {
        push_quest "quests/special_stage_t1.qst"
        change_state "finish"
    }
    
    state "t2"
    {
        push_quest "quests/special_stage_t2.qst"
        change_state "finish"
    }

    state "t3"
    {
        push_quest "quests/special_stage_t3.qst"
        change_state "finish"
    }

       //ADD MORE IF YOU NEED

    state "finish"
    {
        destroy
    }
}    

-- Level launcher:

object "special_state_launcher"
{
    requires 0.2.0
    hide_unless_in_editor_mode
    category "CustomCont"

    state "main"
    {
        set_animation "SD_RING" 0
        on_level_cleared "launch"
        let "$_globalVar=112"
    }
        
    state "launch"
    {
        if "collectibles() >= 50" "wait"
        change_state "finish"
    }

    state "wait"
    {
         show_dialog_box "<color=00ff00>+50 RINGS!</color>" "GET READY FOR <color=ff0000>SPECIAL STAGE! </color> (Please don't press ENTER...)"
        on_timeout 8 "push"
    }

    state "push"
    {
        add_lives "200"
        create_child "special_launcher"
        change_state "finish"
    }

    state "finish"
    {
        destroy
    }

}

Finally we need an object to jump and go to the next level of the quest, because if we simply pop_quest, we will start again the same level. That's why I added the strange condition "add 200 lives". See:

-- Jumper:

object ".go_special"
{
    requires 0.2.0
    always_active

    state "main"
    {
        hide
       if "lives() >= 200" "next_level"
        destroy
    }

    state "next_level"
    {
        add_lives  "-200"
        next_level
    }
}

If you start a level with 200 lives of more, it means you come from a special level, and that means that the player has completed already the level the game is going to load, so we skip it -and load the next level.

The special stage should contain a object which pop_quest at the end. For example, here's an special stage where the player has to get 100 rings to win:

object "extra1_stage"
{
    requires 0.2.0
    hide_unless_in_editor_mode
    always_active
    category "special_stage"

    state "main"
    {
        set_animation "SD_RING" 0
        if "collectibles() >= 100" "win"
        on_level_cleared "lose"
        on_player_death "lose"
    }
        

    state "win"
    {
        disable_player_movement
                //The dialog creator shows a dialogbox depending on which stage we are. Not neccesary for your game :D
        create_child "dialog_creator" 
        on_timeout 4.5 "pop"
    }

    state "lose"
    {
        disable_player_movement
         show_dialog_box "<color=ff0000>FAILED!</color>" "Try again!(Please don't press ENTER...)"
        on_timeout 2.5 "pop"
    }
    

    state "pop"
    {
        pop_quest 
        change_state "finish"
    }

    state "finish"
    {
        enable_player_movement
        destroy
    }

}

The startup of your special level should be

startup ".default_startup" "extra1_stage"

and the NORMAL level has to be

startup ".go_special" ".1tspecial" ".default_startup" 

.

And that's all smile

22

(6 replies, posted in General)

I scripted a workaround to support special stages and then return to the original quest. I wrote it some time ago and it works well. After finish a level, if you have more than 50 rings, it loads the specified level. After completing the level it will return to the quest and load the next level.

The only thing is, if the player press the button to skip the score animation before the special level loads, it will go to the next quest level without loading the special one. I added a textbox saying "Going to special stage! (Please don't press ENTER)", but that's all.
I'm sure you can do something my object to get your quest. I will upload it  to the MOD section tomorrow. smile

Edit: take in account that this works well in the end of the level. Of course I could load the special stage in the middle of a level, but I won't be able to return to that state in the level. I have to start the level again or load the next quest level.

23

(15 replies, posted in Off-topic)

People visits this not so often. The development is going veery slow now.

We need MARKETING. Looks like nobody knows this. There's not a lot of forum members and we really need people doing fun things here to attract more people.

24

(11 replies, posted in General)

KZR wrote:

play the music track as a sound effect. in theory, you can even program a basic sequencer inside the engine through scripting only.

If you make a big vertical object that moves right, and several other objects that play a sound effect when they collide with the big one, you can build levels that are actually songs smile

Well, the idea of sound effects is good, but you cannot synchronize the music with them. I mean, the sound effect will always start playing at the beginning. But the background song could be playing anyware, so they won't play synchronized.

So I think you cannot do the multi-layered music using sound effects.

Of course, the musical level is a real possibility smile And the sequencer idea is pretty funny.

25

(11 replies, posted in General)

I've just realized that this cannot be done with current music engine in OpenSurge.

Simply read the docs about the "play_music" command:

Plays the specified music.Only one music can be played at a time. You need to change the state of the object (or destroy it) after you call this command, otherwise the engine will try to play your music at each cycle, causing weird results.

Something has to be changed in the source code. I think that we could change music syntax to make it more flexible:

- 1. In the description of the level, in "music" we should be able to select more than one song. The engine would load all the songs into memory, in a music array. Each song would have its properties, like loop and volume.

- 2. The command set_volume volume would be modified to

set_volume "song_from_preloaded" volume

To assign the value of each song separately. Also a set_loop would be neccesary to set the number of loops of each song.

- 3. Next, modify play_music "song_name_from_musics_folder" to

play_music "song_1", "song_2", "song_3" ..., transition_time, time_to_start

or even

play_music "song_1", "song_2", "song_3" ..., transition_time, time_to_start_song1, time_to_start_song2, ...

Where "song_j" is the name of a pre-loaded song in (1.) and transition time is the fade in/out time. All the songs selected will play simultaneously. Time to start is at which time the songs start playing.

- 4. Finally, a function

getSongCurrentTime("song")

would give the current time of the song. Note that the argument is neccesary because you may have multiple songs playing.

With this new archictecture, the application to our multi-layered music is trivial. In the level config, apply (1.) and pre-load, let's say, 5 songs, called "musics/s1.ogg", "musics/s2.ogg",  ... "musics/s5.ogg".

Then, create an object and set the volume/loops of each song, for example,

set_volume "musics/s3.ogg" 0.6
set_loops "musics/s1.ogg" -1

After that, simply call the songs you want to play with play_music. Suposse we're playing "s1" and then we do

play_music "musics/s2.ogg" "musics/s3.ogg" 1.2 0.0

This would make a fade out of "s1" and then a fade in of "s2" and "s3", in 1.2 seconds. The songs would start playing at the beginning, 0.0.
Then imagine that "s1" ... "s5" are different tracks of the same song, which I want to play in different layers. Then if "s1" is the base music playing, I can do:

play_music "musics/s1.ogg" "musics/s4.ogg" 0.0 getSongCurrentTime("musics/s1.ogg")

That would make the transition without fading (so you the music won't go off and then on), and will continue playing from the time is currently playing. Since all the songs are different tracks, you'll have no syncrhonization problems with the getSongCurrentTime function.

A problem with this could be that you may try to play a 1 minute song starting from second 76, for example. To fix this, I would simply start playing at current_time MOD song_duration. This also could help to minimize the total memory required to do the layers. If "s1" has 40 bars, and "s2" 20 bars, using this trick "s2" will play 2 times every time we have played "s1".
This, combined with the command mentioned in (2.), the set_loops, could be very fancy. Songs would stop simply after certain loops, defined manually.