Author Topic: Writer needs Coder  (Read 34729 times)

Paul Jeffries

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 257
  • Karma: +1/-0
    • View Profile
    • Vitruality.com
Re: Writer needs Coder
« Reply #15 on: September 15, 2014, 07:30:44 PM »
I think everybody else has already covered the 'give up trying to convince anybody to make your game for you' angle, so I'll add some advice on learning to do it yourself:

If you find C++ too difficult then don't use C++.  It's a great language if you know what you're doing but it's absolutely the worst language to pick for somebody who (to be blunt) is too lazy to learn how to use it properly.  The good news is there are plenty of other languages and game making tools which are a lot easier to get to grips with.  Python is a pretty nice language for beginners and it does a lot of stuff for you that C++ doesn't - you'll definitely be able to learn it and use it a lot faster.  If you really can't deal with that then there are other things like Gamemaker out there that you could try.

TheCreator

  • Rogueliker
  • ***
  • Posts: 370
  • Karma: +0/-0
    • View Profile
    • Fame
    • Email
Re: Writer needs Coder
« Reply #16 on: September 16, 2014, 06:10:03 AM »
How would you know?

I don't. On the other side, you haven't provided anything to make anyone think that the game(s) you are working on is great.
Fame (Untitled) - my game. Everything is a roguelike.

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Writer needs Coder
« Reply #17 on: September 16, 2014, 07:37:26 AM »
I don't. On the other side, you haven't provided anything to make anyone think that the game(s) you are working on is great.

No wonder you have difficulties to find team members. Then again, so do I, because I'm even harder to people than you. But I'm also different, because it's really, really difficult to find people who are in the same level with me, you know.

guest509

  • Guest
Re: Writer needs Coder
« Reply #18 on: September 19, 2014, 10:41:30 PM »
I think everybody else has already covered the 'give up trying to convince anybody to make your game for you' angle, so I'll add some advice on learning to do it yourself:

If you find C++ too difficult then don't use C++.  It's a great language if you know what you're doing but it's absolutely the worst language to pick for somebody who (to be blunt) is too lazy to learn how to use it properly.  The good news is there are plenty of other languages and game making tools which are a lot easier to get to grips with.  Python is a pretty nice language for beginners and it does a lot of stuff for you that C++ doesn't - you'll definitely be able to learn it and use it a lot faster.  If you really can't deal with that then there are other things like Gamemaker out there that you could try.

I use Gamemaker. It's totally doable but you DO need to know how to code. Absolutely. It turns a TON of chores into easy mode though. Hell I've been using it so long I barely remember how to begin making a game in C or Pascal.

guest509

  • Guest
Re: Writer needs Coder
« Reply #19 on: September 19, 2014, 10:43:01 PM »
Also, to the OP. I have hundreds of pages of idea for games. I think your list seems like ideas to make Angband/Crawl better.

With effort you can tweak the heck out of Angband without being a dynamite coder.

Brigand

  • Rogueliker
  • ***
  • Posts: 93
  • Karma: +0/-0
    • View Profile
Re: Writer needs Coder
« Reply #20 on: September 19, 2014, 11:09:02 PM »
I use Gamemaker. It's totally doable but you DO need to know how to code. Absolutely. It turns a TON of chores into easy mode though. Hell I've been using it so long I barely remember how to begin making a game in C or Pascal.

