• Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

3905 Excellent

About TheComet

  • Rank
    Advanced Member

Personal Information

  • Interests


  • Github
  • Twitch
  1. Problem with sleep

    As someone with this exact problem, I can confirm that staying away from screens, reading books, and not eating food 2 hours before bed helps (digestion keeps you awake). If you are considering sleeping pills, don't abuse them. They can help you get into the correct rhythm, but you really shouldn't need to use them for more than a week. Perhaps the most important thing for a good rhythm is getting up at the same time every day, no matter how you feel. Do whatever it takes to get out of bed at 08:00 or whatever, even on weekends.
  2. Why A.I is impossible

    On a more serious note, here are my 2 cents to the whole "subjective experience" discussion: I think it's easy to look at a system that behaves slightly differently than ourselves and go "pff, this thing is clearly not conscious". We've seen this being said about animals and now we're seeing it being said about computers and I don't think it's as clean cut as you might initially think. Self consciousness is the ability to observe and react to ones own actions. Who is to say that a PID control loop is not "self conscious"? You might laugh at this idea, but if you think about it, what arguments can you really make against it? Are living systems not just a highly complex composition of millions of self-regulatory systems, where the thing that identifies as "me" is at the very top of the hundreds of layers? Who is to say that each of those systems is not self conscious in its own way and has its own subjective experience? When a thought enters your mind, you proceed to think about that thought, and think about thinking about that thought, and so forth. This process of self-thinking is some kind of feedback loop, which relies on the results of many "lower level" feedback loops, right down to the molecular level (or perhaps even further, who knows). This is also the reason why you see fractals when you do psychadelics, because systems with feedback loops are recursive, but that's beside the point. And for that matter, who is to say we are at the "top" of this chain? Humans form structures such as societies or companies, which also have an ability to self observe and react accordingly. Who is to say companies aren't conscious? Or the environment isn't conscious? Or the billions of devices connected to the internet haven't formed a self-conscious "brain" of some kind? Or the galaxy isn't one gigantic conscious super-organism? It might be very different from our own consciousness, but again, that doesn't necessarily make it unconscious. Randomness is another point of discussion. Must a self-conscious system necessarily have an element of randomness? There are numerous psychological experiments that predict how a human will respond to specific situations with an astoundingly high degree of accuracy (see: Monkey ladder experiment, see: Stanford Prison experiment, see: Brain scans that predict your behaviour better than you can) It almost seems like we are under an illusion of being in control and perhaps the actions we take are for the most part predetermined. Whether this is true or not is of course unknown, but the real question is: Does it matter? If so, why? Just because it appears that human consciousness is not computable doesn't mean it's random. It is very obviously highly organized, otherwise you'd be unable to respond to this thread, or even have an experience for that matter. So: If I were to add an RNG to my Turing machine to make it less predictable and thus "more conscious", isn't that taking a step back from the actual problem?
  3. Why A.I is impossible

    Okay so just add some RNG to your turing machine. Problem solved!
  4. Manual syntax trees

    I thought this thing I wrote might be a worthy candidate for a coding horror. Expression* SymbolicMatrix::determinant3x3() const { /* * Given the matrix * * / a b c \ * A = | d e f | * \ g h i / * * The determinant can be calculated with: * * det(A) = (aei + bfg + cdh) - (gec + hfa + idb) * * The entries in the matrix are stored such that a=0, b=1, c=2, etc. */ return Expression::make(op::sub, // (aei + bfg + cdh) - (gec + hfa + idb) Expression::make(op::add, // aei + bfg + cdh Expression::make(op::add, // aei + bfg Expression::make(op::mul, // aei Expression::make(op::mul, // ae entries_[0]->clone(), // a entries_[4]->clone()), // e entries_[8]->clone()), // i Expression::make(op::mul, // bfg Expression::make(op::mul, // bf entries_[1]->clone(), // b entries_[5]->clone()), // f entries_[6]->clone())), // g Expression::make(op::mul, // cdh Expression::make(op::mul, // cd entries_[2]->clone(), // c entries_[3]->clone()), // d entries_[2*3+1]->clone())), // h Expression::make(op::add, // gec + hfa + idb Expression::make(op::add, // gec + hfa Expression::make(op::mul, // gec Expression::make(op::mul, // ge entries_[6]->clone(), // g entries_[4]->clone()), // e entries_[2]->clone()), // c Expression::make(op::mul, // hfa Expression::make(op::mul, // hf entries_[7]->clone(), // h entries_[5]->clone()), // f entries_[0]->clone())), // a Expression::make(op::mul, // idb Expression::make(op::mul, // id entries_[8]->clone(), // i entries_[3]->clone()), // d entries_[1]->clone()))); // b } All jokes aside, how would one make this look better?
  5. I'd add methods for doing that to you serializer/deserializer classes: class Deserializer { /* ... */ void readFloatArray(std::vector<float>* v) { size_t arraySize = readUInt(); // we saved the size so we know how much to read v->resize(arraySize); for (size_t i = 0; i < arraySize; ++i) v->push_back(readFloat()); } /* ... */ }; class Serializer { /* ... */ void writeFloatArray(const std::vector<float>& v) { writeUInt(v.size()); // save size, for reading back for (size_t i = 0; i < v.size(); ++i) writeFloat(v[i]); } /* ... */ }; Then, to read the 100 floats: File file; file.open("whatever.dat"); std::vector<float> myFloats; file.readFloatArray(&myFloats);
  6. For some reason the compiler cannot resolve which base class set() is to be called (someone more experienced might be able to shed light on the exact issues here). The solution seems to be to do something like this: template <class ...Ts> class entity : public component<Ts>... { public: entity() {}; ~entity() {}; template <class U> void set(const U& data) { component<U>::set(data); } };
  7. A bit late to the party, but have a look at this pattern, I think it's a really elegant way to serialize binary data. Also have a read of section 7.4 in Beej's guide to network programming about data serialization and how to make binary data portable here: http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#serialization struct Serializer { // To be implemented by files, buffers, network connections, or whatever stream you want to write to virtual size_t write(void* data, size_t size) = 0; bool writeUByte(unsigned char byte) { return write(&byte, sizeof(byte)) == sizeof(byte); } bool writeUInt(uint32_t i) { return write(&i, sizeof(i)) == sizeof(i); } bool writeFloat(float f) { uint32_t buf = htonf(f); // Convert to portable representation return writeUInt(buf); } bool writeVector3(const Vector3& v) { bool success = true; success &= writeFloat(v.x); success &= writeFloat(v.y); success &= writeFloat(v.z); return success; } // Etc. }; Basically you write methods for all of the different types of data you want to have serialized in your program (maybe you have buffers, strings, quaternions...) Then you can implement the serializer for a file like so: struct File : public Serializer{ size_t write(void* data, size_t size) override { return fwrite(fp_, data, size); } private: FILE* fp_; }; Or you could implement the serializer for a buffer: struct Buffer : public Serializer{ size_t write(void* data, size_t size) override { for (size_t i = 0; i != size; ++i) buffer_.push_back(((char*)data)[i]); // horribly slow way } private: std::vector<char> buffer_; }; You get the idea. The point is, the code writing the data doesn't have to care about what it's writing too and it also doesn't have to care about endianness or type sizes, because that's handled by Serializer. Then, similarly, you write a Deserializer to handle reading the data back: struct Deserializer { virtual size_t read(void* dest, size_t size) = 0; unsigned char readUByte() { unsigned char buf; read(&buf, sizeof(buf)); return buf; } uint32_t readUInt() { uint32_t buf; read(&buf, sizeof(buf)); return buf; } float readFloat() { uint32_t buf = readUInt(); return ntohf(buf); } Vector3 readVector3() { Vector3 v; v.x = readFloat(); v.y = readFloat(); v.z = readFloat(); return v; } }; Example usage would be: struct Vector3 { float x, y, z; }; int main() { Vector3 v = {1.0f, 4.0f, 7.0f}; File ser; ser.open("whatever.dat"); ser.writeVector3(v); ser.close(); File des; des.open("whatever.dat"); v = des.readVector3(); des.close(); }
  8. Newbie, Need Help..

    If you were me and saw this thread with 1. An unhelpful title 2. A post that doesn't ask a question How would you respond? It's like going into a car repair shop without a car and saying "I have a problem..." and then just awkwardly standing there. Please ask an actual question next time.
  9. @_Silence_ that would be less than optimal and defeating the purpose of the dirty flag in the first place. In practice, doSomethingThatChangesResult() can be called anywhere from 2 to thousands of times before getResult() is called. With your suggestion, the time consuming calculation would needlessly be performed thousands of times instead of just once.
  10. I've run into this problem a few times in my own code and in code from open source projects and would like to hear your op-onyos about it. It basically looks like this: class Foo { float cachedResult_; bool dirty_; public: void doSomethingThatChangesResult() { dirty_ = true; /* ...*/ } float getResult() { if (dirty_) cachedResult_ = doComplexCalculation(); return cachedResult_; } }; The problem is that you cannot use Foo::getResult in any other methods that are const. As a client of this class, you don't necessarily care about whether the result is cached or not (or maybe you should be caring, and that is the core of this apparent issue?) Is it acceptable to make dirty_ and cachedResult_ mutable in exchange for making getResult() const?
  11. I'm going to go ahead and say yes, there is such a thing. In the brief period of my life where I actually completed a game, I went looking for voice actors on youtube. I was pleased to find an overwhelming number of people who were pretty much unknown (they have 10-100 subscribers or something) and yet their voices sounded amazing. I found a girl to voice my female character for a total price of free, and it sounded really good.
  12. Java game from 1998

    I suggest hopping onto #graal on irc.stinkybear.net and asking the guy personally there.
  13. Using DOT to Debug Data Structures

    Hi! It's fairly stable at this point (as in, it doesn't crash, there are no memory leaks, it correctly calculates results in every situation). The biggest API change in the near future will be that positions and rotations are specified in local space rather than in global space (which is currently the case). Other than that I don't see the API changing. Functionally, the way it was designed introduces some major flaws (none of which you will not run into if you don't try to solve nested trees with multiple end effectors). I'm still working on getting those fixed.
  14. It should be pointed out that doing it this way will introduce new, harder to solve design issues into your code that can potentially explode into a huge mess. For instance: Draw order of different entities is no longer defined. Before, you could be certain that no matter how many Cars you added and removed and how many Boats you added and removed, all of your cars would always draw before boats. With the Entity base class, this is no longer the case. It could be that Cars and Boats and Boars and Goats are all interleaved in weird ways and thus rendered/updated as such. Why is this an issue? Well, if you want to put cars on your boats and properly calculate collision for this (for example), while updating one of your car entities, the boat your car is on is in an unknown state. Was the boat already updated? Or is it still waiting to be updated? Half of the time you will be calculating collisions using the previous frame's boat position, the other half of the time you will be using the correctly updated boat position. As a side-note: This is the fundamental flaw with ECS frameworks and why I've taken such a disliking towards them.
  15. How to stay motivated?

    I find the github issue tracker to be a powerful motivation tool, if you use it correctly. Stuffing a three layered cake into your mouth all at once will of course not end well, and the same is true for any programming project: If you try to think about how much you have yet to implement, you will be mentally overwhelmed. The issue tracker helps you break your project down into small manageable steps, and if you're using github, you can generate visual graphs of your progress and use milestones to see the progress of particular features in your game. It's a lot easier to motivate yourself when you can set goals and reach those goals. For instance, you could tell yourself that you will fix 2 issues a day, and when at the end of the day you were able to fix those two issues, you can smile to yourself and feel good about your accomplishment.
  • Advertisement