Thrive Game Development
Would you like to react to this message? Create an account in a few clicks or log in to continue.

Thrive Game Development

Development of the evolution game Thrive.
 
HomeHome  PortalPortal  Latest imagesLatest images  SearchSearch  RegisterRegister  Log inLog in  
Welcome new and returning members!
If you're new, read around a bit before you post: the odds are we've already covered your suggestion.
If you want to join the development team, sign up and tell us why.
ADMIN is pleased to note that this marquee has finally been updated.
ADMIN reminds you that the Devblog is REQUIRED reading.
Currently: The Microbe Stage GUI is under heavy development
Log in
Username:
Password:
Log in automatically: 
:: I forgot my password
Quick Links
Website
/r/thrive
GitHub
FAQs
Wiki
New Posts
Search
 
 

Display results as :
 
Rechercher Advanced Search
Statistics
We have 1675 registered users
The newest registered user is dejo123

Our users have posted a total of 30851 messages in 1411 subjects
Who is online?
In total there are 10 users online :: 0 Registered, 0 Hidden and 10 Guests

None

Most users ever online was 443 on Sun Mar 17, 2013 5:41 pm
Latest topics
» THIS FORUM IS NOW OBSOLETE
Miscellaneous Programming Questions Emptyby NickTheNick Sat Sep 26, 2015 10:26 pm

» To all the people who come here looking for thrive.
Miscellaneous Programming Questions Emptyby NickTheNick Sat Sep 26, 2015 10:22 pm

» Build Error Code::Blocks / CMake
Miscellaneous Programming Questions Emptyby crovea Tue Jul 28, 2015 5:28 pm

» Hello! I can translate in japanese
Miscellaneous Programming Questions Emptyby tjwhale Thu Jul 02, 2015 7:23 pm

» On Leave (Offline thread)
Miscellaneous Programming Questions Emptyby NickTheNick Wed Jul 01, 2015 12:20 am

» Devblog #14: A Brave New Forum
Miscellaneous Programming Questions Emptyby NickTheNick Mon Jun 29, 2015 4:49 am

» Application for Programmer
Miscellaneous Programming Questions Emptyby crovea Fri Jun 26, 2015 11:14 am

» Re-Reapplication
Miscellaneous Programming Questions Emptyby The Creator Thu Jun 25, 2015 10:57 pm

» Application (programming)
Miscellaneous Programming Questions Emptyby crovea Tue Jun 23, 2015 8:00 am

» Achieving Sapience
Miscellaneous Programming Questions Emptyby MitochondriaBox Sun Jun 21, 2015 7:03 pm

» Microbe Stage GDD
Miscellaneous Programming Questions Emptyby tjwhale Sat Jun 20, 2015 3:44 pm

» Application for Programmer/ Theorist
Miscellaneous Programming Questions Emptyby tjwhale Wed Jun 17, 2015 9:56 am

» Application for a 3D Modeler.
Miscellaneous Programming Questions Emptyby Kaiju4u Wed Jun 10, 2015 11:16 am

» Presentation
Miscellaneous Programming Questions Emptyby Othithu Tue Jun 02, 2015 10:38 am

» Application of Sorts
Miscellaneous Programming Questions Emptyby crovea Sun May 31, 2015 5:06 pm

» want to contribute
Miscellaneous Programming Questions Emptyby Renzope Sun May 31, 2015 12:58 pm

» Music List Thread (Post New Themes Here)
Miscellaneous Programming Questions Emptyby Oliveriver Thu May 28, 2015 1:06 pm

» Application: English-Spanish translator
Miscellaneous Programming Questions Emptyby Renzope Tue May 26, 2015 1:53 pm

» Want to be promoter or project manager
Miscellaneous Programming Questions Emptyby TheBudderBros Sun May 24, 2015 9:00 pm

» A new round of Forum Revamps!
Miscellaneous Programming Questions Emptyby Oliveriver Wed May 20, 2015 11:32 am


 

 Miscellaneous Programming Questions

Go down 
3 posters
AuthorMessage
Nimbal
Programming Team lead



Posts : 258
Reputation : 24
Join date : 2013-03-17
Age : 39
Location : Ratingen, Germany

Miscellaneous Programming Questions Empty
PostSubject: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 11, 2013 1:36 pm