Gamemaker is really great and does make anything to do with 2d graphics a snap (you can't beat it for rotating sprites, creating easy particle emitters, making media a snap, etc), but it has some strange limitations. Arrays are pretty limited, and are just about the only data structure you have to work with. There are absolutely no advanced data structures of any kind (no objects or even types/structs, which is a major bummer). By extension of no objects, there are no pointers, meaning no (easily implemented) linked lists, queues, trees, etc. I've seen a few extensions people have coded for it, but they are pretty wonky.

That being said, if you ignore the drag and drop interface, GML is at least vaguely similar in structure to C++ and Java, so it's a good starting point if you are wanting to learn.

I've got a hybrid Star Control-roguelike game around 50% done in Gamemaker, and the ease of the things it does well outshines its limitations. If they would just add some better data structures, it would clearly be the way to go for any 2d project, roguelikes included.

guest509

  • Guest
Re: Writer needs Coder
« Reply #21 on: September 21, 2014, 03:49:59 AM »
Here are all of those data structures Brigand said aren't doable.

http://docs.yoyogames.com/source/dadiospice/002_reference/data%20structures/index.html


Maybe I just misunderstood what he was saying. But all of those things are in there.

Zireael

  • Rogueliker
  • ***
  • Posts: 604
  • Karma: +0/-0
    • View Profile
Re: Writer needs Coder
« Reply #22 on: September 21, 2014, 09:14:35 AM »
I will recommend T-Engine as I tend to do. I knew NOTHING of programming when I started on Veins in June 2013, so a year and three months ago.

T-Engine is incredibly easy to pick up and you can pick apart ToME and other published modules to proceed.

Brigand

  • Rogueliker
  • ***
  • Posts: 93
  • Karma: +0/-0
    • View Profile
Re: Writer needs Coder
« Reply #23 on: September 21, 2014, 11:35:00 AM »
Here are all of those data structures Brigand said aren't doable.

http://docs.yoyogames.com/source/dadiospice/002_reference/data%20structures/index.html


Maybe I just misunderstood what he was saying. But all of those things are in there.


sorry, I am pretty unclear in how I wrote that. You can always create these structures using arrays and filling them with indexes to the object; you just aren't  able to create a user defined object with fields and methods (and pointers to other user defined objects) - which is why I put easily implemented in quotes. Only having arrays to work with is wonky.

But, It does appear that they are constantly adding new features to gml, so it may be in the future. Maybe they have recently added this, but the last version I bought did not have oop support.

guest509

  • Guest
Re: Writer needs Coder
« Reply #24 on: September 22, 2014, 12:20:55 AM »
Did you read that link? Gamemaker includes all the functions required to manipulate the following:

"stacks, queues, lists, maps, priority queues, and grids."

I never use them, I stick with arrays and use tons of heredity, but they are in there. Not just arrays.

Or are you saying that GM handles them poorly? Is that it? I wouldn't know...I do know other GM users that make use of them extensively. But maybe they are just used to the clunkiness.


There's another program coming along too, I've not used it, but it's a competitor to Gamemaker:
https://www.scirra.com/

Also, of course, T-Engine.

Brigand

  • Rogueliker
  • ***
  • Posts: 93
  • Karma: +0/-0
    • View Profile
Re: Writer needs Coder
« Reply #25 on: September 22, 2014, 02:33:58 PM »
Did you read that link? Gamemaker includes all the functions required to manipulate the following:

"stacks, queues, lists, maps, priority queues, and grids."

I never use them, I stick with arrays and use tons of heredity, but they are in there. Not just arrays.

Or are you saying that GM handles them poorly? Is that it? I wouldn't know...I do know other GM users that make use of them extensively. But maybe they are just used to the clunkiness.


There's another program coming along too, I've not used it, but it's a competitor to Gamemaker:
https://www.scirra.com/

Also, of course, T-Engine.

I did read that link, but I must be explaining it poorly. I'll give you a simple example (that is probably already obvious to you):

Most OOP roguelikes have an 'actor' class, or something similar like that. Lets say you want to add a new monster to the list (or queue, or attack, or whatever) - it can be a new action on the stack, a new monster in the list, whatever, it doesn't matter: actor.next = new actor();

That's it. You can add a constructor that will instantiate the actor for you with default behaviors, and you can pass the monster type to direct the constructor at creation time (eg, monster.next=new actor("goblin");) If you want to delete a monster in the middle of the list, its as simple as

monster.next = monster.next.next;

or if its at the end of the list

monster.next = null;

and you're done - if the monster you remove no longer has an active reference, the garbage collector frees that memory (some languages make you do it yourself, but you can have a destructor to take care of the clean up - either way its a hell of a lot better way to do it than what follows). You can pass an object reference wherever you want, and each object can have whatever methods you want attached to them: (monster.take_damage(3);) You know all this - this is programming 101 stuff.

Contrast this with GML, and using arrays for everything. A monster then is referred to explicitly by an index into a bunch of arrays....a bunch of arrays that cannot be easily redimensioned, and have memory reserved whether they are used or not.

name[3]='goblin';
hps[3]=10;
defense[3]=4;
inventory[3,1]='sword';
inventory[3,2]='helmet'

..... etc....

You now either have to have a capped number of actors, or reserve memory for a lot of creatures you may not be using. You have to iterate through the list to find what you want each time (not a huge big O, but it adds up) God forbid you want to copy a creature...then you have to laboriously copy every single array at a specific index, and unless you keep a position variable, iterate through the array each time to find a free index. If you add a field later, you have to go through all your code and update in every single place. There's no cohesiveness to the code. You have to iterate through an entire array every pass to see if there is an active actor at that index  UNLESS you compact the list of actors down and iterate through a set number each time - which requires copying arrays to remove gaps in the list every time a creature dies/leaves/whatever. And if you do that, it invalidates EVERY data structure you are using that references creatures by indexes unless you go clean them up every time too.

Yes you can do everything with GML's array based data structures that you can with OOP, but it would be a hell of a lot easier if they just allow you to make your own classes/objects, which is the entire point of what I'm saying. Trying to program a balanced binary tree using arrays? Holy crap, you could, but it would not be fun. 'Easily implemented' is the keyword. Even worse, GML also has arrays restricted to 2 indexes (2D)... full stop.  As opposed to a simple list/queue/whatever of objects with pointers to other objects in the structures which you can do in 30 secs with no support coded needed.
 
At the end of the day, its half a dozen of 1, or six of the other. If you program in a conventional OOP language (Java, C++, etc), you get the massive flexibility of an object oriented language but you have to write or use a potentially hairy 2d library (though there are some good choices out there that make it easy); if you use GML, you get AWESOME 2d graphics capabilities at the cost of being forced to use arrays for everything. There's another thread going now that talks about a system with heavy object interaction that might be worth looking at that you just couldn't do with arrays (you can't attach a behavior to an array index like you can with a class.)

If they have added this to the latest GML, then I stand corrected, and redact all of what I have said, but as of the last version I bought, none of this existed. It is a work in progress, and they have some really new nifty features each time I log in, but I haven't bought all the expensive available modules - I bought the first level package that unlocks all the standard features, but none of the add-ons. And whan I bought it, it wasn't called Gamemaker Studio, it was still Gamemaker 8.

guest509

  • Guest
Re: Writer needs Coder
« Reply #26 on: September 22, 2014, 02:48:01 PM »
Oh yeah, definitely. GM isn't built like that at all. If you are used to using those other methods it can be a big head switch.

I'd almost forgotten about a lot of that stuff, I've not coded outside of GM in at least a decade, besides going through code looking for errors for people.

EDIT: To the thread starter, you might want to look into the program called Construct 2. It costs money, but there is a free version. It is a drag and drop heavy system with no actual coding going on.

Brigand

  • Rogueliker
  • ***
  • Posts: 93
  • Karma: +0/-0
    • View Profile
Re: Writer needs Coder
« Reply #27 on: September 22, 2014, 03:01:36 PM »
I'd almost forgotten about a lot of that stuff, I've not coded outside of GM in at least a decade, besides going through code looking for errors for people.

Nothing wrong with that - in spite of its limitations, I like it a lot too. If they added true OOP support, as far as my hobby stuff goes, I probably would just use it exclusively too.

Bear

  • Rogueliker
  • ***
  • Posts: 308
  • Karma: +0/-0
    • View Profile
Re: Writer needs Coder
« Reply #28 on: September 22, 2014, 06:30:08 PM »
It's Interesting and odd to read the comments about GM and compare them to the framework I've evolved for my own use. 

I started with a lot of pointer based dynamically allocated structures of the type Brigand evidently prefers - but discovered that most of the central elements of the game (actors and events and the schedule and the map) need to have many references to each other, in places that depend on the semantics of individual subtypes of those classes - so deallocating anything WITHOUT leaving references to it somewhere is very difficult and gets more difficult the more different kinds of things you have.  You wind up having to walk virtually the full game's data structure deleting references every time you want to delete anything.  Otherwise, you wind up with dynamically allocated data containing references to deallocated things.  If your references happen to be pointers, that's bad for two reasons, because there are two different kinds of bugs it can cause when you try to refer to the object the stale pointer points at.  First, you can crash, which is bad, but you can also wind up referring to  things allocated after the things the original pointers pointed at were deallocated, which is worse.  Also, pointers were an extra headache for save-and-restore functionality, because you had to swizzle all the pointers to get a restored game where the pointers mean the same thing as the pointers in the saved game did. 

So I eventually abstracted dynamic allocation, using a manager class for each data type.  Now when I say New_Actor(), the manager for actors decides where it's going to keep the new actor and returns a reftype.  The manager handles allocation, and keeps a pointer (the ONLY pointer to that actor to live in a dynamically-allocated data type) in a hash table keyed by the reftype value.  A reftype value, unlike a pointer value, is never reused, so I don't have to worry about aliasing.  I can deallocate on command, without worrying about crashes caused by following stale pointers.  When something hands the manager a stale reftype, it returns a null value without crashing, which can be checked for and handled at the call site.  Finally reftypes mean the same thing in a restored game that they meant in the saved game with no need for pointer swizzling; the new pointer value, whatever it is, is keyed by the same reftype value inside the actor manager, so the rest of the code, which handles data structures that contain only reftypes, never pointers, need never worry about it.

There's no "maximum number of actors," nor "vast amounts of wasted space", both because the data managers do dynamically resize the hash tables at need.  This also takes care of "compacting the array", and does not require walking data structures changing reftypes stored in game data to  refer to new array locations when it happens.   The complexity cost is an O(1) hash table lookup whenever a routine needs to acquire an actual pointer to data, and that has not been a noticeable burden. 

Anyway, the rules are simple. In any dynamically allocated data, you store reftypes rather than pointers.  When you actually need a pointer, you use the reftype to look it up.  Any time you use a reftype to look up a pointer, you check to see whether the pointer is NULL.  If it is,  that datum no longer exists.

And, um, underneath it all....  the data manager classes use hash tables which are implemented in terms of arrays.  Which are what GM uses....  and what annoys Brigand.

One man's drink is another man's poison?

Brigand

  • Rogueliker
  • ***
  • Posts: 93
  • Karma: +0/-0
    • View Profile
Re: Writer needs Coder
« Reply #29 on: September 22, 2014, 07:27:34 PM »
It's Interesting and odd to read the comments about GM and compare them to the framework I've evolved for my own use. 

I started with a lot of pointer based dynamically allocated structures of the type Brigand evidently prefers - but discovered that most of the central elements of the game (actors and events and the schedule and the map) need to have many references to each other, in places that depend on the semantics of individual subtypes of those classes - so deallocating anything WITHOUT leaving references to it somewhere is very difficult and gets more difficult the more different kinds of things you have.  You wind up having to walk virtually the full game's data structure deleting references every time you want to delete anything.  Otherwise, you wind up with dynamically allocated data containing references to deallocated things.  If your references happen to be pointers, that's bad for two reasons, because there are two different kinds of bugs it can cause when you try to refer to the object the stale pointer points at.  First, you can crash, which is bad, but you can also wind up referring to  things allocated after the things the original pointers pointed at were deallocated, which is worse.  Also, pointers were an extra headache for save-and-restore functionality, because you had to swizzle all the pointers to get a restored game where the pointers mean the same thing as the pointers in the saved game did. 

So I eventually abstracted dynamic allocation, using a manager class for each data type.  Now when I say New_Actor(), the manager for actors decides where it's going to keep the new actor and returns a reftype.  The manager handles allocation, and keeps a pointer (the ONLY pointer to that actor to live in a dynamically-allocated data type) in a hash table keyed by the reftype value.  A reftype value, unlike a pointer value, is never reused, so I don't have to worry about aliasing.  I can deallocate on command, without worrying about crashes caused by following stale pointers.  When something hands the manager a stale reftype, it returns a null value without crashing, which can be checked for and handled at the call site.  Finally reftypes mean the same thing in a restored game that they meant in the saved game with no need for pointer swizzling; the new pointer value, whatever it is, is keyed by the same reftype value inside the actor manager, so the rest of the code, which handles data structures that contain only reftypes, never pointers, need never worry about it.

There's no "maximum number of actors," nor "vast amounts of wasted space", both because the data managers do dynamically resize the hash tables at need.  This also takes care of "compacting the array", and does not require walking data structures changing reftypes stored in game data to  refer to new array locations when it happens.   The complexity cost is an O(1) hash table lookup whenever a routine needs to acquire an actual pointer to data, and that has not been a noticeable burden. 

Anyway, the rules are simple. In any dynamically allocated data, you store reftypes rather than pointers.  When you actually need a pointer, you use the reftype to look it up.  Any time you use a reftype to look up a pointer, you check to see whether the pointer is NULL.  If it is,  that datum no longer exists.

And, um, underneath it all....  the data manager classes use hash tables which are implemented in terms of arrays.  Which are what GM uses....  and what annoys Brigand.

One man's drink is another man's poison?

What your saying may be true, but the conversation stops for me at "need to have many references to each other". As you say, as soon as you start placing pointers everywhere, you end up with memory leaks - you get circular references that don't get garbage collected but you cant reference, stale references that are pointing at some object that is now out of scope - the object continues to exist because "something" is pointing at it, or the most fun bug to track down, the null pointer reference (which is admittedly hard to debug in dynamically allocated system, so that it a point for doing it with arrays).
Quote
deallocating anything WITHOUT leaving references to it somewhere is very difficult and gets more difficult the more different kinds of things you have

I keep it simple - items/inventory instances point at/are pointed at by an actor or a SINGLE map manager (for items laying on the ground) and that's it - the destructor for the actor simply points the item objects back at the map manager (the items fall to the ground) which also makes it easy to determine what gets displayed. Actors are in an action queue, eliminating the need for a schedule, and that's it. The only cross pointers you get are actors targeting other actors. The first thing I do in the destructor is pass the 2 lists a single time, and set the pointers that refer to the dying object to null before the object goes out of scope - it takes literally 1 line of code in a do/while loop, and eliminates the need for a manager class as well as null pointer references.

Yes, I do have to peel off the objects when I save and then write them out manually, but that all occurs in one easily maintainable spot (and what other way would you do it anyways?). Each object has a unique id that sets the pointers back up when I load the game. Its an easy way to do it that I think the OP can grok as he is learning a language. (swizzling as you say)

Maybe I'm unrealistically biased, but I just like super encapsulation with a one-way pointer system; I definitely have produced spaghetti before, going overboard with pointers, but its something everyone does as they are learning. (I should add I usually avoid 2-way pointer structures for the very reasons you described; eg, doubly linked lists)

My entire argument is based on simplicity of coding; of course doing it the way you described produces in a more robust system that results in more stable memory use and eliminates null pointers/run time reference errors, but I don't think this is a beginner task. (After all, GML is supposed to be newbie friendly with its drag and drop IDE.) I don't even know if it's possible to do it this way in GML, but I could be mistaken.

Either way it goes, I think the real take away from all this conversation is that the OP quit reading this thread a long time ago (either scared off, or went elsewhere when told to do it themselves.)
« Last Edit: September 22, 2014, 07:44:25 PM by Brigand »