• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

Vincent_M

Members
  • Content count

    555
  • Joined

  • Last visited

Community Reputation

969 Good

About Vincent_M

  • Rank
    Advanced Member

Personal Information

  • Location
    Las Vegas
  1. I debated about this: start now, and ask questions later, or sit back and contemplate. I chose to ask about architecture first, but ended up diving into the project. I initially wanted to ask about jitter, latency and how to combat that with dead reckoning/path interpolation. I've read some papers online, but wanted to go over the specifics of it once I actually had something implemented. I ran into the issue of writing my Asteroids MMO using TCP sockets a few years back. It was a nightmare attempting to convert it to UDP, and I never finished UDP support. The game was plagued by jittering when 2 players weren't playing off of the same access point.   I started writing a REST API for user account management. This allows users to create new accounts, verify them via email, change emails, rename usernames, etc. I'm thinking about using it for login purposes too, but my NodeJS server could handle this as well since it'll have database access as well. At my old job, we would pass an API-KEY key-value pair in each of our REST API's requests. The request would return an error if the call didn't include it with the correct value. I've seen the use of API keys mentioned online, but I don't see the point of using them. Anyway monitoring the API calls via proxy can figure what the key is, so why bother using one? Is this to help stave some type of automated attacks not specifically targeted at my application?   I thought agar.io used WebSockets. Player movement didn't appear to have any jittering unless players broke into smaller pieces since you'd suddenly have a bunch of objects moving much faster onscreen. I'll ask more specific questions when I get to that point. Working on the sign-in system.   I've used both in Python projects at work in the past, but not in PHP yet. I'm considering Redis for sessions, possibly   Perfect! I've wondered if there was a UDP counterpart to WebSockets. I've searched online in the past, but found nothing. When I first read about WebRTC, I also wondered how supported it'd be client-side in browsers, but I think it'll work for my purposes. I'm writing stuff that's meant to be more experimental than mass-supported.   I've wondered about this myself. It seems like WebSockets have been widely supported since 2012.
  2. I want to make a real-time light MMO-like Asteroids game using Unity and WebSockets for the client, and NodeJS, SocketIO and Box2D on the server side. I'll handle scaling by having each instance of my server be a separate "universe" the player can explore.   Players only have a single login for their account, and can jump between available servers, which are considered separate "galaxies". Since the player's account isn't directly tied to any specific server instance, the login mechanism needs to be separate from that, so I've thought about going the REST API route. Once successfully authenticated, my REST API would generate a authentication token to represent their login credentials for their session. Once the player is logged in, they can select a galaxy (server) to visit, provided it hasn't met its player capacity. When the player attempts to connect to that server, the client will pass the player's token, and the server will check if that token is a valid session with the database (this might breach RESTfulness).   If the server finds that the token is valid, a socket connect between the client and server is attempted. Upon success, a player object is created on the server, added to the list of current players. The server will use Box2D, or some type of physics engine to process movement, collision, etc, and report the observable portion of galaxy that the player can see as a message to the client ever few milliseconds (the goal is 30 frames per second). The Unity client will render the observable objects within view to the user. The client will periodically send input signals to the server (again, the goal is 30 fps). Those input signals are interpreted by the server to perform actions, such as steering the ship, shooting projectiles, interacting with the environment, etc. Whenever the client sends a message to the server, it also sends its token that the server uses to ensure that the client connection is coming from something that it originally considered legitimate.   WebSockets is primarily meant to send real-time data in the form of binary data instead of JSON to reduce overhead and serialization/deserialization between the client and server. Unity's .NET implementation appears to support binary serialization/deserialization that could be faster than JsonFX, but I have yet to benchmark it. Packing the database into binary datatypes will be a pain on the NodeJS side, but I plan on going back to a C server once I get things figured out. The server also has access to the database to submit queries such as kills, resources mined, health picked up, score, currency, in-game shop transactions, inventory pick-ups, etc.   The player can also update their player info in-game, send money to users, and other actions that the REST API would handle. As far as database queries go, I'd probably use AWS SQS for a larger-scale design, and have some sort of in-memory database to help with queries happening between what's actually in the database, and what's yet to be in it.   I'd use AWS, and have a server for the REST API, one for the database, and one for each galaxy configuration per instance required. How does this sound as far as architecture?
  3. That's a pretty good point. I remember some one mentioning in a thread a while back where he'd play Age of Kings on his 4K display. The largest map sizes could fit entirely onscreen. This could be an advantage or disadvantage to the users depending on how physically large the display is (32-inch vs 60-inch). The was we addressed the varying aspect ratio issue in one of our portrait mobile games was similar to how the Warcraft games did it. We'd use our skinniest aspect ratio (9:16) as our basis aspect ratio to draw all UI elements within. The game would be in full-view, while our widest aspect ratio (3:4) would have decorative borders on the sides. We used a fixed-height Cartesian coordinate system where the origin was at the center of the screen, and the y-axis was facing up rather than down. We'd place all of our UI elements within the bounds of the 9:16 aspect ratio, and add those borders just outside of the 9:16 view. Then, wider aspect ratios would show the border. How much of the border it showed depended on how close to 3:4 we got.   I believe we used a fixed height of 720, or maybe we used 960. In any case, this was only for placement and size (including 9-slicing). We were targeting the iPad retina as our highest possible resolution, so our fullscreen backgrounds were 1536x2048 (3:4). In a 720 fixed-height coordinate space, we get a viewport range of +/-360, which covers 2048 pixels down on a retina iPad.   This can all be accomplished with the projection matrix, as mentioned by IceCave.
  4. I've been really tired today, so I'm struggling to conveying my thoughts.   1. Of course, it'll take more time. I've spent a long time trying to get experience on my own, but it appears that I'm only working harder, not smarter. I can't seem to focus on a single thing.   2. I'm picky because I'm so new to the software engineering industry in general. I don't know what most job roles really are, or even what I want. Not only do I need experience, but I need to figure out what I want that's obtainable right now. Then, I actually know what to work toward.   3. I meant seniors. Most companies are looking for senior developers, not junior developers.   4. I mean not knowledgable in as "uncomfortable." If I see something I might be interested in, should I just go for it? Getting a job in that field could land me a reliable mentor.   5. This warrants a quote: I completely agree. I need more experience in the industry in general, not just programming. I try to balance my programming, gym and family time with a social life too. I'm always meeting people who want to do projects with me. Again, lack of experience and direction on my part's destroyed every personal project I've done to date. I'll post back when I'm done reading your article.
  5. I've been programming as a hobby for well over a decade now, but I've only been programming professionally for 2 years. Due to this, I have access to mentors who know their stuff, but I also have access to some pretty gnarly code bases. I've only worked for small companies during this time. My only work-experience skills are in Unity/C# (some C# development outside of Unity), Python, ActionScript3, and a few libraries within all those.   I have a lot of personal experience in C++, but not in the workplace yet. I also have personal experience with PHP, SQL (I've only used MySQL for the implementation), Java, and Objective-C. I've also got experience with Qt, the Android and iOS SDKs, and a bunch of libraries. I have a degree in Management Information Systems, but I'm at most, junior-level in everything. I'm in my mid-20s, and ambitious like most people my age. Unfortunately, I lack the skills of a seasoned professional. I want to get those skills.   I really want to get a lead developer role in something involving backend or tools development. I really enjoy programming, and try to put in 20 hours into it a week after work and gym. I think I'm decent in C++ and C#, but far from mastery. I've been told I have potential by a potential employer, but results are what they want. I really want to have a sense of mastery when it comes to software design in general.   There are plenty of software development jobs in Las Vegas where I live, but I've become picky on what to apply for. Part of my pickiness comes from lack of experience. Most of my experience is in C++, but everyone wants juniors. Would it be wise to seek out a junior-level job in a field I'm not really comfortable in? I really want to run a small-time video game studio, and make fun games for mobile, and Steam. Again, who wouldn't want that here on these forums? haha
  6. I use "this->" when I have identical names. When assigning variables in the constructor's initializer list, it seems to not make any different that my constructor parameters have identical names to my       Do class fields still get assigned by value when passing by reference, right? One thing that confuses me about references is that I can still pass literals in as parameters. I've just recently started using references, so it's practice at this point. If I wanted to pass objects by value into my constructor (aka, make a copy, just like push_back() does in std::vector), would I not use a reference? If I wanted to pass by reference, would it be wise to use references over pointers, or does it depend on the situation?       I've seen these cases a lot myself in the past. I think the book, Clean Code, suggests not doing this though. I can't remember if I really read that a year ago when I read the book, or even why that'd be the case. Personally, a prefix sounds like a good way to go as, you like said, explicitly establishes scope for that variable throughout the class. I could even have local variables with the same name, but no prefix, and the code wouldn't look as confusing, provided the situation would require a variable named like that. I'm a big fan of just the preceding underscore, which appears to be a common convention in Obj-C, C#, etc. I've been told by a lead developer in the past that a preceding underscore isn't a good practice in C++ while it is in C#.   @Gooey: The code compiled fine, but it does look misleading. I didn't even think about this as I was still thinking in terms of passing-by-value. Trying to go with references over value when I can do that. but you also bring up a good point. A const reference makes it misleading. @Strewya: Good point on the code convention. Removing the const reference sounds like the better way to go.   EDIT: I found this post on why a we shouldn't start variable names with an underscore. Bottom line: variables starting with an underscore is reserved for C++ implementors. Sounds like this goes for variables starting with both upper and lower-case letters after the underscore. Josh Petrie also pointed out in a previous post I started 2 days ago when I was doing that with my header guards. I thought he only meant that for header guards though. After reading that post, it makes all sense now. I guess m_* might be the way to go. This posts suggests using trailing underscores for naming. I kind of like that naming convention.
  7. One issue I frequently run into is trying to come up with decent names for parameter names. This is especially a problem in constructors and setter methods. For example, take the following class: class Car { private: unsigned int gas; unsigned int tankCapacity; float headlightRange; public: Car(const int& gas, const int& tankCapacity, const float& headlightRange = 15.0f) : gas(gas), tankCapacity(tankCapacity), headlightRange(headlightRange) { } void SetGas(const unsigned int& amount) { gas = amount; if(gas > tankCapacity) gas = tankCapacity; } void SetCapacity(const unsigned int& amount) { tankCapacity = amount; if(gas > tankCapacity) gas = tankCapacity; } void SetHeadlightRange(const float& range) { if(range > 0.0f) headlightRange = 0.0f; } }; Ok, so I couldn't come up with any setters where I could only think of a parameter name that matches the field that'd I'd be modifying right now, but it's been an issue for me from time to time. Still, the constructor's a concern.
  8. True, some WebGL games are simply too ambitious for mobile, but there are some impressive WebGL demos such as this one on my iPhone 6 Plus at an intractable framerate. As far as large amounts of memory consumption: probably a byproduct of much of everything being in JavaScript --even if running as an IL/emscripten approach. WebGL's currently-supported implementation is the JavaScript equivalent to the OpenGL ES 2.0 API in C, which Unity's supported for some time now. They'd mostly have to use some sort of IL approach, such as JS.asm/emscripten to convert the code-base over to something browsers, even Node.js could run. It sounds like their own IL2CPP is their solution to that. If anything, just switch your platform and renderer to OpenGL ES 2.0, and you've got yourself a natively-written app. Now, your only hurdle is Apple's App Store review process. Sure, there are plenty of hurdles that Unity's got to jump, but their publicly-released efforts regarding WebGL look pretty solid so far.
  9. I override removeRows() to specifically remove scene nodes from my own hierarchy's structure between beginRemoveRows() and endRemoveRows(). It's been a few weeks since I worked on this, but I think removeRows() was being called internally by the base class, QAbstractItemModel, whenever I moved something in my hierarchy. Changing drag and drop operations from InternalMove to DragDrop seemed to stop calling removeRows() internally.   I agree with trying to avoid having to subclass QTreeView for simple operations. You'd think it'd provide more intuitive signals for when selections change and occur, but hey, there are reimplementation methods for that (ugh)! Again, I'm still pretty new to Qt, and it looks like it doesn't directly handle selections, but rather the QSelectionModel field it has does this.   Either way, my hierarchy system appears to work like a charm now. There are only minor changes here, but here's the working source code I've got: #include "SceneModel.h" #include "Scene.h" #include "Node.h" #include <stdio.h> #include <stdlib.h> #include <QKeyEvent> #include <QMimeData> #include <QByteArray> #include <QColor> #include <QDebug> Qt::ItemFlags SceneModel::flags(const QModelIndex &index) const { Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); if(index.isValid()) return defaultFlags | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEditable; else return defaultFlags | Qt::ItemIsDropEnabled; return QAbstractItemModel::flags(index); } Qt::DropActions SceneModel::supportedDropActions() const { return QAbstractItemModel::supportedDropActions() | Qt::MoveAction; } int SceneModel::rowCount(const QModelIndex &parent) const { // make sure the scene's root node is valid and the parent's column is zero if(!scene || !scene->GetRoot() || parent.column() > 0) return 0; // return the parent's children, if valid if(parent.isValid()) return static_cast<Node*>(parent.internalPointer())->GetNumChildren(); // otherwise, return the children return scene->GetRoot()->GetNumChildren(); } int SceneModel::columnCount(const QModelIndex&) const { return 1; } QModelIndex SceneModel::index(int row, int column, const QModelIndex &parent) const { // make sure the root, row and column data is valid if(!scene || !scene->GetRoot() || !hasIndex(row, column, parent)) return QModelIndex(); // get the parent Node from the index Node *parentItem = scene->GetRoot(); if(parent.isValid()) parentItem = static_cast<Node*>(parent.internalPointer()); Node *childItem = parentItem->GetChild(row); if(childItem) return createIndex(row, column, childItem); return QModelIndex(); } QModelIndex SceneModel::parent(const QModelIndex &index) const { // make sure the index is valid if(!scene || !index.isValid()) return QModelIndex(); // get the child item to get the parent item Node *childItem = static_cast<Node*>(index.internalPointer()); if(!childItem) return QModelIndex(); Node *parentItem = childItem->GetParent(); // return nothing if the parent item is the root if(!parentItem || parentItem == scene->GetRoot()) return QModelIndex(); return createIndex(parentItem->GetChildIndex(), 0, parentItem); } QVariant SceneModel::data(const QModelIndex &index, int role) const { if(!index.isValid()) return QVariant(); if(role == Qt::ForegroundRole) { Node *node = static_cast<Node*>(index.internalPointer()); if(node && !node->IsActive()) return QColor(Qt::gray); return QVariant(); } // handle displaying the data if(role == Qt::DisplayRole || role == Qt::EditRole) { // get the child and parent Node pointers Node *node = static_cast<Node*>(index.internalPointer()); return QString(node->GetName().c_str()); } return QVariant(); } bool SceneModel::submit() { // make sure the scene is available if(scene) { // check if the selected node is valid if(selectedNode) { // get the selected node's index, and update its display data QModelIndex selectedIndex = createIndex(selectedNode->GetChildIndex(), 0, selectedNode); setData(selectedIndex, QString(selectedNode->GetName().c_str()), Qt::DisplayRole); } } return QAbstractItemModel::submit(); } bool SceneModel::setData(const QModelIndex &index, const QVariant &value, int role) { // check if the index is valid, and either in EditRole or DisplayRole mode if(index.isValid() && (role == Qt::EditRole || role == Qt::DisplayRole)) { Node *node = static_cast<Node*>(index.internalPointer()); if(!node) return false; // set the node's new name, and signal that data has changed node->SetName(std::string(value.toString().toUtf8())); emit dataChanged(index, index); // emit signal that specifically signifies that the name has changed if(role == Qt::EditRole) emit SelectedNodeNameUpdated(node->GetName()); return true; } return QAbstractItemModel::setData(index, value, role); } bool SceneModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int, const QModelIndex &parent) { // make sure this is aciton shouldn't be ignored if(!scene || !data || action == Qt::IgnoreAction) return false; // get the encoded data of our Node pointer QByteArray encodedData = data->data(SceneModelMIMEType); Node *node = (Node*)encodedData.toULongLong(); if(!node) return false; // get the parent node QModelIndex destinationParentIndex; Node *parentNode = static_cast<Node*>(parent.internalPointer()); if(parentNode) { destinationParentIndex = parent; } else { parentNode = scene->GetRoot(); destinationParentIndex = createIndex(0, 1, scene->GetRoot()); } // get rowCount if row is invalid (this might be an old Qt bug) if(row == -1) row = parentNode->GetNumChildren(); // move the row Node *sourceParentNode = node->GetParent(); QModelIndex sourceParent = createIndex(sourceParentNode->GetChildIndex(), 0, sourceParentNode); moveRow(sourceParent, node->GetChildIndex(), destinationParentIndex, row); return true; } QStringList SceneModel::mimeTypes() const { QStringList types; types << SceneModelMIMEType; return types; } QMimeData *SceneModel::mimeData(const QModelIndexList &indexes) const { // make sure there's exactly 1 index and it's valid if(indexes.size() != 1 || !indexes[0].isValid()) return nullptr; // get the Node pointer from the index's internal pointer, convert it to quintptr, then to a UTF string quintptr nodeAddress = (quintptr)indexes[0].internalPointer(); QByteArray encodedData(QString::number(nodeAddress).toUtf8()); // allocate mimeData, provide it with encodedData, and return it QMimeData *mimeData = new QMimeData(); mimeData->setData(SceneModelMIMEType, encodedData); return mimeData; } bool SceneModel::insertRows(int row, int count, const QModelIndex &parent) { if(!scene) return false; Node *parentNode = static_cast<Node*>(parent.internalPointer()); if(!parentNode) parentNode = scene->GetRoot(); // make sure a parent node was found before continuing if(parentNode) { // begin inserting rows, and add begin adding uniquely-named fields beginInsertRows(parent, row, row+count-1); // insert nodes for(int i=0;i<count;++i) parentNode->AddChild("New Node"); endInsertRows(); return true; } return QAbstractItemModel::insertRows(row, count, parent); } bool SceneModel::removeRows(int row, int count, const QModelIndex &parent) { if(!scene) return false; Node *parentItem = static_cast<Node*>(parent.internalPointer()); if(!parentItem) parentItem = scene->GetRoot(); // make sure a parent node was found before continuing if(parentItem) { beginRemoveRows(parent, row, row+count-1); parentItem->RemoveChildren(row, count); endRemoveRows(); return true; } return QAbstractItemModel::removeRows(row, count, parent); } bool SceneModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) { Node *sourceParentNode = static_cast<Node*>(sourceParent.internalPointer()); Node *destinationParentNode = static_cast<Node*>(destinationParent.internalPointer()); Node *childNode = sourceParentNode->GetChild(sourceRow); // make sure the child isn't one of the parent nodes if(childNode == sourceParentNode || childNode == destinationParentNode) return false; // if source and destination parents are the same, move elements locally if(sourceParentNode == destinationParentNode) { // only process if a local move is possible if(sourceParentNode->IsMovePossible(sourceRow, count, destinationChild)) { beginMoveRows(sourceParent, sourceRow, sourceRow+count-1, destinationParent, destinationChild); sourceParentNode->MoveChildren(sourceRow, count, destinationChild); endMoveRows(); return true; } } else { // otherwise, move the node under the parent beginMoveRows(sourceParent, sourceRow, sourceRow+count-1, destinationParent, destinationChild); childNode->SetParent(destinationParentNode, destinationChild); endMoveRows(); return true; } return false; } Are you trying to achieve a typical hierarchy-based scene graph with a tree view as well? Also, were you able to get it to work without the mandatory MIME data nonsense? I can see where MIME data is necessary when dragging files from say, Explorer or Finder into your view or items between separate views, but not from within the same view.
  10. I've looked at other C++ books recently. I wanted to get one on STL and templates in general. I've heard Effective C++ was a really good one, but wasn't sure which version to get.   This is a really good point you've brought up. After reading how references are like pointers that can't be NULL, it looks like I could still pass NULL/invalid pointers into the reference parameter parameter by pointed value, which will result in a segment fault.   This is another thing I keep going back and forth on. When I started learning C/C++, there were cases where the PSP homebrew community would store their data as POD if they could afford to in an effort to perform less calls to fread() and fwrite(). Again, padding and endianess between environments is a caveat.   As far as this convention goes: if(rotated) { } I actually prefer it that way for bools, pointers and integer values where zero acts as a special use-case versus a non-zero value. The only reason I wrote that as if(rotated > 0) { } is because I thought that'd be a more accepted convention. I'll post more often when I have questions regarding code conventions.
  11. As mentioned above, there are many ways to handle this. One way we dealt with this at a video game company I worked at was work in a fixed-height coordinate space. Instead of having all of your coordinates match up to pixels, come up with some arbitrary fixed height value (test it out though). The fixed height will be the domain of your screen's coordinate space. The width would vary between screen sizes, and you could find it by multiplying your fixed height value by the aspect ratio. That said, make sure all of your fullscreen background artwork produced with the height of your fixed-height value, and its width being whatever it is multiplied by your most extreme aspect ratio (most-likely 16:9, if working in landscape). Then, the sides would just be clipped on screens with fuller aspect ratios, most-notably the 4:3 aspect ratio. You'd design most of your UI in the middle of the screen, making sure it fits nicely in 4:3. You could attach certain UI elements to the edges of the screen so that they hug the sides regardless of fullscreen or widescreen aspect ratios. 9-slicing will be a huge part of this as well. A good deal of your panels and other large UI elements would most-likely be percentage-based if you want them to scale with the screen. The beauty here is that your UI is no longer resolution-dependent, and mostly not aspect-ratio dependent. You could get more creative, and have different resolution images for different resolution devices. For example, high-res iamges for Quad HD and 4K displays (many mobile devices are going Quad HD today). You could use lower-resolution versions of your images for lower-resolution devices --something I highly recommend. Lower-resolution devices are generally older devices as resolutions have been increasing almost every year. These older devices won't have the memory, or the GPU bandwidth to support these higher-resolution textures, so I'd suggest having some sort of content pipeline in place that automatically cooks up low-end builds with lower-resolution images.   Regarding having multiple resolutions of your game's assets, I'd use PC games as an example. With varying hardware and screen resolutions, gamers can usually lower graphical settings, such as texture resolutions, if there isn't enough resources to go around.   You can also use techniques mentioned above alongside this process.
  12. Sorry if this is tl;dr. It took me 3 hours to write up a response. Took it to heart though.   Quick glance at the code, you pass parameters by value specially std::string, you do not use const anywhere including marking methods which do not change state of an object. Those two things would be give me the impression that you are a junior.     AND       I still struggle with all of these. I can nail a lot of the simple stuff, but I don't most of the time. I've been programming in C++ as an obsessive hobby since I was in middle school, about 11 years ago. That said, I still do consider myself novice. I've started to notice that I need to get feedback from other programmers to grow, otherwise I'll just be stuck in my old ways. I just gotta face that I'm not John Carmack --I'm just a regular guy lol. I'll to ask more questions, and apply the advice in smaller test cases to reinforce what I'm being taught.   I can't thank you all enough for the feedback.
  13. I recently interviewed with a CAD-based studio where I live for a C++/Renderer position. The role was to work on their internal 3D rendering code that's written in DX/OpenGL. They asked for a code sample of one of my personal projects. I sent them one of my projects. It's a basic, open source, texture packer application using Qt to provide the UI. It's not much, but at least it's pretty complete. The CEO got back to me about 10 days later, and said I was too junior for their company at this time. They're looking to fill a senior position first, then they'd consider bringing me on to get mentored.   I was only a little disappointed at first, but more curious than anything. I've been programming since middle school, but I'm only 2 years into programming professionally full-time. I've worked in 2 smaller/startup companies in this time. None of my work has been C++ or lower-level rendering-oriented, so it didn't surprise me when they turned me down. I know I'm not the best C++ programmer out there. I'd like to have some one with better knowledge of C++ to point me in the right directly as far as decent C++ practices go. I don't know if there are any good resources for this online, so I wanted to ask for one in this thread, if that's allowed. I'd really appreciate it if anyone could give me feedback. It can be downloaded here. If anything, you'd get a texture packer with source out of it.
  14. I've done a lot of OpenGL development in the past few years, but with the release of DirectX 12 with Windows 10, I'd really like to start learning how the new APIs will work. I wanted to wait until Vulkan became available, but I'm not sure how long that'll take. From what I could find online regarding Metal, Vulkan and DX12, it sounds like these APIs are all very similar. Does this seem to be the case? For example: if I wanted to convert my game from DirectX 12 to Metal or Vulkan, the process would be "easier" than porting between OpenGL to any of the new APIs, correct?   If I wanted to start learning about DirectX 12, are there any decent learning resources out there to begin, or would I have to dive into MSDN docs to figure out what goes where. I did find this DirectX 12 Programming Guide on MSDN though. I read in this post that these newer APIs are more difficult to work with as they provide more explicit control over the GPU, and that game developers must now deal with the less pretty side of GPUs that older API drivers used to hide.
  15. I have developed two open-source projects I developed in Qt:   SDF Font Generator/Packer Loads a TTF or OTA file, and generates SDF glyphs. Exports to a single binary file containing the 8-bit texture data, and glyph rect definitions. Currently only supports ASCII. Also, for test purposes, you can choose source glyph's sample size. Ideally, you want 4096x4096, but my algorithm is really slow. It could take a few hours to generate. 512x512 does pretty well right now. You can also zoom in and scroll to get an idea of what the glyphs look like close-up. Currently doesn't support sharp corners.   Sprite Packer Drag and drop images from your OS's file manager application into the dock on the right. The user can select multiple rects from the dock, and it'll highlight them in the atlas. You can also zoom in and scroll. The atlas updates automatically. A background color can be specified if color-keying is desired, and padding can be applied to your images. Outputs a compressed PNG for the atlas, and a JSON file for the image rect dimensions. A variety of image formats are supported. There are some odd artifacts that have cropped up recently, and sometimes crashes occur.   They both use a lot of the same boilerplate code. There are some graphic issues when compiling for OS X as Qt seems to use the same OpenGL context for its own internal use. The only binaries I provide are for Windows 10, since I just upgraded. Here are the links: Glyphic-0.9-win32.zip Glyphic-0.9-src.zip   SpritePacker-0.9-win32.zip SpritePacker-0.9-src.zip   I hope these projects help others with their future projects! Also, if you have any feedback, I'd be happy to hear it. I'd really like feedback on code structure, and class architecture. I'm trying to develop better coding conventions.