I will make an entire report on what I noticed about construct 2 current build when I used it to create MoonShield for the c2 contest
But First who the f*ck am I?
I'm just a french guy freshly out of artschool who used multimedia fusion and construct classic quite a lot for almost 2 years (only 10 months on construct) (I did some project you can see and test on http://yanngranjon.com/games/)
I think construct 2 will be one of the best game creator available right now (once perf issues will be erased from html5 browser support). Still, my report will cover some issues I encountered and some concept I believe might be interesting to consider.
I don't expect all that I will write to become reality of course, but well, there could be some nice idea.
So here I go
In my opinion, there are 3 important points that game maker software should look for :
- enhancing code readability : being able to reopen an old capx and quickly understanding what it does, working on big complex capx project between team members with minimum time on decrypting what the other did...
- enhancing modularity : being able to work on a project as a team as well as alone. Games are more often made by teams than by lone crazy monster like konjak or nifflas. So we should be able to write some piece of logic algo and quickly (copy/paste ?) integrate it into the main project without logic bug.
- still keep it SIMPLE! That is its better quality.
So first READABILITY :
c2 achieves that very well, you can make comments, group parts of game logic, sort these parts into included event sheets to easily reuse some part of your engine.
Also, I love the fact that you can take a tab and put it away and see the event sheet And a layout at the same time.
And I love the search feature (could be a whole project search maybe? and a search and replace too maybe?)
Still, I have three ideas to increase readability even more and help creating more organized and usable project.
1/ inline comment on global/local variable creation
instead of alterning comments and variable definition
you could have something like that
It mimics the way some comments variables in scripted codes
int myVar; //this variable does that[/code:1l15ke80]
And can make capx easier to understand when they are cluttered by so many unrelated global variables.
[img="https://app.box.com/representation/file_version_18379861793/image_2048_jpg/1.jpg?shared_name=fn8fbozksngw1hgfymib"]
[img="https://app.box.com/representation/file_version_18379862143/image_2048_jpg/1.jpg?shared_name=vcv6mlq8r99ia8194c1h"]
2/ syntax coloration.
We could select a whole bunch of code and set the background to a color, or tell the content of a group to display a given color. this way even when going through tones of events you can still know in which group you are :
[img="https://app.box.com/representation/file_version_18379859869/image_2048_jpg/1.jpg?shared_name=z5ih64ejnom6iumekesn"]
You could also have some highlighting feature to more or less make some important parts stand out more or visually associating some events.
3/ enhanced library
I think the library should evolve a bit. I'm thinking of very simple feature like : knowing if an object is used or not in an event sheet or layout. It could be done with simple color code or icons.
[img="https://app.box.com/representation/file_version_18379877247/image_2048_jpg/1.jpg?shared_name=xbace0w0hw17pbzvtxf9"]
And by right clicking an object in the library you should have information to locate them in layout and/or event sheets.
[img="https://app.box.com/representation/file_version_18379874811/image_2048_jpg/1.jpg?shared_name=a2o8s044rkane3vb2r6j"]
[img="https://app.box.com/representation/file_version_18379876585/image_2048_jpg/1.jpg?shared_name=9jb9906ufqeq56nbce0s"]
Since now deleting an object in a layout doesn't delete it from the library (which is a great, very great idea, it IS a real library of objects now) the library can become a mess pretty fast.
You could also have a dangerous cleaning feature that erase all stuff that aren't used at all.
Also for readability (but I believe you have that in your roadmap) the folder organisation in the library should appear in the ACE windows. with collapsing sections.
Now MODULARITY :
What I did in MoonShield, was building a simple level. And when I worked out all the basic mecanics, I planned to simply put all these mecanisms in an event sheet and include it in other levels with alternate gamplay (but didn't have time to do that for the contest <img src="{SMILIES_PATH}/icon_e_sad.gif" alt=":(" title="Sad"> )
[img="https://app.box.com/representation/file_version_18379855979/image_2048_jpg/1.jpg?shared_name=c5zori7wmsaouo3idows"]
Here two major problems arised :
1/ Global variable unique initialisation
As construct classic uses global variables the same way, I anticipated this one. The very nature of global variable is that if you have a layout that should restart (like "you lose" -> restart), you WILL have to reset all global variables by hand, making redundant annoying code like that :
[img="https://app.box.com/representation/file_version_18379867359/image_2048_jpg/1.jpg?shared_name=nhu29f1yfs2xdeyplqvm"]
Unfortunately, local variable won't do for that kind of situation, because they are just temporary variable that can't evolve during the game because they get reset each game loop. Which make them an awesome tool to increase readability because you will have a code like that :
[img="https://app.box.com/representation/file_version_18379881107/image_2048_jpg/1.jpg?shared_name=49xnbfju20n2dh3rhddo"]
Instead of having a big hard to read expression. And also as there are local, the global variable combobox will not be cluttered by them.
I have two solution for this problem (which are more or less the same) :
[ul]
[li]global variable should have a property to make them travel between layout or not[/li]
[/ul]or
[ul]
[li]having a third type of variable "layout variable" that gets reset on start of layout. You can also have the same variable name for other layout (increase readability)[/li]
[/ul]
This way you can have your layout parameter set at the beginning of the event sheet, OR a bunch of variable in an included eventSheet that will create and reset the variable you want for each layout.
This way you avoid redundance and conflict. Keeping true global variables for just the data that should travel.
[img="https://app.box.com/representation/file_version_18379869965/image_2048_jpg/1.jpg?shared_name=zzek4aqkby3t5mp8cdxw"]
Because, after all... There's not that much game that will need a whole bunch of travellable data (score?.. experience?... in rpg it's probably important yeah...)
Also, this way you really only have the variable that you need in the ACE windows (global+current Layout+current local variables), far less cluttering.
2/ Start of layout initialisation conflict
The second problem was unexpected and also pretty annoying. c2 doesn't care where I include an event sheet, he will first call the start of layout code of the included event sheet and then those from the parent event sheet. This structure makes difficult gameplay variation on a same base mecanics.
[img="https://app.box.com/representation/file_version_18379867203/image_2048_jpg/1.jpg?shared_name=r8p97kpxr1yfwgk07a2m"]
In MoonShield, I had to take all start of layout events out of the included event sheet and duplicate most of them in the "parents" of each level.
I think included code should be read in order of its call in the parent event sheet. So if I put start of layout before an include, it should be evaluated before. If I put it after, it should be evaluated after.
I think it's an expected behavior.
3/Other ideas
Other than these two problems, a duplicate layout feature can be interesting. Let say I have a game with asteroids to deviate in order to protect a planet. Now I want another level where I still have to protect my planet, but have to create another one by aggregating asteroids. I'll gladly start from the first layout, adding the new planet and some piece of code to change default positionning and add the newEarth logic.
Also, the ability to merge construct projects. Let say I work with an awesome guy who is really great in UI programming (with c2) and I prefer to code a collapsing black hole ('cause it more fun right?). It would be great that :
- my buddy do his thing on a layer named HUD with his objects and his code properly isolated in a standalone event sheet (included in the layout event sheet)
- I do my part on a layer named GAME with my objects and my code the same way
Every thing works for me and for him
We all worked on the same Layout named "Level1" which has the event sheet "eLevel1"
We merge the two capx, c2 recognize the same layout name, merge all the object/layer/event Sheet in one layout with his layer on top of mines, his event sheet next to mines, and his objects added in the library, with an autorenaming feature (library & eventSheet) in case duplicated names appear. And then we're done! His HUD on top of my game without breaking any sweat
And if he wanted to use some of my objects, we could select the same object that has been renamed during the merging and right click "replace by existing object", after a little check (same instance variable/behavior/effect), the renamed object is deleted and in the eventSheet it is replaced by the proper one.
Or maybe the autorenaming feature during the merging could prompt some stuff to ask if it should autrename or merge the objects (creating the variables/behaviors that doesn't already exists)
For the last part, Keeping Things simple
C2 pretty much ace that already.
I have just a little ideas I already talked about it to ash actually.
default values.
The idea is that each paremeter global/local/instance variables, position, rotation, size, opacity,... have a default value set in parameters. But I think these default should be stored by c2 and retrivable. this way you could do something like
[code:1l15ke80]healthbar set Width to : default(healthbar.Width) * Player.life/default(Player.life)[/code:1l15ke80]
You could, along with that have a setDefault() function to change these values. Imagine if the player's max life increase, you will just have to do a
[code:1l15ke80]setDefault(Player.life,default(Player.life)+10)[/code:1l15ke80]
it's really simpler than creating variable to store these default values (and unreal dev kit does that)
Now for some bug and annoying stuff I encountered :
- a freezing bug : [url=https://app.box.com/s/o2tlph5xzxvy78vyflac]BUG-PhysicFreeze.capx[/url]
- when do a sequence of png, I importe it in animFrame with the import animFrame feature, and I try to modify these png afterward, I can't overwrite them 'cause they are "left open"
- sometimes I have to close and reboot c2 before an export to hear the sound
- we already talked about that but I write it to be complete, the size of an image is update after the frame is drawn, so you can't have the size of an animFrame at the same time you change it. It can be annoying for when you have to setup stuffs with loops.
- the find function isn't case sensitive. I can see that it can be usefull, but it would be great to have either two find function or another argument to set it case sensitive or not.
- there's no LayoutName expression to get the current name of the layout otherwise, I would have been able to overcome the include conflict by checking this value.
Annnnd that's all (:
I hope I've been clear enough and that some ideas are interesting. And that Ash will read this and give me his opinion.Yann2011-10-28 14:48:13