ID:151311
 
Getting back into the swing of things, I decided to start a project that's been on my mind for a while now. Problem is, I don't really know where to begin...

I figured I'd start along the lines of mockups and design documents (of course) but my real question is what part of the game do the rest of you begin working on first? The log in system, combat, story modes, huds... Or do you start implementing from where the game starts and proceed adding things in the direction of the story as needed?

Thanks for any ideas.

-GreenMonkey
I usually start by programming the generic core systems like text handling, and things like that. Then I'll move on to the more game-specific things, focusing on the things that will become the backbone of the game at some point. Like if the game had turn-based random battles I'd probably start working on that first off -- after the generic systems are done.

When you end up with multiple projects you can usually split the generic systems into libraries to be used in other projects, as long as you make them open-ended enough to be adaptable to any project. Sometimes these little personal libraries grow into something other people can use (see: hub://Nadrew.StringHandler and hub://Nadrew.WindowManager), so they can be polished up for public consumption and released as a resource.
...Deja vu...

Oh, and I also find that commenting code that I might mess up on as I make it usually makes it easier, and if there's ever a need for someone to pick up on your code (a collaborated project) it won't take a week for them to understand it all.
In response to Nadrew
Seems like a logical approach, and I like the idea of creating separate libraries for future use.

I have many systems that seem to need to be designed and I became a bit overwhelmed, I'm not much of a programmer so some of these things like on-screen interactions, menus, and random turn-based combat involving those utilities seem a bit complicated at the moment.

Any suggested demos I should try to learn from? The language itself doesn't seem too difficult to pick back up, but there are many demos out there that handle things differently, I'd like to pick up the proper syntax as I go the first time around.

Thanks for the prompt replies.
In response to Ill Im
That "deja vu" link seems like a very sporadic and complicated approach to design. I tried to consider it, but it seems like creating as many unique systems as that entails would be what I should avoid.

Like anything else, simplicity should be a cleaner and more efficient approach, but then again I could be wrong. In the end I'm hoping to keep overall CPU usage on the low end without sacrificing performance or cutting corners.

I do agree with your commenting statement however, that seems like a necessary approach to design, especially since I'll be relearning as I go.

Thanks for the response however, and if I misunderstood your link please feel free to correct me.

-GreenMonkey
In response to GreenMonkey
This is actually how most games on the iPhone are developed, in Obj-C, you have to create the object, and all of its variables, and declare all of its functionality, then you actually have to give it functionality/use its variables. All their classes are separated into header and body files, header is where you define it, body is where the actual functionality is.

It is not necessary to do this, but it makes it a lot more do-able, rather than programming, and on the fly thinking "Oh, I think I'll add this object", then later on you think, "Oh, this object would work better if it had a procedure that did this" *has to change entire object's programming to integrate that one proc* *repeat*

EDIT: In short, it's basically just adapting the idea of fully developing something before creating it, like how most professional games have really long, lengthy, beefy design documents that pretty much tell you how the game is made, and what will be in it.
In response to GreenMonkey
GreenMonkey wrote:
That "deja vu" link seems like a very sporadic and complicated approach to design. I tried to consider it, but it seems like creating as many unique systems as that entails would be what I should avoid.

These "unique systems" are objects, object-oriented programming is what is used on almost everything nowadays.

Like anything else, simplicity should be a cleaner and more efficient approach, but then again I could be wrong. In the end I'm hoping to keep overall CPU usage on the low end without sacrificing performance or cutting corners.

Simplicity is not always cleaner.
proc/addToNumber(number)
return number++


that's a lot simpler than
proc/addToNumber(number,amount,limit)
return min(number+amount,limit)


but in the long run, what if you want to add 64 to the number? Now you have to call addToNumber 64 times, though it is more simple. (This is only an example, I know you can simply do number+64, but for the purpose of getting my point across, let's just say you can only use a procedure to add to the number)

Here's what your code will look like if you want to add 64.
for(var/i=0 to 64)
if(varNumber < 999)
varNumber += addToNumber(varNumber)
///Vs.
varNumber = addToNumber(varNumber,64,999)


if you comment the functionality of each object, it won't matter how easy it is to look at, once you know what it does, it's just that much faster to do something. For instance, say you're making a game where you push a button, and the room rotates 45 degrees, and you win, and it gets boring really fast.

So you decide to add multiple buttons that rotate the room different amounts of degrees based on the player's color. If the player is red, pressing the blue button doesn't rotate the room, the green button rotates it 22.5 degrees, and the red button rotates it 45 degrees, and whoever rotates the room 360 degrees wins, would you rather this:
rotateRoom(button)
switch(team)//check the player's team/color
if(red)//if it's red, good, now lets check the button
switch(button)//checking the button
if(blue)rotateRoom(0)//blue? Darn, no rotation
if(green)rotateRoom(22.5)//green, yay rotate
if(red)rotateRoom(45)//red, super effective because of STAB (pokemon reference)
//do it for all the other teams too
//OR
rH//rotation handler
Red
var
list/tBRA=list(blue=0,green=22.5,red=45)//team button rotation associations
multiplier=1//now you can have power ups, wewt
//assign the user a red rotation handler
//..... later on somewhere else in the code
rotateRoom(button)
rotateRoom(rH.tBRA[button])//multiply it by the multiplier for power upz, yay

right now the first example has less lines (wait after actually looking at the code, it doesn't), but say you want more teams? cyan, beryl, and violet (which are just blue, green, and red again basically but you get the gist), in the second example all you have to do is add a new rotation Hander type, in the first example, you have to not only make a new if clause in the switch statement, but you have to add to all previous if-clauses, and let's say you're also rotating somewhere else, like, when the user steps on a certain tile, lets copy and paste that huge block of code there as well, code many more lines than it needs to be.

The use of objects is not exactly necessary, but do you want the variables for your mob to be clustered up in different files looking like an NBOTLs file, or datums with their -own- variables and functionality. (Not to mention this is just in general how it is usually done. You could make a game where every proc is attatched to one object if you want, but do you know how ugly it would be?)
GreenMonkey wrote:
I figured I'd start along the lines of mockups and design documents (of course) but my real question is what part of the game do the rest of you begin working on first? The log in system, combat, story modes, huds... Or do you start implementing from where the game starts and proceed adding things in the direction of the story as needed?

Implement the fun parts first and add the non-fun parts only as they're needed. Combat is fun, making an interface and HUD isn't. Make combat first and as you work on it, add the necessary interface/HUD elements. I see a lot of DM developers do the opposite - they make the interface and login parts first, then they start to run out of steam before they have any of the fun parts made.
In response to Forum_account
I do actually develop in the way FA just described, but I'm starting to question that method.
In response to Ill Im
Ill Im wrote:
So you decide to add multiple buttons that rotate the room different amounts of degrees based on the player's color. If the player is red, pressing the blue button doesn't rotate the room, the green button rotates it 22.5 degrees, and the red button rotates it 45 degrees, and whoever rotates the room 360 degrees wins, would you rather this:
> rotateRoom(button)
> switch(team)//check the player's team/color
> if(red)//if it's red, good, now lets check the button
> switch(button)//checking the button
> if(blue)rotateRoom(0)//blue? Darn, no rotation
> if(green)rotateRoom(22.5)//green, yay rotate
> if(red)rotateRoom(45)//red, super effective because of STAB (pokemon reference)
> //do it for all the other teams too
> //OR
> rH//rotation handler
> Red
> var
> list/tBRA=list(blue=0,green=22.5,red=45)//team button rotation associations
> multiplier=1//now you can have power ups, wewt
> //assign the user a red rotation handler
> //..... later on somewhere else in the code
> rotateRoom(button)
> rotateRoom(rH.tBRA[button])//multiply it by the multiplier for power upz, yay
>

right now the first example has less lines (wait after actually looking at the code, it doesn't), but say you want more teams? cyan, beryl, and violet (which are just blue, green, and red again basically but you get the gist), in the second example all you have to do is add a new rotation Hander type, in the first example, you have to not only make a new if clause in the switch statement, but you have to add to all previous if-clauses, and let's say you're also rotating somewhere else, like, when the user steps on a certain tile, lets copy and paste that huge block of code there as well, code many more lines than it needs to be.

The use of objects is not exactly necessary, but do you want the variables for your mob to be clustered up in different files looking like an NBOTLs file, or datums with their -own- variables and functionality. (Not to mention this is just in general how it is usually done. You could make a game where every proc is attatched to one object if you want, but do you know how ugly it would be?)

[Note: This ended up being a bit long. I don't think you gave bad advice, the examples are just too general to work.]

The underlined part isn't true. To add more teams you just need to add extra blocks to the outermost switch statement. You don't have to add to any of the existing sets of if statements. You'd only have to add to each set of ifs when you add a new button color.

Both methods that you show are equivalent. If you add a new button, think about what has to change. For the first method you have a switch for all the player colors and inside each one, a switch statement for the button colors. To add a button color you add a case to each inner switch. To add a player color you add a case to the outer switch. In the second example you have a child type of /rH for each player color and each /rH object has a list that contains each button color. To add a button color you add an entry to each list. To add a player color you add a new child type of /rH.

You can map the cases in the outer switch statement of the first example to the number of children of /rH and you can map the cases in the inner switch statements to the lists that each /rH object defines.

They're essentially equivalent and equally messy so I'm not sure which method was supposed to come out looking better. The comments are excessive and the variable names are cryptic. It doesn't help that you're dealing with two sets of colors (player colors and button colors) and don't have any way to tell which is which (ex: is /rH/Red the rotation handler for red buttons or red players?). Call the object /RotationHandler instead of /rH and you don't need the comment after it that says "//rotation handler". That comment only helps you when you're looking right at that bit of code. It doesn't help you later on when you need to create a rotation handler object and can't remember that you named it "rH".

And aside from all that, it seems a little silly because buttons will likely be objects (derived from /obj) because they're something you'd place on the map. You wouldn't need to create a datum for it.

I see where you were going with that. I think it'd work better with a more specific example.


for(var/i=0 to 64)
if(varNumber < 999)
varNumber += addToNumber(varNumber)
///Vs.
varNumber = addToNumber(varNumber,64,999)


For this case, I'd prefer to do just this:

varNumber += 64
if(varNumber > 999) varNumber = 999


When you look at that code there is no doubt about what it does. If you wrap it up in a proc, even with the most intuitive proc name it won't be as clear. You're on the right track, but the example is just too general. If we give the variable more meaning, you can see how defining a proc (or object) to handle things is beneficial:

mob
var
mana = 100
proc
fireball()
if(mana < 10) return
mana -= 10
world << "[src] casts fireball!"


Fireball costs 10 mana, so you check that the player has enough mana, then subtract it from their total, then cast the spell. This is all simple and straightforward, you don't need any comments to make it clear. However, what if you want to add a new ability that reduces the cost of spells by 50%? Imagine if you have 40 procs just like fireball() to handle different spells. You'd have to go back and change it to be like this:

mob
var
mana = 100
half_cost_spells = 1
proc
fireball()
if(half_cost_spells)
if(mana < 5) return
mana -= 5
else
if(mana < 10) return
mana -= 10
world << "[src] casts fireball!"


It wouldn't be fun to do that to every spell. You could do something like this:

mob
var
mana = 100
proc
mp_cost(m)
return m

fireball()
var/cost = mp_cost(10)
if(mana < cost) return
mana -= cost
world << "[src] casts fireball!"


If you initially coded it this way, to add the 50% mana reduction you only need to change the mp_cost() proc.

You could then take this a step further and create objects for each ability to show how you'd handle a variation on the mana reduction effect (ex: 50% mana cost for fire spells, or healing spells). The mp_cost() proc is sufficient when the reduction doesn't depend on the spell. If you create a datum for each spell and give it a cost() proc, the proc can take into account the player's status and the properties of the spell to decide the cost. That way you can use a very generic procedure for casting spells. You can also make use of inheritance to change how things work.