Tips n' Tricks for Developing

Fool

  • Posts: 88
I've been using stencyl for a few months now. During development I've found design can be smooth or painful depending on how you go about it. So I'd like to share some of what I discovered during my own developmental headaches. This isn't going to be comprehensive or a full blown guide, but a collection of some observations about how to solve common problems.
Edit: Thanks for the easy format suggestion Guri.


PROBLEM: How to implement selection on multiple mobile actors
SOLUTION: Use global input an an attribute to cycle through actors if they are fixed in place,
like a Tower Defense game. For mobile actors, attach onClick events to each actor that is selectable. Stencyls pipeline assumes you rely on events for communication, so use them. The selector should have reference attributes for 'source' and 'target' which are settable and gettable by any actor that implements an onClick event. The only logic the selector should handle is to check if source already has a value, and if so, then the actor that triggered the event should be stored in 'target'.
CONCLUSION:  Each actor should be responsible for its own logic, and global objects, such as a 'selector' should do little more than hold state.



PROBLEM: Many events on actors may be expensive
SOLUTION: Unless you are running a lot of heavy code in a draw event, most events are going to be lightweight, only incuring a cost when you call them. The exception is the 'update' event, which you want to limit. Also if you don't need say physics events or updates, try going into an actors physics tab and changing them to a 'simple' actor.
CONCLUSION: With events, you only pay for what you use. If you are worried about a solution being inefficient, actually implement it and run the solution before you reject it. For example, I was worried about attaching a lot of onClick events to too many actors. I tried it, and surprisingly, it worked without taking a performance hit. Always question your assumptions



PROBLEM: How to represent items in game
SOLUTION: Ideally you want to be able to encapsulate logic in each item, instead of writing a bunch of events in some global object or scene behavior for every possible item. So each item should be an actor. The way I did it was to use actors, and then create an 'item' behavior, with a map attribute called 'properties'. Then from the behavior configuration screen, I could customize
any actor with this behavior, adding a 'name', 'description', 'durability', 'value' etc.
CONCLUSION: Each item  or object should be responsible for its own state. I believe this is called
encapsulation. There are a lot of ways this could have been handled, as a global database system, storing items as a comma delimited string, etc, but by far I've found this way to be the most flexible and simple to implement.



PROBLEM: How to implement player inventory
SOLUTION: As with the representation of items, we can solve this with a behavior. I implemented a behavior called "Container", with two attributes, "Limit" and a list called "Contents". I added an 'addItem()' event that gets the target reference from my selector (a scene behavior).
CONCLUSION: Most problems have simple solutions, easily solvable without resorting to big messy global objects.  Actors are golden, and work well for encapsulating logic, while behaviors work well for storing data or state.



PROBLEM: How to handle cleaning up objects, and other conditional states
SOLUTION: A good example of this is when I implemented actor based items. I had a boolean value 'isClaimed', so when the onClick event happens, it gets set to true. I then added a boolean event so when 'isClaimed' became true, it would kill the actor, removing it from the map instead of allowing the player to pick it up an infinite number of times.
CONCLUSION: Boolean flags are preferable to just calling code, or having a bunch of nested if statements
to check various conditions. It allows events to act as setter functions, so you don't have to expose the gory insides of an actor or behavior to outside code. This way, if the implementation of something internal changes, it won't potentially break external code that uses it.



PROBLEM: Lots of duplicate code, especially condition and if checks
SOLUTION: This crops up typically when one or more objects is altering the state of another object, and has to make sure everything is alright before it does. For example, when I first implemented my item system, I started out with one item, a pistol. The pistol would get the players inventory and inventory limit, and then do a check. But suppose I added weight checks? Bulk checks? Maybe type of item checks because some containers can only hold certain items, such a canteens holding water. This would quickly grow out of control, and I'd have to use this same code in every item. Instead I had the containers event addItem() call a custom block in the container behavior itself, that checks to see if the container is full, and then gives the go ahead or not by returning true or false.
CONCLUSION: An actor or any object shouldn't directly change or set the innards of another. If you
are doing a lot of conditional checks like this, with lots of duplicate code, ask "Can I turn this into a custom block or event?" And "where can I move this code so I don't have to keep rewriting it?"



PROBLEM: I don't know how to use 'x' and reading the manual doesn't help
SOLUTION: When I was implementing items by using hashmaps to store their name, durability and so forth, I initially didn't know how to use them. Print is a great command, and will allow you to inspect the state of your game in the logger, as it is running. This is good for testing assumptions. In my case I wasn't sure if I could take a reference to an actor, get a map-attribute from one of its behaviors, and retrieve a key. Before implementing a fancy save system, or storage system, I attempted to
output the value of a single key from a single behavior attached to a single actor in game.
CONCLUSION: Because of this I was able to figure out exactly how maps work. Whenever you don't
understand by reading, you can usually figure it out by testing to see what works.