This thread is for miscellaneous questions about Thrive's code. If you don't understand something, need input on implementing a feature / fixing a bug or have general questions about programming, ask away.

Note that if you run into problems while getting your development environment set up, the Development Troubleshooting thread is probably a better fit.
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 11, 2013 2:23 pm

Shouldn't the interfaces Touchable and TouchableValue have protection against instantiation like boost abstract inheritance or pure virtual destructor?

Also i see they use overloading of assignment to track changes, couldn't a derived class override the assignment operator themselves and ruin the concept? or is that an unwritten rule for values and components, not to do so?

EDIT: I think i'm missing a point about assignment, it would call both the assignment of the base and derived class right? sorry
EDIT 2: I see the lua script hud.lua is calling touch() explicitly, is that a lua only thing? i can't imagine it having to be explicit everywhere
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 11, 2013 3:03 pm

Another question!
I'm not seeing a clear distinction between what is written in lua scripts and what is written in c++. The agent class is made in c++ but the microbe and organelle classes are in lua. Also pretty engine specific (correct me if im wrong) things like hex grid and camera is in lua which confuses me a bit.

Could someone elaborate on which kind of code goes where?
Back to top Go down
Nimbal
Programming Team lead



Posts : 258
Reputation : 24
Join date : 2013-03-17
Age : 39
Location : Ratingen, Germany

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 11, 2013 3:23 pm

Hm, we could give Touchable a pure virtual destructor I guess. The thing is, a Touchable by itself is obviously useless. You wouldn't keep a pointer to a Touchable around anywhere, it would always be a pointer to a derived class so aliasing on destruction isn't really an issue. Although to be honest, I think the lack of a virtual destructor is an oversight because Touchable originally started out as a template.

Now, about that assignment operator in TouchableValue. Note that TouchableValue is a template, intended to "wrap" other data to make it touchable. For example, if you just want to have an integer and make it touchable, you can either do it the long way:

Code:

struct AnInteger : public Touchable {
    int value = 0;
};

AnInteger myInteger;
myInteger.value = 10; // Ugly member access for a single data field
myInteger.touch();     // Explicit touch() required
Or, with TouchableValue:
Code:

TouchableValue<int> myInteger;
myInteger = 10;   // Natural assignment with automatic touch()
That last line above is where the assignment operator comes into play. The operator just updates the internal value and automatically calls touch(). If the wrapped data structure is a type with its own assignment operator, this operator will be invoked in the first line of TouchableValue's assignment operator. So everything should work fine.

