Welcome, Guest. Please login or register.

Login with username, password and session length

Advanced search

1411414 Posts in 69360 Topics- by 58415 Members - Latest Member: sophi_26

April 16, 2024, 08:55:07 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsPhoton's 2015 1GAM Devlog
Pages: [1]
Author Topic: Photon's 2015 1GAM Devlog  (Read 1113 times)
Level 4

View Profile
« on: January 03, 2015, 02:48:50 PM »

TIG User Photon here, and here's a little bit of my story...

Brief History

I got "serious" about game development about three years ago. By serious, I don't mean in terms of commercial endeavors but rather that I would just start MAKING GAMES. College made me realize life wasn't slowing down and if I ever wanted to pull the trigger on something like this, I'd better do it sooner than later. I chose sooner.

I started out in Python and made some pretty simple stuff with Pygame. Probably the best thing I made there was a three-level platformer where a robot was trying to escape a trash compactor (rising floor.) I then ended up discovering Stencyl as the result of playing an LD entry by AdventureIslands (to his shock, as he told me he considers it one of his worst entries.) Despite coming from a coder's background, I found the ability to focus on the logical meat of design, if you will, to be a huge boost. Plus, observing Stencyl's way of doing things spurred me to think about how I'd implement similar core features in my own personal codebase/engine. Over about two years, I ended up with four games publicly released, three of which were Ludum Dare entries of my own.

Somewhere within the last six months, I moved back to hard-coding and picked up the foundation of Stencyl, Haxe and OpenFL. I've been plunking away slowly but surely on designing an entity-component system (read more about those here) of my own doing.

Why 1GAM?