PROBLEM: I don't know whats next, or how to solve a problem
SOLUTION: A lot of times us coders can get bogged down in syntax, scratching our head over weird errors, wondering if we are misunderstanding how some api works or other. Again, its important to test assumptions, and preferably using small experiments. Sometimes I'm not really sure what I'm doing at all, or what the next step is. The trick is to not focus on the syntax. Use pseudo-code, breaking the problem down into simple code-like steps, with short English sentences. In the case of learning to map attributes, my pseudo-code looked something like this
    addItem would do something like...
      1. get source
      2. get source behavior Container
      3. For item = Container.contents do:
      4.   print(item.name) #name being a key in the hashmap of the item
CONCLUSION: Pseudo code helps you see, swiftly, if you really understand the problem, and gives you an
idea, like a compass, of where to start.



PROBLEM: I just lost my project / my project files are broken / someone stole my computer
SOLUTION: This won't actually help you if you are already dealing with this problem, so fair warning. "File-> Export game" lets you save out your project file to any location. I like to version it, so that I can easily see my latest project, in case some problem forces me to revert to an earlier build. Also, get something like dropbox and put all your game files in it, as it automatically syncs them each time it is start, ensuring you have an offsite backup
CONCLUSION: If your project goes on long enough, you will, at some point have to resort to backups.
Don't hesitate, it only takes a few minutes to make sure you don't lose weeks or months of work.



PROBLEM: My game or mechanics would be great, but everyone says otherwise when I describe it.
SOLUTION: Look, its easy to imagine an amazing game in your head, work out the mechanics, run the proverbially simulation. In some sense, when people play actual games, they do just that, form models and run a crude subconscious simulation of the game world. This is especially an easy way to design if you are a strong visual thinker. You can write down your ideas, but is that going to capture the 'feeling' you're trying to convey? What you want to use in this instance is a 'mockup'. It may not be quicker, but it is much better at communicating the essence of your ideas. Also mockups are good for telling you, at a glance if an idea would genuinely be fun, or only sounds fun (0). For a variety of reasons some concepts sound like they'd be a blast to play, but can never work out without being a time-suck to implement, or worse, are impossible. In the end mockups help to tell you which direction to take your game, and at best act as a visual road map for others on what you want to achieve.
CONCLUSION: (0) For reference, see Peter Molyneux.


PROBLEM: My design documents are littered with all sorts of notes
SOLUTION: If you're like me, you have suggestions, concepts, bug fixes, technical details, oddball ideas, todos, maybe-dos, and a dozen other categories of notes, all scattered throughout your project. While working I boiled these down to BIGT notation. Heres how it works. You can leave all these notes scattered about, but you add tags to them so they are easy to eyeball. And theres only four categories.
   [BUG] for anything that needs fixed or doesn't work as it should
   [IDEA] non-technical concepts, ideas, suggestions, design, etc.
   [GUTS] gory technical details. How you handle your rendering, why you chose system a over system b
   [TODO] Everything else that doesn't fit, or you haven't catagorized yet. A catchall
CONCLUSION: Implement sanity checks early on. That way when you start making serious progress, things
don't devolve into a hot mess and are easier to clean up when they do.


I'll add to this, and polish as I go. If you have tips, post em, and I'll edit them into the original post along with your name.
Thanks for reading.

« Last Edit: April 21, 2016, 08:53:10 pm by Fool »

gurigraphics

  • Posts: 690
Quote
[IDEA]Concepts, suggestions, improvements, anything non-technical

You can try to summarize it and leave only the essentials:

[Problem] Performance:  Framerate 10 FPS.
[Cause] I used many actors.
[Solution] I used less actors.
[Result] Framerate go to 60 FPS.

It is best to read and even think about.

ceosol

  • *
  • Posts: 2279
I am happy to hear that you are figuring things out. However, I did not understand most of what you wrote. Maybe it was the terminology. For instance, I think of a database either as 1. a collection of data, or 2. a method of online data storage (such as mysql databases). Lists and Maps are forms of databases and are extremely useful in Stencyl, especially for inventory systems... yet you said a few times that databases are not the answer. I use lists in pretty much every single game I make.

I made a game recently with 300+ actors on the screen at all times and it has no lag even in flash. It you have a few actors and regions and are seeing lag, it means that your actors are running processes that they shouldn't be. Start using a lot of booleans to shut off actor events when they are not needed. Also, instead of utilizing regions, create your own location determinations using "x of self >. . . and x of self + width of self < . . ."

Fool

  • Posts: 88
Hey thanks ceosol! I tried to clean up a lot of it, and clarify it based on what Guri said.
I was talking more or less about big monolithic collections of items, with values. Global objects, and over complicated systems.
Think "Architecture Astronauts", overbuilding and over complicating things that should be simple.

« Last Edit: April 21, 2016, 09:18:31 pm by Fool »

ceosol

  • *
  • Posts: 2279
It is much more clear now. However, I am still very confused by a lot of your terminology. This reads as a coding language help book. I am not a coder, nor will I ever be a coder. Stencyl's key demographic is people wanting to make games without coding. If you want to help more people, wouldn't it be better to write this in a "Tips 'n Tricks for Dummies" sort of way?

When I was learning how to teach others, I was told to "explain things as if I was talking to my four year old sister (or daughter)".