The explicit call to touch() in hud.lua is necessary because the "properties" field is not a simple TouchableValue, but a struct derived from Touchable (it's like the first, complicated variant above). The Touchable class can't know that you modified the data, since you don't assign to the Touchable itself, but assign to one of its members. As far as I know, there is no overloadable operator for the "dot" style member access.

Quote :

I'm not seeing a clear distinction between what is written in lua scripts and what is written in c++.
That's right. I expect there to be quite a few agent particles on screen during a normal game, and since the agent stuff was relatively straightforward to implement in C++, I skipped Lua alltogether for them. The microbe and organelle stuff on the other hand took some trial and error until I got it right (or should I say "working"?) which is so much more convenient in Lua. There's no hard and fast rule what's to be written in C++ and what in Lua. If in doubt, start in Lua. Chances are that it can be translated into C++ if necessary, but you'll definitely get results more quickly.

Also, please note that this is the first time for me using an entity / component approach. I'm still experimenting with how to use it to implement actual gameplay with interacting objects and such. So take all my ramblings with a spoonful of salt and if you find awkward code somewhere, don't read too much into it. It was probably me trying to use a screwdriver to drive the nail into a wall.
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 11, 2013 3:32 pm

Very enlightening, thanks!

I've been a bit nitpicky with the very few code antipatterns(?) i've found (mostly because they stand out with otherwise proper written code)

How do you want me/others to handle such minor details? Fix them ourselves and request a pull for a minor thing or post it somewhere like here for the author/someone privileged to fix it or just ignore it for now?
Back to top Go down
Nimbal
Programming Team lead



Posts : 258
Reputation : 24
Join date : 2013-03-17
Age : 39
Location : Ratingen, Germany

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 11, 2013 3:47 pm

A pull request with a fix would be very welcome.

Just a word of caution concerning git and pull requests. Ideally, you would create a so called "topic branch" for the intended fix, commit the change there, push the new branch to GitHub and then create a pull request referencing the branch. After that, you would switch to another branch again for further work and only check out the topic branch if it turns out that the fix requires more changes (pushing those will automatically update the pull request).

Realistically, you will regular get into situations where you work on something larger over several days. During the course of this work, you find several small issues and want to fix them. If you are really, really disciplined (I'm not), you'd need to follow this workflow to maintain clean, focussed pull requests that only handle exactly one issue:


  1. Commit or stash your changes in the "long" branch you are working in
  2. Checkout the master branch (or, at the moment, the prototype branch. I really need to merge that.)
  3. Create a new topic branch for the small issue you want to fix.
  4. Implement the fix and commit it
  5. Push the topic branch, create a pull request
  6. Checkout your original long branch
  7. Rebase the long branch onto the topic branch
  8. Continue working


This is obviously rather tedious and, as already mentioned, I usually don't follow it myself. For the moment, where there are rather few programmers actively working on Thrive, you can just commit the small fix in your long branch. Eventually, you'll make a pull request for it and the fix will come right along.
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 11, 2013 3:59 pm

Alright thanks!

And yeah i'm familiar (for the most part) with the tedious correct practises of git and i'll try and follow them strictly atleast initially!

Back to top Go down
PortalFan1000
Learner
PortalFan1000


Posts : 104
Reputation : 1
Join date : 2013-07-18
Age : 24
Location : This plane of existence

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 11, 2013 7:15 pm

This is not a question about the code itself, but I was wondering: where did you guys learn c++? Could you send me a link to a c++ tutorial site? Or a coding textbook? Anything to teach me c++? I know that there are scraps of code here but I would like to know the fundamentals.
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptySat Oct 12, 2013 6:04 am

Hey!

We already have a subforum for these kinds of questions that you should use:  https://thrivegame.canadaboard.net/f21-programming-language there's already a mini tutorial on that link a long with other stuff (Took me a while to find my way around here aswell)

But personally i had already learned C and loved fiddling with pointers, bitshifting ints, but i also loved OOP so c++ was a natural thing for me to look to, and so i went straight to more complex tutorials than you can probably handle if you don't know C already! One of the absolute best beginner c++ >>game<< tutorials that i used was lazyfoo.net/tutorials/SDL/ but i believe that does require some basic knowledge already. Once you get well familiar with the language you should grab a copy of Effective C++ by Scott Meyers for a lot of important details which are the things people have trouble with in c++.

It is a turbulent time for c++ as the language is rapidly iterating and getting better, so you'll learn some c++98 code that could be written better with c++11 (and in not too long, c++14) so you will have a choice between older high quality tutorials covering 98 and newer tutorials covering c++11 with less relearning things (I'm not sure how good people have been with updating their tutorials). Just google around!

Also note that you don't have to know c++ to do some programming on the project. You can do almost as much with our lua scripting integration, which we use to easily and quickly write useful code that'll work but is a little slower than it could have been in c++.
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 18, 2013 11:17 am

I've had some trouble with luabind.
In my attempts to understand and make luabind work with my class, I've tried making a simple test class and bind a single method, but i continue to get the error:
Code:
attempt to call global 'TestClass' (a nil value)
from lua whenever i try to use the class from a lua script (setup.lua)

What i've tried adding is:
In agent.h:
Code:
class TestClass {

public:
    static luabind::scope
    luaBindings();

    int
    memberTest();

};
In agent.cpp:
Code:

int
TestClass::memberTest(){ return 4;}

luabind::scope
TestClass::luaBindings() {
    using namespace luabind;
    return class_<TestClass>("TestClass")
        .def("memberTest", &TestClass::memberTest)
    ;
}
In microbe_stage/script_bindings.cpp:
Code:
luabind::scope
thrive::MicrobeBindings::luaBindings() {
    return (
        AgentAbsorberComponent::luaBindings(),
        AgentEmitterComponent::luaBindings(),
        TestClass::luaBindings() // <-- Here
    );
}
It seems from the error message that lua isn't properly notified of my TestClass. What am i missing?
Thanks
Back to top Go down
Nimbal
Programming Team lead



Posts : 258
Reputation : 24
Join date : 2013-03-17
Age : 39
Location : Ratingen, Germany

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 18, 2013 11:25 am

crovea wrote:

What am i missing?
The constructor:
Code:

luabind::scope
TestClass::luaBindings() {
    using namespace luabind;
    return class_<TestClass>("TestClass")
        .def(constructor<>())
        .def("memberTest", &TestClass::memberTest)
    ;
}
Although the error message you get doesn't quite fit, I would have expected it to complain about calling a table value, not a nil value. So either there's something else going on besides the missing constructor, or my understanding of luabind / Lua has a few problems.
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 18, 2013 1:06 pm

I had already tried adding a constructor with the same error

Any chance you could try and copy my code in and see if it works for you?
Or i can create a branch you can try, will take me a few mins
Back to top Go down
Nimbal
Programming Team lead



Posts : 258
Reputation : 24
Join date : 2013-03-17
Age : 39
Location : Ratingen, Germany

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 18, 2013 1:20 pm

A branch would be appreciated. Just so we can be sure it's the same code.
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyFri Oct 18, 2013 3:38 pm

Here's the branch!
https://github.com/jjonj/Thrive/tree/test-class-lua
Back to top Go down
Nimbal
Programming Team lead



Posts : 258
Reputation : 24
Join date : 2013-03-17
Age : 39
Location : Ratingen, Germany

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptySun Oct 20, 2013 11:49 am

I finally got around to testing this and... it works fine for me out of the box. The script prints "4" as expected, no Lua error whatsoever.
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptySun Oct 20, 2013 2:59 pm

Very strange. I'll try and rebuild thrives with cmake entirely and see if that helps!

EDIT: Yep that worked.
I'm using windows as you probably know, and therefore codeblocks. I only built the "install" build target once, and been recompiling with the "Thrive" target whenever i've been doing changes. Could it be that i need to rebuild "Install" for luabind changes?  

Perhaps a rundown of the different build targets could be useful for me and future devs!
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptySun Oct 20, 2013 3:22 pm

What i was missing was recompiling the "install" directory, which i didn't realize was necessary more than once.

Akwardly i'm probably more familiar with how to build a compiler than how to use one, so i haven't looked much into the build targets.

EDIT: Turns out that using the "Thrive" build target doesn't actually update the executable, so i guess i'll be using "install" exclusively then
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptySun Oct 27, 2013 7:12 pm

More questions time!


  1. With the codeblocks project, there are a lot of build targets (i assume these don't only exist for codeblocks, but are in cmake somehow). Which build targets are for what? I'm exclusively using "Install" as of now, do i ever want to use others?
  2. I assume the whole implementation struct idiom is to hide things like private variables from the interface, correct? also noticed that EntityManager has a method in its implementation (getComponentCollection) again is this because it's supposed to be private and hidden from the interface?
  3. I've seen some input checking done as
    Code:
    assert(entityId != NULL_ENTITY);
    is there any advantage to this other than brevity?
  4. In EntityFilter class' implementation the initEntity method has these two lines:
    Code:
    m_entities[id] = group;
    m_entities.insert(std::make_pair(id, group));
    don't they attempt to effectively do the same thing? (according to documentation of insert, it just does nothing from what i see here), am i missing something?
  5. 'detail' namespace is used in luabind and other than that only in EntityFilter, why here and why only here?
  6. And my most urgent question: ComponentGroup is defined like this
    Code:
    ComponentGroup = std::tuple<
            typename ExtractComponentType<ComponentTypes>::PointerType...
        >;
    Which to my understanding should expand into a tuple of component types. However, it is assigned to with a return value from:
    Code:
    entityManager->getComponent<RawType>(entityId);
    which returns a pointer to an actual component and not the type of a component. There seems to be a mismatch there, what am i missing?
Back to top Go down
Nimbal
Programming Team lead



Posts : 258
Reputation : 24
Join date : 2013-03-17
Age : 39
Location : Ratingen, Germany

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyMon Oct 28, 2013 3:50 am

crovea wrote:

Which build targets are for what?
I don't have a Windows environment handy right now, so I'm not sure which build targets Code::Blocks is offering. I think the only interesting ones at the moment are

  • install: Compiles the executable and copies it, along with all assets (textures, scripts, models, DLLs, etc) into the "dist" subdirectory of the build directory
  • clean: Deletes all object files in the build directory, causing a complete rebuild with the next invocation of the "build" (or "install") target. Mostly useful if you manage to confuse CMake about dependencies between source files, but this is very rare.
  • zip: Like "install", but also creates the archive "Thrive.zip" inside the build directory which contains everything necessary to run the game. I'm not sure if Code::Blocks offers this one.


crovea wrote:

I assume the whole implementation struct idiom is to hide things like private variables from the interface, correct?
Yep, that's the pimpl idiom. Everything that's private (except constructors, destructors and operators) can be put into the Implementation struct. That allows us to change stuff in the implementation without having to recompile everything that uses the class. It also has a (minor) performance penalty due to the additional indirection, but if we find that to become a problem, it's easy enough to remove.

crovea wrote:

I've seen some input checking
I'm not sure what you mean by "brevity". Are you thinking of throwing an exception instead? Usually, assertions are there to catch programmer errors (like forgetting to initialize a variable) while exceptions should be used to handle expected error situations that the programmer can't avoid any other way.


crovea wrote:

In EntityFilter class' implementation the initEntity method has these two lines
Oops. These are indeed redundant. The second one is a tiny bit faster because it skips the construction of a default pair along with a copy assignment. So the first line can be removed.

crovea wrote:

'detail' namespace is used in luabind and other than that only in EntityFilter, why here and why only here?
The detail namespace is commonly used to contain internal implementation stuff that's not important to the public interface of a class, similar to the pimpl idiom. Since EntityFilter is a template and all its code needs to be included by its users, we use the detail namespace to avoid polluting the global namespace with all those utility templates and functions. I can't speak for luabind's authors, but they probably have similar reasons. It's a template heavy library after all.

crovea wrote:

And my most urgent question: ComponentGroup is defined like this
I assume you're talking about these lines:
Code:

RawType* component = entityManager->getComponent<RawType>(entityId);
// ...
std::get<index>(group) = component;
Note the "std::get" in there. It returns a reference to the tuple's entry at the specified index. If std::tuple had an index operator (it doesn't), we could write this instead
Code:

group[index] = component;
Back to top Go down
crovea
Programming Team lead
crovea


Posts : 310
Reputation : 59
Join date : 2013-10-07
Age : 34
Location : Denmark

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyTue Oct 29, 2013 7:14 pm

Nimbal wrote:
I'm not sure what you mean by "brevity".
I mean as opposed to a big fat if statement to check input! I'm largely unfamiliar with Assert except for its semantics, it's obviously easier to write, but i was wondering what advantages it had other than that. I since looked it up and found it only does checking in debug mode which is awesome

Nimbal wrote:
Note the "std::get" in there.
I'm afraid you missed my question and rightly so. I know about std::get and even why it has to be a global function (to prevent ugly syntax basically). I now realize i had simply confused myself in a mildly embarrasing way!

Thanks for the answers
Back to top Go down
Nimbal
Programming Team lead



Posts : 258
Reputation : 24
Join date : 2013-03-17
Age : 39
Location : Ratingen, Germany

Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions EmptyWed Oct 30, 2013 3:23 am

crovea wrote:
I'm afraid you missed my question and rightly so.
After rereading your original question about three times, I finally got it. Chuckles were had, but we never need to speak of this incidence again if you don't want to.
Back to top Go down
Sponsored content





Miscellaneous Programming Questions Empty
PostSubject: Re: Miscellaneous Programming Questions   Miscellaneous Programming Questions Empty

Back to top Go down
 
Miscellaneous Programming Questions
Back to top 
Page 1 of 1
 Similar topics
-
» Miscellaneous Bugs And Questions That Don't Deserve Their Own Thread Thread
» Miscellaneous Bugs And Questions That Don't Deserve Their Own Thread Thread
» Programming Team
» Miscellaneous Bugs And Questions That Don't Deserve Their Own Thread Thread
» New-ish to programming, what should I do?

Permissions in this forum:You cannot reply to topics in this forum
Thrive Game Development :: Development :: Programming-
Jump to: