Any tips for working on large projects?

Not favoritedFavorited Favorited 1 favourites
From the Asset Store
_______ Huge collection of metal fixtures ________
  • citron2010 alastair gave a good explanation of why people use a global sprite for storing variables. There's also an addon for that purpose.

    As for JSON, I use it to store values that are needed rarely. For example, I might add a key like 'MenuNotificationShown' to JSON. There's no point in creating a separate variable for this since I only access it once in the project.

    It's also easy to save all these values at once in Local Storage - just use Sprite.AsJSON and JSON.ToCompactString

  • The camera does not use asynchronous events, we run Tween, it changes the zoom variable, which is also affected by other actors.

    In my particular case, the camera is complicated by the fact that one layout can have several separated locations with cameras and they are logically limited by additional variables. This makes the work somewhat inconvenient, but sometimes it is useful. For example, if you need to quickly teleport through a maze of mini-locations.

  • > For cutscenes and game events I ended up writing a camera with 23 active parameters - zoom and movement via tween or lerp with various curves, optional input blocking and types of hero tracking and forced scrolling. This saves a lot of time now.

    envoys: Can you describe your cutscene camera a little bit? The story I want to tell is pretty visual with lots of "sight gags". I can't afford to pay for all that animation so I'm thinking about using static comic panels and the timeline editor to scroll and zoom as needed. (Maybe with some limited animations here and there.)

    Sorry for the delay, description above.

    For scrolling and zooming comic panels, I think a tween camera would also work.

  • Thanks for the reply, envoys!

    I'm a longtime Construct user, but basically a 63 year old idiot. ;-) So I'm confused about what you mean by a "camera". I assume we are talking 2D and not 3D, right?

    Is your "camera" a block of code (or function) that controls the viewport?

  • I call it a camera because I use a 2.5D perspective with a variable angle to the horizon. But it's just zoom and scroll.

    Create a global variable zoomLayout (for example) and every tick use the Set scroll layout system action. Assign it the value of your zoomLayot variable. Now the scaling is equal to your variable and you can conditionally use Set scroll layout clamp(zoomLayout, minZoom, maxZoom) to limit the zoom as you wish to the minZoom and maxZoom variables.

    Next, create a Camera sprite with the Tween behavior, use Tween(Value) to change the value of the zoomLayout variable with clamp. Voila, you have a camera for cutscenes based on system expressions and behavior. The Sinusoidal curve will give a natural softness of the start and stop, and the Elastic - the shaking of an important event.

    To use custom scrolling, you should not have objects with the Scroll To behavior (there are tutorials on how to do this via Lerp). Roughly speaking, the camera sprite is followed by the vievport system action Scroll to position. And the camera follows the hero via lerp buffering. For zoom, lerp can be disabled and Camera Tween X, Y can be used to move the camera.

    I remember in C2 there was a plugin called "Magic camera". C3 allows you to reproduce this plugin with more pleasant camera movement using built-in tools.

    Controller restrictions are needed if you zoom with the mouse wheel (for example), and scroll after the cursor or the hero.

  • You need to have a lot of time, a lot of patience, a lot of experience, imagination and you need to have money or a sponsor for the programs you need. You need help to make the graphics, animations, music and more. You can look for free and cheap programs like Inkscape, Gimp, Aseprite.

    But my biggest advice is not to lose motivation and inspiration because it is a long road. It is a shame that it is no longer like 15 years ago when you could download any program and use it with some crack or pirate key.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Make a single post with suggestion is too long, I actually was planning to write a book about it once I will get a bit of free time. Anyway, I agree with all the ones that suggest to organise your project putting variables in one dedicated Event Sheet, also as Ashley suggested, i start to use Static Local variables when things are getting crowded, also in the debugger they are listed separated from the other variables.

    Here is I organise Constant and Variables, I start with Constants, written all in CAPITAL letters, Variable have instead only the first letter of each word as capital, unless is a conjunction or similar, also I add _ (underscore) between constant and variables name to make it easier to read them. Also comment always variables because when you use them in the events, you can see the description and I like to have reminder about the possible values they can have, like for example variable Location has as description (House, Village, Cemetery, Dungeons) those are the values I can use for my game. In this way if you go back after a while on your project, you don't have to worry if the value was Village, Town or City, you will be shown that it has to be Village.

    When you give name to constant and variables, try to have them in a big category first and then go on more details, it will be easier to type and found them. As from my screenshot you can see that I am using for example SLOT_PLAYER_FRONTLINE, if you have instead them called as PLAYER_SLOT_FRONTLINE, while start to type you will probably get lots of variables that start with Player as your game becomes big. This is an easier way to find and remember variables. Since you know that you are looking about something related to the Slot object, then next thing is the Player's slot or the Enemy's slot? And finally, which type/location of Slot?

    Moving on, a thing that will probably need to use a lot will become Arrays, I use plenty of them in basically nearly of all my games.

    For the Array, make a separate Event Sheet from Constants and Variables one, to make it easier to find what you need.

    Create Constant for your Arrays, to identify Rows and Columns and eventually even the Z axis. In this way it will be like having the title of those in the first row and column of excel. You don't need to remember what is Array_Cards.At(loopindex, 1), you can just easy read it as Array_Cards.At(loopindex,CARD_NAME), so going back to check your code you know that you are looping through your Array reading the Cards' Names.

    As you can see from the screenshot, I divide them according to the Array and I give names related to the Array name itself, but I don't mention the word Array in the constant because again, I would receive so many suggestions when typing variables.

    Finally, still related to the Array, things are getting easily out of hand when you start to have ten or more different arrays, therefore under those array constants, I create a sub group that encloses all comments that explain the structure of each array. This is not useful only if you work by yourself, but also if someone else is going to read your program.

    Here another screenshot of my game current in development. It's a card game and needs a few arrays to handle all the things:

    As you can see, in the example, X is used as index of the card (first card, second card, and so on), while the Y is basically the details of each card.

    Going back to the array constants, it's not easy to also add some values in between arrays, if you want to expand or even reduce fields, so what you will have to do is to go to the comment of the Array Structure, add the line you need. For example you want to have "Cost", after the name, so you add a line there. Then you go back to the constants and change their value. That means that you don't need to go to check anywhere in your thousands lines of code the value to alter, you just change it from the Array event sheet once and you are good.

    Last thing you can notice from the last screenshot, is how I organise groups, sub groups always mention the main groups to show the whole "path", so when you enable and disable them you easily understand which one is which and it's also easy to recall them while typing.

    Same things applies to function names.

    I will stop here since the list of things you can do can really be covered only by writing a book. Other suggestions are:

    - Track the event workflow adding Logs through the Browser plugin (you can check them pressing F12 and going in the Console Tab of your browser)

    - Make a small project first, then add stuff. Have a complete one level game, then add more levels later. You will always have the game ready to be published at any time, in case you have to cut it short because you run out of time or money.

  • dop2000

    > I have two objects for "global stuff" - a sprite (invisible, global) and JSON. The sprite is for variables I use often, and JSON for everything else.

    > The sprite also has Tween, Timer, and LineOfSight behaviors, so I can run occasional timers/tweens or cast a ray when needed.

    Please could you expand upon this a little? What do you mean by "The sprite is for variables I use often" and how do you use the JSON?

    I understand adding Tween and Timer behaviours to some object as they can then be used anywhere else - I've always found it odd that Timers in particular had to be associated to an object and not just global.

    he just using a global sprite, that can be visible across entire game, like lets say u want a small logo to be seen on all pages, you can use that logo's ability to add "instance variables" on it, that will act as global variables, this has been a thing for a long time. is like a "workaround" around the 50 events limits which take 1 event away from free users even by simply adding globals.

    useful to keep in mind, but if u have a big project, problem with it is that it might glitch, simpler would be to make ur values in an array or dictionary, unlimited size data to be kept in, just is more dificult to fetch and store data.

    the logo/sprite in question can also be invisible out of screen as long as u remember not to delete any sprite that is outside the screen. or u can keep it in the hud layer that stays always in screen and make it invisible, but that will slow down ur games, even if is invisible, the data there will slow down ur game resources, because "invisible" actually is not invisible.. is transparent and everytime u fetch 1 variable the gpu trying to render that sprite which uses a little bit more resources in spikes... and if u fetch consequencely 10-20-50 variables from that sprite ur game will have a spike "load freeze" on read/write data.

  • if u have a big project, problem with it is that it might glitch

    No, it won't glitch as long as you make sure that there is only one instance of this object.

    is transparent and everytime u fetch 1 variable the gpu trying to render that sprite which uses a little bit more resources in spikes... and if u fetch consequencely 10-20-50 variables from that sprite ur game will have a spike "load freeze" on read/write data.

    I don't think this is true.

    The sprite is invisible and off-screen, so it's not consuming any GPU or CPU resources.

  • About global variables

    If you use a dictionary you have a more awkward time debugging a variable in a watch statement. I haven't used the global sprite yet but this seems like one of its advantages.

    yours

    winkr7

  • My advice for a big project is : add custom notes everywhere and try to make your code as short as possible (because even if you do so, you will probably have thousands of events).

    You will work on this project for several years, this means that you will often have to work on some code that you wrote 6 monthes ago, or even 1 or 2 years. Take the time tu put detailed notes in your events in order to help your future you remembering quickly what you have done.

    This is my process : for every feature, i write a first "functional" version of the code. Then, i try to simplify it in order to get rid of unnecessary and redundoant things. Finally, I write a custom note on almost every event and sub-event to describe what I am doing and why I am doing like this.

    This process is very helpfull in the long term.

    Another advice would be : use massively the functions and the function mapping ! This is a very usefull tool, especially for bigger projects.

  • > if u have a big project, problem with it is that it might glitch

    No, it won't glitch as long as you make sure that there is only one instance of this object.

    > is transparent and everytime u fetch 1 variable the gpu trying to render that sprite which uses a little bit more resources in spikes... and if u fetch consequencely 10-20-50 variables from that sprite ur game will have a spike "load freeze" on read/write data.

    I don't think this is true.

    The sprite is invisible and off-screen, so it's not consuming any GPU or CPU resources.

    true true, i totally agree with you. But... we are talking about a 1st time here who is about to take on a big project. everything can go wrong. thats why i mentioned those issues.

    for example, if he using the global object as invisible while the Construct says is invisible cause is a html5 interpreter u are correct... but u have to take in consideration all objects in screen are rendered by canvas... even if the system is saying is "invisible" once in screen they are actually transparent, and believe it or not... rendering "transparency" uses more memory then actual colored pixels.

    same reason why "antialisign" requires more memory... cause antialisgn basically is the smoothing of harsh edges into the background/foreground using transparent objects which requires more memory to render to calculate how much % of transparency should be and wherre that transparency should apply.

    in a large project now... depending how many of this objects u have the % usage will stack considerable...

    now in ur suggestion if is 1 object shouldnt do a big impact... however stacking that invisible object with 100000 variables that will take over globals to save "events" is a trade off i wouldn't even consider.

    from mistakes like "forgetting what that invisible sprite does" to lets say u have a project team member coming in sees a object that has "seemingly no purpose" and deletes it, then all the game engine brakes.

    thats why i suggest better use json, arrays, dictionary anything that its purpose is to keep number values, text values by default.

    if he likes to visualise the "array" he can even do a event sheet dedicated to global variables and nothing else - as long as they are all properly named and commented.

    in the end is all going to be a big time consuming thing, especially correctly commenting things.

    i find myself more then 50% of the time, implementing ideas, patching things, then not commenting and going back to comment and i forget what everything does, and just stare at it and im like "it works, it made sense at the time, but what does it all mean" xD

    dont take it as a "neing" ur tip, for you it works, for others also might work, but if you want to work in a big project with team members they need to know that sprite object thats hidden is a dictionary or the entire engine in 1 so i believe is going to be confusing, saying that... if he /she feels comfortable go at it.

    but considering C3/C2 is mainly used for tablets and phones, i know from past experiences sprite objects, and many instance variables on them, will glitch, like the variables will fail to be read and written. i used this method in the past, and i just dont recommend it long run. especially in a large scale project.

    especially a sprite is easy to delete by mistake, or change its designated state by simply adding it in a familly by mistake, and then "woops" the familly gets destroyed when shot, and now ur invisible sprite that holds all user data gets removed or cleared.

    and so many other reasons similar to above.

    now memory wise you are correct once outside the screen no memory is used, C3 engine doesnt render nothing that is outside the screen.

    but is easy to remove a sprite by mistake once outside the screen.

  • here are my tips for large scale projects

    coment everything on spot, even if takes double the ammount to properly do it, document everything as many said above me.

    You need basically to create a "user manual" or better said a "dev manual"

    when you make games or software that is 1000 -10,000 lines of code maybe you don't need that many comments.

    but if you are going above 10,000 lines of code or in Construct events, you might want to do so...

    also as many suggested, layers events and layouts, name them accordingly, early in C2 and classic someone used this format and i since followed it instinctively for Construct cause it made sense and its easy to find stuff

    for example you have Intro screen and the events sheet for it will be ES_Intro_Screen

    that will differentiate between the layout and event sheet, not wasting time clicking back and forth trying to figure out which one is which, especially when u got like 10 event sheets opened or 10 layouts opened.

    latest C3 now has colored comments, i use that feature instinctively since implementation, reason?

    RED is danger (meaning properly comment stuff and alert lines), Orange mid danger (meaning above medium danger if modified stuff might brake and cause weird glitches), yellow somewhat danger (some visual glitches or missalignments), green "animation stuff" "hud lements" - no danger if altered wrong, maybe some display not showing.

    folders in project - i used this structure for my project usually

    "g-spot" = plugins (mouse,touch,audio,etc) - all plugins that i use goes in this folder - (i name it usually like that or core but not to mess with the engine core - i usually give it a "sensitive naming" because once u mess with it, things go hot in weird places.)

    "hud elements" - everything hud related (for in-game) goes in this spot

    "menu items" - all menu items goes here

    "character" - everything related to character goes here

    "intro screen" - all intro/loading screen goes here

    and u can do this for everything just keep track of them in a proper manner.

    global variables - now here as the latest post in this topic there are a few factors to consider

    are u confortable with using "workarounds" or sacrifice "memory usage" for sake of "development purpose" ? or u care more about how the "game performs"?

    sometimes i find that what i think makes sense to me as a dev, is not always healthy for the game "resources" and i tend to do more harm then good, while is easy for my work it will clutter the project and barelly open it up in some cases.

    that's why i prefer using Arrays, dictionaries or instead of the actual dictionary plugin, a json/xml file, or most of times i just make a Variables_event_sheet that i include in everything as "globals" and "graphic dump" layout to make every sprite first instance renderable and not having to worry about if i can call "create object" if object is not placed in a layout somewhere.

    famillies - are your friend, no matter how good you are at simplifying things, you will find famillies are the best - like touretto says "all for the familly" and in our case .... its just true, famillies are one of the most powerful tools you can use in a project, learn to use them, when to apply them and how they interact with other project objects will make ur life easy.

    json/xml/array - you want to learn this how they function how to properly make a grid, how to read and write them etc. plenty of examples plenty of tutorials just grind till u get the hang of it, it looks scary in beginning but are easy actually, requires somewhat some logical thinking.

    entry level html5,css,javacript knowledge - if you want to understand how C3 works, will help you long run to understand this 3 languages. they are a must in everyones repository as developers,jquerry optional not really needed since javascript does similar stuff nowadays and sometimes even better.

    functions - now here... i seen projects doing functions and were a masterpiece when looking at the code, and i seen projects that would make you hurt just reading the names of some of the functions ... avoid naming everything the same with 1_2_3_4_5_6 at end or in front, unless imperatively needed or required for some reason.

    and going back to my first recomendation ... ALWAYS keep track of your code, i personally changed my style of coding lately, from just implementing in, implementing and while my head is hot and in the moment add comment immediately, otherwise i close i go to sleep, come back, and i look at it like some stranger made the code... and dont understand a thing of it.

    always document your progress

    oh and since i mentioned progress... turn autosave on, and make a habbit in making a backup, even if u "ctrl+s" by now as a tick response, "save file corruption" is a thing.

    late development stages, streamline everything, find a better way to make ur code faster to read and run, reduce image sizes, and code. The shorter everything is and smaller the less memory usage your game will use, the greater experience the user will have.

    Advertising - early in development across the years, decades by now, devs would stick ads on all pages of their game, bottom, top, spam full screen ads, video ads etc, you name it.

    Personally i never liked that because before making games, i played games, and i hated watching advertising especially forced ones.

    So one perfect model for advertising is a fairy dancing on ur screen saying hey "you want to watch some ad? you get X ammount of gold or diamonds or whatever, by watching this you help me as a dev and also u get something from it... you dont want to watch an add now? ok il come back later buzz u later"

    that is the perfect model, piratesoftware mentioned this also in some of his twitch stream, but i totally agree. Also if users buy your game, and u have a in-game store for purchasing items etc ... don't make them powerful, make them design choices, especially if its a multiplayer game. it just ruins the mood as a player to grind free mode in watching them ads and diamonds and whatever and then some guy just comes in trows 100$ in ur store and bam top1% rank in leaderboards. while the rest grinding months in ur game. is toxic avoid it.

    if you really want to give "a powerup" for donations or in-game stuff do this, instead of giving level 100 gear to the "payup" guy.. sell instead the ability to grind faster, or the ability to get 2x rewards if he watches the fairy ads or something that is a bit OP in balance of the free user that only paid for ur 5$ game or 20$ game, but can't afford to pay another 1000$ in-game supplies.. make it fair for everyone.

    A good example here is the way POE is doing it, they sell goods and services, but the game is free, u can buy materials in game etc but all the in-game purchaseable items, don't give u any powerup are just super cool visuals nothing more.

    and sort of this are my personal tips, you will find, that most of them repeat with a recurring theme with other devs, thats because its a "right way of doing things" which most devs will find and there is a "let the world burn way" of doing things.

    hope it helps.

  • but u have to take in consideration all objects in screen are rendered by canvas... even if the system is saying is "invisible" once in screen they are actually transparent, and believe it or not... rendering "transparency" uses more memory then actual colored pixels.

    No, you’re wrong. Check out this demo — make the sprite invisible, and you’ll see that GPU utilization stays 0% even with tens of thousands sprites.

    Besides, this whole thing is moot because I’m not creating 100,000 invisible objects with 100,000 variables. It’s a single sprite with about 100 variables — zero impact on performance.

    but is easy to remove a sprite by mistake once outside the screen.

    That’s why my sprite has big text saying "DO NOT DELETE" on it. Plus, I have only one instance of it in the Loader layout, which I rarely even open in the editor.

    thats why i suggest better use json, arrays, dictionary anything that its purpose is to keep number values, text values by default.

    Oh, I do. I have about 30 different JSON objects. But for frequently used values, instance variables are much more convenient.

    but considering C3/C2 is mainly used for tablets and phones, i know from past experiences sprite objects, and many instance variables on them, will glitch, like the variables will fail to be read and written.

    No, that never happens. These so-called "glitches" are always due to user error.

    especially a sprite is easy to delete by mistake, or change its designated state by simply adding it in a familly by mistake, and then "woops" the familly gets destroyed when shot

    Just like you can accidentally delete an array, dictionary, or global variable?

    These things are easily avoidable if you just pay a little attention to what you’re doing.

  • EDIT: Ninjad by dop2000, lol. I echoed similar things, but yeah.

    for example, if he using the global object as invisible while the Construct says is invisible cause is a html5 interpreter u are correct... but u have to take in consideration all objects in screen are rendered by canvas... even if the system is saying is "invisible" once in screen they are actually transparent

    This is incorrect. An object marked as invisible is simply not rendered. You can test this with a blank project, have 3000 onscreen objects (and 1 other object moving so that the game ticks and provided measurements in the debugger), make them visible and invisible, and see the gpu improvement when they're invisible.

    now in ur suggestion if is 1 object shouldnt do a big impact... however stacking that invisible object with 100000 variables that will take over globals to save "events" is a trade off i wouldn't even consider.

    Its worth considering, but it's nice we have the choice on which path to take. An object's instance variable list, for all intents and purposes, is a dictionary - you can have 1000s of inst vars and would barely notice cpu difference, even if reading/writing to them often.

    from mistakes like "forgetting what that invisible sprite does" to lets say u have a project team member coming in sees a object that has "seemingly no purpose" and deletes it, then all the game engine brakes.

    This should never happen, because a team of C3 devs would know to right-click and use "find all references" on object they are unsure about. If they find references on the mysterious hidden object, they'll quickly realise what it's for in all the events they are listed. If they use "find all references" for the specific instance variable, again, helps here. Lastly, when you delete an object that has any events, it will warn you about deleting and ask if you'd like to "find all references", which the dev should be checking before deleting.

    thats why i suggest better use json, arrays, dictionary anything that its purpose is to keep number values, text values by default.

    I do agree with this! Dictionary is like an enhanced "instance variable" list, with extra benefits like getting the variable by name (which inst vars cannot do) deleting and adding new ones at runtime (again, inst vars cannot do) and link them to many different objects at once if ever needed, rather than adding inst vars repeatedly to multiple objects, or using family instance vars (which, both are great, but a dictionary being able to just link up to any object type, or even a family, is excellent).

    The one benefit to a hidden sprite, is behaviours, like tween or line of sight. But you still could use a hidden sprite for those, but store vars in the dictionary.

    i find myself more then 50% of the time, implementing ideas, patching things, then not commenting and going back to comment and i forget what everything does, and just stare at it and im like "it works, it made sense at the time, but what does it all mean" xD

    Lolol yes, many times this happens. Or better yet, you think "wow wtf why did I design it this way, it could be way better!".

    but considering C3/C2 is mainly used for tablets and phones, i know from past experiences sprite objects, and many instance variables on them, will glitch, like the variables will fail to be read and written.

    This, I have never heard of, nor encountered. It should be reported as a bug if you can reproduce it. Does this bug happen with like 1000 inst vars, and does it happen with a dictionary with 1000 keys?

    especially a sprite is easy to delete by mistake, or change its designated state by simply adding it in a familly by mistake, and then "woops" the familly gets destroyed when shot, and now ur invisible sprite that holds all user data gets removed or cleared.

    I disagree - you could add a dictionary or JSON or array into a family by mistake, too! But if someone does this, then that's user error. Even ignoring the topic of a hidden sprite, if it's just regular game and someone decided to add an FX into a family that doesn't belong there, then they would indeed get unexpected results and must fix this or remove them from the family.

    now memory wise you are correct once outside the screen no memory is used, C3 engine doesnt render nothing that is outside the screen.

    Correct, and it doesn't render when onscreen but invisible. (it renders if visible but opacity is set to 0, iirc).

    but is easy to remove a sprite by mistake once outside the screen.

    But why? What if a preloaded particle was offscreen and invisible, why is it easy to delete it? Devs need to be more alert when they're tampering with the unknowns in a project!

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)