(NOTE: for those who don't know, 1GAM stands for "One Game a Month."

Three years later, I've hit a couple of significant milestones in my opinion. That being said, I have a long way to go. As I try to balance real life and game development, it just seems to be getting clearer and clearer that I know so little about it despite the leaps and bounds I've already taken. Perhaps I'm in, as one might call it, the sophomore slump. I can make a "game", but seeing it through to a non-jam style, polished finish is another thing altogether.

I'd considered joining 1GAM before, but never really threw down the gauntlet. But I've been making changes to my daily routine in an attempt to establish a more disciplined routine for game development. One main change is that I have started "dedicating" small chunks of time to programming and then logging time spent, so that I can keep a more tangible record of my work ethic. This has been, in part, to keep myself from having sporadic ten-fifteen minute sessions here and there that don't accomplish much.

I feel like I'm getting in a better position to effectively accomplish 1GAM as a result. Besides, another thing I want to strike is "analysis-paralysis." If I set a discrete, short-term goal, the "premature optimization" disease is (hopefully) less likely to hit me.

Not to mention all the little things that quiet, non-public games can get away with not having. General polish, distribution mediums... these are the kinds of things 1GAM will hopefully help whip me in shape for.

And so here it is: I'm taking the challenge to complete 12 games in 12 months. I am now throwing down the gauntlet for 1GAM. Hold me to it!

Devlog Focus

So why a TIGSource Devlog?

Well, part of it is accountability. I don't necessarily expect anyone to come storming through my door if I fail, but it typically helps when you know other people are aware of your intents and watching. Who, Me?

Plus, I want to share the journey with the people here. The hope is that over time, we can help each other. My plan is to focus strongly on the programming aspects of my games. Desirably, this will help other aspiring game developers as well as letting more veteran developers come along and give advice on what they think could be done better. Again, I know so little... but one of the best teachers out there is experience. I do hope that throughout the year I can hone some of my artistic and musical abilities as well, but the primary focus at least for this devlog is to discuss programming and design strategies and methodologies. I very much enjoy giving back knowledge I've acquired over the years; don't be afraid to make this devlog work both ways in that regard. By the end of the year, who knows where we'll end up?

So consider it begun. Stay tuned fellow TIGSource goers; first update on my 1GAM quest is coming soon!  Hand Thumbs Up Left Big Laff Hand Thumbs Up Right

Game Showcase

January (Resolution) : Roids
February (Maps) : Pending
March (??) : Pending
April (??) : Pending
May (??) : Pending
June (??) : Pending
July (??) : Pending
August (??) : Pending
September (??) : Pending
October (??) : Pending
November (??) : Pending
December (??) : Pending
« Last Edit: February 01, 2015, 07:11:10 AM by Photon » Logged
Level 4

View Profile
« Reply #1 on: January 04, 2015, 09:36:43 AM »

Do you use psuedocode?

I almost never did. Even what I have started using is still very similar to real code. But recently I discovered a rather bad design practice that I was doing that led me to start using this more.

In the entity-component system design, systems do work on components (which are owned by entities.) If I want to write code for a system, it would make sense to think that I would need component classes for the system to work with. As a simple example, let's say I want to update a Bitmap's position.

Originally, I ultimately would design the components and then design the system. For simpler systems like the one just mentioned, I can get away with this. But I realized this is backwards. I'm trying to determine what data I need and how to organize it before I confirm how I'm actually going to use it. I wonder if this is something I picked up from OO.

But how do I write system code before having the components set up? Write pseudocode instead.

Again, the system in question is a very simple one, but I went through the motions anyway and went back to put together a rough design doc for the simple system. Hopefully it does a good job of getting to the point and explaining itself:

V00.01 - 01/03/2015

Action: Update a bitmap's position on screen based on its owning entity's position

Update Psuedocode

var img:Bitmap = bitmap currently attached to stage/parent/etc.
->x:Int = x-position of bitmap on parent
->y:Int = y-position of bitmap on parent
var new_x:Int = new x-position for bitmap
var new_y:Int = new y-position for bitmap

function update(t:Int):Void
img.x = new_x;
img.y = new_y;

Logical Breakdown

The action is accomplished in a single set of value assignments.

Using a separate base position allows us to update a much smaller data structure over the course of an
update cycle without having to pull in an entire bitmap object every time position is manipulated. Thus the reason for
this system and action.

Data Breakdown

Simple sender and receiver relationship:

Bitmap << Base Position

Component Design

// Sender
class PositionComp:
x:Int = (new_x)
y:Int = (new_y)

// Receiver
class BitmapComp:
data:Bitmap = (img)

Extra Design Notes


So I'm attempting to make that part of my process now.  Hand Pencil Ninja

So who else uses pseudocode? How do you use it? Do you use something different for the pre-code planning?
Level 4

View Profile
« Reply #2 on: January 09, 2015, 11:05:14 PM »

The first week of work is almost done. Its been mostly baseline work, but so far I have the (basics of the) following implemented and tested:

  • Basic Drawing and Positioning
  • Sprite Sheets and Animations
  • Keyboard Input

EXCITING, NO? Hand Shake LeftBig LaffHand Shake Right

I've been working through figuring out this ECS thing. At first, certain things about using the ECS seemed to be a pain. However, I've made some good progress, as well as some interesting observations as I consider how to build out my engine/game. For instance:

Persistent Vs. Volatile Data

Bear with me, I may be stretching term usage a bit here but whatever...

Its something I've noticed before, but look at a commonly-used variable set like position (x and y). Have you ever had the problem of how to manipulate this data with multiple forces/effects without said forces/effects knowing about each other? For instance, let's say you have basic movement, on-stage wind, and a stun status effect. Basic movement is your player input movement, wind causes slight displacement in a particular direction and stun effects stop your movement altogether.

OK, so let's say you are walking around and an enemy jumps out and stuns you. This means no movement. Simple enough, right? But how do we do this without talking to the player input handling/controller and the wind effect? Adding checks to the two other forces is clunky, especially since we'd have to do that for any other effect with similar results. We could try to undo any changes that the controller and wind already made to the player's position, but...

That's what I'm getting at. Player position is PERSISTENT. Its not usually supposed to reset every frame. Its easy enough to change your x from 20 to 40, but figuring out it was at 20 before the change to 40 can be drastically more complicated. You might have to climb through every other possible effect and try to figure out what it did to the position and where it was prior to any amount of changes that occurred. I have a feeling I'm not the only one who's experienced this taxing dilemna where separate forces act on data in ways that inadvertently affect other forces' ability to do their job.

Now, if position were VOLATILE (for our purposes here, it resets to zero every frame,) things would be different. Position would always be at zero at the beginning of a frame. You have a nice reference point to work with even if other effects came in before you. Its not a silver bullet necessarily, but it does help some. Of course, this just isn't the case for data like player position.

This is where my considerations on determining component structure and data separation come into play. Part of the idea of the ECS is that data can interact indirectly and naturally. Our player input, wind, stun effects and whatever else can go about their business and the desired effects on position take place. How do we achieve this? Can we partition our data and logic out into distinct enough pieces to achieve this?

I have a proposition for protecting our precious persistent data: we hide it behind a volatile gatekeeper.

Let's go back to the example. Before, we had something like this:

Position << Player Controller
Position << Wind
Position << Stun Effect

Each change to position overwrites the old position. If we want to get the old position, this might mean working backwards or storing off positions elsewhere for future reference. These things might work in some instances, but what if we did this instead:

Displacement << Player Controller
Displacement << Wind
Displacement << Stun Effect

Position << Displacement

This may seem a little overkill to manipulate position indirectly, but when I think about it it makes sense. All our changes are added/incremented to the displacement component. Once all changes have been accounted for, THEN we write them to position cumulatively. If we order our forces correctly, things can be kept in decent order. For instance, if stun goes last and decides all movement should be canceled, it simply wipes the displacement module back to 0 prematurely for an easy "undo." This can keep us from locking arms between components in a way that hurts flexibility. It can certainly make straightforward actions... well, straightforward to implement as opposed to jumping through x number of hoops.

In theory, each persistent component that needs protection should have a "sentinel" volatile component that controls what can happen to its persistent counterpart. I see it as a one-to-one relationship: this way, the persistent component can receive its changes and then safely reset its gatekeeper so its ready to receive the next series of updates. The point is, data is protected until we have a certain confidence that we want the changes being proposed to stick. And the ECS seems to be well suited to this set-up.

So that's my "quick" take on the matter. I may post an example from my code later but for now, thoughts? Am I making any sense?
Level 4

View Profile
« Reply #3 on: January 12, 2015, 06:28:19 PM »

Thought I'd give you all a little more to chew on:


I've put some of my design docs out on Dropbox if anyone wants to see part of my design process. If anyone is interested in seeing source, just say so here. I'm not quite to the point where I want to just throw my entire project out into the open, but I can still share pieces with those who are interested.

In other news, I need to start solidifying a game concept soon for this month's game. I'm thinking I might do some sort of sailing game, where a resolved sailor is determined to get home to his lady. I'm thinking something simple where you have to guide a ship via top-down 8-way movement, and your movement can be affected by things such as strong winds. Of course, merging those two movement effects is something I talked about in my last post; when and if I get a wind system doc drawn up, I can post it and show more clearly how I plan to let the two run autonomously.
Level 10

Scary, isn't it?

View Profile WWW
« Reply #4 on: January 12, 2015, 08:17:37 PM »

I like the design docs, even though it's fairly simple stuff! Keep it up!

Do I need a signature? Wait, now that I have a Twitter I do: https://twitter.com/theimpmaster
Level 4

View Profile
« Reply #5 on: January 12, 2015, 08:41:12 PM »

I like the design docs, even though it's fairly simple stuff! Keep it up!

Simplicity is key. The decoupling allowed by the ECS concept, per my observations thus far, allows me the ability to build diverse, flexible game systems.

For instance, I was talking about implementing a wind effect. Now, its really easy to start thinking broadly: who is responsible for the wind? Where should it come from? How does the entity know where to get it? What data format should it be in? While these may be good questions, I have found thus far that it helps to work backwards from the end state.

When I stopped and thought, I realized the first thing was that I had to apply the effect to the entity. It didn't really matter where it came from or who owned it if it didn't apply to the entity; the first step backwards was to get to the point where I could have the entity be affected by some (indistinct) force. So that's what I did first, and I have that working (I've added the design doc for the PerpetualForceSys to DropBox.) Again, its not much, but it lays a flexible groundwork for not only the wind but for any other force that wants to chip in. And now that I've tested it and see that it works, I can take the next step backwards.

So more or less, I try to focus on one set of inputs and outputs at a time when designing components and systems.
Level 4

View Profile
« Reply #6 on: January 21, 2015, 11:03:52 AM »

Hey guys. Near the end of last week I had some stuff I was taking care of so I don't have a whole lot to show for. But now I've got some free time coming up in the next week or so and I'm still planning to have something to ship for 1GAM January. I may update the design docs folder later with some of the new stuff.

That being said, I have one major feature I'm trying to sort out right now and good 'ol "analysis paralysis" has been poking me. That feature: collisions.

Collisions are an interesting beast because it involves not only entity-to-entity relationships, but a constant shift between this entity versus that entity colliding and what have you. Right now I just want to get a simple AABB system set up based off of the Separating-Axis Theorem. The actual physics part of running collision detection and separation isn't what's got me hung up though, like I said.

Part of me feels like I'm getting caught in pre-mature optimization, but whenever I try to implement something for this I end up second-guessing myself. Do I bunch collision groups, sensor-status, and parent id into one big object/component? Or is that secondary info for a manager class? Should I make collision shapes their own entities owned by their respective parent entities? Each method seems to throw a wrench in the system. The fragmentation of data in the ECS is making me question how to make sure all necessary data from one entity reaches the next entity, how one entity/system knows who to pass it to, etc.

Well, we'll see what happens I guess. If anyone has any input on this, feel free to chip in.
Level 4

View Profile
« Reply #7 on: February 01, 2015, 07:09:36 AM »

Well, I made it. Things didn't go quite as planned, but hey! Getting through the hard knocks is part of why I'm doing this.

I more or less just ended up with a game of Asteroids. I had planned to do something with the theme and using the screen wrapping in a creative way, but it didn't quite get to that point. So I don't pretend that this is anything incredible, but its a start:


Perhaps more importantly, the payoff in getting back to hard-coding, learning ECS, and gathering intelligence on how I want to structure things moving forwards is PHENOMENAL. I've already taken notes so I can hopefully end up with a lot less "hackery" in February. I'll probably write up a (quick?) postmortem about it in a bit, so stay tuned.
Pages: [1]
Jump to:  

Theme orange-lt created by panic