Jump to content
  • Advertisement
  • entries
    6
  • comment
    1
  • views
    7517

About this blog

It's a journal :P

Entries in this blog

 

Fun Updates this week

Hey all,
For the first time in several weeks, I was able to get a decent amount done with the game. Most notably, the UI is now clickable and interactive, a tile flipping mechanic was added to the game, and there's now a (rather ugly) player turn icon above the head of the character whose turn it is.

For the clickable UI, I went with a rather simple function that takes the mouse position, and tests it against the various button dimensions and returns an integer that is later passed into the respective function, whether it's for players, tiles, etc, like so:[code=:0]//pull opengl screenCoords from common commands, where 0,0 is bottom left//// glm::vec2 tempCoords = OpenGLScreenCoords(window, ScreenDimensionsIN); //iterates through uiButtons to see if click matches coordinates//// for(int i = 0; i uiButtons.x*ScreenDimensionsIN.x && tempCoords.x .y * ScreenDimensionsIN.x && tempCoords.y > uiButtons.z*ScreenDimensionsIN.y && tempCoords.y .w * ScreenDimensionsIN.y && glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS && keyLMOUSEBool) { //return button that was clicked, set bool to true, reset keys//// uiButtonImages = uiButtonHighlight; keyLMOUSEBool = false; clickedBool = true; ResetKeys(window); return i; } }
The integer it returns is treated much like any key press in the rest of the functions in game. So, to fire a spell, it checks the function parameters for either the keypress, or the integer corresponding to the respective key, if that makes sense. I'll likely look into whether there is a cleaner or more efficient way to do this, but for the moment, it seems to work fine.

I added a player turn icon above the player's head whose turn it is. Things were rather confusing without it :P The shading, shape and color are all just placeholder until I have time to design a decent looking one.

And, then lastly, I added a tile flipping mechanic/ altar mechanic that flips either the tile the player is standing on, to match their good/evil alignment (players will get an attack/defensive boost or penalty based on the tile they're standing on). The flip one is pretty self explanatory and simply bumps the player up into the air, and flips the tile up with them, and lands as their respective tile alignment. The altar mechanic was a little tricky for me to implement as it deals with both the players and the environment, whose classes don't interact with each other. So, I had to add a function in the main class to handle these (currently, this is how much of the game is set up. With the main class directing things between the players/terrain/ui/etc).

The altar will fall from the sky to the game board, flipping the tiles around it, and anything standing on them, one by one, changing the tile color to match the player's alignment. It's rather fun :) This week, I'll hopefully have it also damage any opposing players in the process, and add some particle effects.

Other than that, I fixed a ton of little bugs, tried to draw some new characters, got frustrated with my drawing abilities and gave up, and generally tried to clean up the code a little. The code is beginning to feel really unwieldy. The entityManager class (i know, i know, verb-class) is rather huge, and probably ought to be split up. Additionally, i need to go through and make sure that only things that are necessary to update every iteration in the game are included in the main Update() function. At the moment, there are several things that could easily only be calculated on changing turns, or even just once every second or so.

Anyhow, you can view the code here or here. I'd welcome any comments, criticism, or especially advice as I'm still rather new to everything.

Here are some images of the ui/icon and flip mechanics. I was hoping to get video of it, but never got around to setting up something to host video. Maybe next week :)
Have a good week everyone :)

Misantes

Misantes

 

Library Troubles and updates

Hey everyone,

It's been a couple weeks since I last updated. Mostly it was filled with frustratingly retooling the game and testing out different libraries.

I purchased a new laptop, mainly to force myself out of the house a little more often The first time I tried to boot up my project in it, nothing would render. After some investigating, I realized that SFML does not allow you to use anything higher than glsl 1.3 and opengl 3.0 if your graphics driver only supports higher version exclusively in a core context (my laptop intel driver does, sadly).

Unfortunately, I was running opengl within an SFML window to make developing the UI a little easier. I spent a good week implementing different libraries and weighing the pros and cons of each. I ended up deciding to bother with none of them and spent another week redoing the UI just in c++ and opengl. It's a little more hassle, but as my game is a rather simple one, I'd like it to be pretty compatible on lower end systems. So, rather than deal with various library's dependencies, I've opted to simply eschew them where possible. (I'll still likely use SFML for audio, as it doesn't require a sfml window instance). The UI is rather simple, with no clickable abilities yet, but that's on the table for this week.

I learned how to generate a bitmap font image to display text in the UI. I definitely need to spend time making a nice one, as my current one works, but is damned near illegible (my handwriting is terrible).

Anyhow, In addition to that, I implemented a "font/altar" system. You can create a little altar that generates your evil/good currency (and will eventually corrupt/cleanse the tiles around them). It's still a little rough, and using placeholder animations,but it's functioning.

Added the ability to trade/store currency between players and towers.
Added a bit of randomness to the trees and mountains in terms of scale. So, everything has a little variety and isn't a sea of identical mountains.
fixed tons of little bugs and issues.

There are certainly other things, though I've not kept a list of everything. But, those were the really notable changes.

Sadly, that's about all that was accomplished. I wish I had more to report, but the UI/library thing was a considerable obstacle, and not terribly easy to replace. A lot of time was spent trying to implement various libraries, and then learning how to do the UI without them, especially in the text/font areas.

Hopefully with this obstacle mostly behind me, I can progress with some actual game mechanics this week (we'll see how long the clickable UI takes. I've done one in another project, so hopefully I can transfer a lot of that knowledge over).

On the TODO list for this week:
-clickable UI, use to cast spells, end turn, changeable key bindings, etc.
-have the font/altar things change the alignment of the tiles over time.
-add better ways to generate currency.
-make a "selected player" icon above the player whose turn it is.
-really low poly (even lower than now :P) models. The game runs terribly on my laptop. I need to (learn to) profile to see where things are slowing down, but I have a feeling I have a lot of extra and useless vertices being calculated. Every tile has the full 12 vertices, even though you only see the top ones. The little mushrooms have a ton of vertices for being tiny little mushrooms, etc. etc. Multiply these by a few thousand and It adds up, and I think it's the likely culprit. But, we'll see. I definitely need to look at performance as something this simple shouldn't be running this poorly.
As always, I'm open to any advice/criticism/comments, and they would be more than welcome You can view the full project code here or here.

Obligatory and slightly embarrassing game image:

Misantes

Misantes

 

Week 4

Hey everyone,
This week I didn't get a whole lot done. I agreed to work on a little side project with a friend, so spent much of the week learning javascript and the phaser engine syntax. However, I'm going to admit, I'm finding using javascript with phaser is boring me out of my mind. I wanted to broaden my programming base, which is why we went with an unfamiliar language to me, so I'll probably stick with it for awhile, but man, do I find it less interesting. I'm guessing its the engine that's bothering me, as there seems to be little javascript used. So, I'm reduced to linking images, and telling the engine where to place them. Perhaps I just haven't plumbed the depths of what the engine can do, but I feel a little superfluous

Anyhow, on this game front, I did manage to get a few things done. I implemented a death animation of sorts, and finally set the game to remove dead entities from the board. I'm a little torn on the idea of removing them entirely, or just setting them as "dead" and not rendering them. There's some pros/cons to each, I think.

Additionally, I added a "currency" to the game. It's just a generic resource that's used to summon minions, build towers etc. When a minion is killed, their currency is given to the minion who killed them. They can store their currency in the Players Tower. I need to give a lot of thought to this mechanic. As of now, players can "dig" on any tile, and have a chance at returning currency. That's unfortunately the only way to generate it in game (though, you can kill the other player for their currency, but they would have had to dig for it). I may pick the brains of everyone on the game design forum, as I'm a little stumped on a fun way to go about this. There's always mining/gardening/chopping down trees that's in a lot of games, though I'm not certain I want to go that route. Anyhow, if anyone reading this has input, I'm open to ideas

Again, with the help of the usual wonderful people here, I was able to work through my segmentation fault from last week. I had to do quite a bit of reading on the stack/heap differences but was able to git rid of the segfault, and learned a good deal as well. So, thanks to those who helped with that
This is something I hope to pay a lot more attention to (up until now, I mostly worked on the stack out of convenience and safety).

Sadly, that's about all I got done last week. For next week, I'm still deciding whether to dig in and learn javascript/phaser for my friend's game, or spend my time with this game.

No screenshots this week, as other than the death sequence, which is just a recolored placeholder spell, most of the work was under the hood.
Next week I'll try to have a bit more of a robust journal, as this week's is feeling rather sparse.
Cheers!

Misantes

Misantes

 

Week 3:

Hey all,
I was still unpleasantly sick for most of the week (this is like the flu from hell). But, managed to still get quite a bit done, mostly in the bug-fixing-realm.
I fixed many of the things that had been bugging me, though were not huge updates.

First and foremost, I changed the raycasting to "see through" trees, players and objects and correctly click the tile that you want. Previously, my raycasting function used the pixeldepth openGL function, which, when used with glm::unproject() can return the world coordinates of the pixel. However, when selecting players, this isn't ideal for a number of reasons. I'm using billboarded characters with partly transparent images. If you click anywhere near the character, (meaning to click on the tile behind the player, for instance), it would return the incorrect value as the pixeldepth would return the location of the character image.

This meant learning some math (damn it, math!). As a bit of a back story, when I was in college, I tested into Calculus II, skipping trigonometry, calculus I, and algebra. However, to be honest, this had more to do with my standardized test taking abilities, and little to do with my math skills. I had no idea what a cosine was. Needless to say, I drowned in the class (even with a math tutor for a roommate). When I was younger, I always learned how to solve the "problems" of mathematical equations, without really understanding what I was doing. I could extrapolate the correct answer, and learned the methods for doing so, but (probably mostly my fault, but perhaps partly my teacher's fault) I never really learned or understood the applications of what I was doing. They were just fun little numbers games, but it led to me pretty much forgetting the majority of it over the course of time.

Anyhow, apologies for the little story here, but it may help explain my troubles for the week So, learning how to solve this raycasting problem meant learning how to calculate the point at which a line intersects a plane. For some of you, I imagine this is trivial, but for me, every tutorial I found assumes I'm caught up to the current level of math required to solve this (which makes sense). So, I more or less had to start a tutorial, and when I got lost, start another tutorial explaining the lower level math (which often required another tutorial explaining that math ). I know I really ought to just spend a few months learning/relearning the math I'll need for game development, but part of me figures I'll eventually learn it all, if I keep at it as I am. It'll be far more frustrating, and I'm likely to code slower (as I keep having to spend a week teaching myself more math), but I tend to be stubborn, so this is probably the route I'll take

Anyhow, the new and improved raycasting function. I'm fairly certain I understand what I'm doing though it's probably not all that elegant, but it works:glm::vec3 XRayCast(glm::vec2 mousePos, glm::mat4 &viewmatrix, glm::mat4 &projmatrix, sf::Vector2f screendimensions, sf::Window &window){ //beware! this function does not account for zero values//// //but it isn't necessary for this function as the camera is at a fixed angle toward the plane, keep in mind if you adjust later//// //variables for raycasting glm::vec3 unprojS;//ray start point glm::vec3 unprojF;//ray end point glm::vec3 pointInPlane(0,-500,0);//point where plane begins glm::vec3 planeNormal(0,1,0);//plane normal (up vector) float t;//variable to solve glm::vec3 intersection;//intersecting point float distanceToOrigin;//used to calculate the end point distanceToOrigin = glm::dot(pointInPlane, planeNormal); //start and end points of ray unprojS = glm::unProject(glm::vec3(mousePos.x, screendimensions.y -mousePos.y, 0), (viewmatrix), projmatrix, glm::vec4(0,0,screendimensions.x, screendimensions.y)); unprojF = glm::unProject(glm::vec3(mousePos.x, screendimensions.y -mousePos.y, 1), (viewmatrix), projmatrix, glm::vec4(0,0,screendimensions.x, screendimensions.y)); //calculate direction glm::vec3 direction = unprojS - unprojF; //calculate intersecting point: t = (distanceToOrigin - glm::dot(unprojS, planeNormal))/glm::dot(direction, planeNormal); intersection = unprojS + t * direction; return intersection;}
With that sorted out, I spent what was left of the week with other minor, if pleasant changes.
-remade mountains to fit to tiles
-made mountains unpassable by players
-made water Minion
-set land minions to not be able to cross water normally
-set water minions to not cross land
-made characters clickable to enable their turn (if it's your side turn and they're your players). This one felt nice to do.
-fixed saving/loading files to account for minions and their respective side
-made trees not spawn in mountains in terrain generation
-made tabbing function to switch between enabled player (ala many RTS games) so you can tab through your available entities when it's your turn.
-tons of little bug fixes

I spent the last couple of days dealing with a segmentation fault. If I added certain things (std::vector of anything, for example, or certain class instances) to my EntityManager class header, it would segfault on startup. In my limited experience, this is usually due to an incorrect pointer somewhere, though I've eschewed pointers for this game (thus far. I'm not entirely opposed to using them, they've just not been necessary yet) and am passing everything by reference where possible, so I was pretty stumped on this. Prior to recent changes, I passed in all the object info for characters (normals vertices, shaders, etc) by reference to the class, but thought it would be cleaner to create them in the class manager, rather than in main. Reverting to the older system seems to get rid of the segfault, but now I'm passing in references to a half dozen parameters for every function in EntityManager(). I tried valgrind and gdb and for the life of me could not pinpoint where I was going wrong.

Anyhow, I don't have a specific list of things to do next week, but I'm fairly certain it's not going to be anything heavily based in math
I'll hopefully focus on game mechanics and the UI.

As always, you can browse the code here or download it here.
Here's some screenshots of the new mountains and water demons (the latter are pretty silly looking )

Misantes

Misantes

 

Week 2

Hey all,
Technically, this is more like week 3 or 4, but it's my second journal entry so I'm going to run with it
I've been sick all week, and still had to go to work, so I figured it would be a good week to simply fix some things I'd been procrastinating.

Taking a few steps back:
Up until this week, I had been postponing learning how to save to and read from a file. I've been programming for about 9 months now, and there's really no excuse, other than I was a little intimidated by the process for whatever reasons. In the early months, I learned the basic cin/cout things, and had used fstream in a limited capacity, but that was really about it as far as the c++ IO functions went.

I've never been much of a "eat my vegetables first" type person, and one of the hazards of learning on your own is habitually avoiding the things you should learn, but don't really want to So, this week, I buckled down and implemented a save/load game feature.

On that note, I want to thank the people here on gamedev.net. Seriously, regardless of my question, the same handful of people always seem to be there to offer helpful advice, week after week, and have helped me through some roadblocks. It's truly appreciated

Anyhow, I spent the early part of the week reading about the different IO functions in c++, and settled on JSON rather than XML and the JsonCPP library to parse it. I learned that I'm terrible at reading documentation. After some help on these forums, player information was relatively easy to sort out and save/load. The world information was slightly more difficult as it consists of a number of vectors of different classes, each with their own attributes. I ended up simply saving a number of arrays in Json. I.e. one array for tree locations, another array for ints that represent the location of the tree image in the texture array, etc, etc. context and code for this implementation is here. It's not very elegant (but it's functional, and seemingly bug-free, so...yay , I'll hopefully go through it later this week and clean things up a little.[code=:0]#include "FileManager.h"FileManager::FileManager(){ //ctor}FileManager::~FileManager(){ //dtor}void FileManager::SaveGame(std::vector &entityVec, TerrainManager &TerrainManager1){ try { //create json object for all values//// Json::Value playerInfo(Json::objectValue); //save player information//// //create vector of json values//// std::vector jPlayerLocVec; //set name and value for entity attributes------------------------------------------------------------- for(int i = 0; i .health; playerInfo["plmana"+tempI] = entityVec.mana; playerInfo["plaffinity"+tempI] = entityVec.affinity; //for vec size, emplace a new array object and set its values//// jPlayerLocVec.emplace_back(Json::arrayValue); jPlayerLocVec.append(entityVec.location.x); jPlayerLocVec.append(entityVec.location.y); jPlayerLocVec.append(entityVec.location.z); //save info to json value//// playerInfo["plLoc"+tempI] = jPlayerLocVec; } //save mountains//// //create vector of JsonValues//// std::vector jMountLocVec; for(int i = 0; i .append(TerrainManager1.MountainVec.location.x); jMountLocVec.append(TerrainManager1.MountainVec.location.y); jMountLocVec.append(TerrainManager1.MountainVec.location.z); //write info to json value//// playerInfo["mountloc"+tempI] = jMountLocVec; } //save ground tile types//// for(int i = 0; i .itileType; } //save forest objects//// SaveForest(TerrainManager1.ForestVec, 0, std::string("forestLoc"), playerInfo); SaveForest(TerrainManager1.ForestVec2, 2, std::string("forestLoc2"), playerInfo); SaveForest(TerrainManager1.ForestVec3, 3, std::string("forestLoc3"), playerInfo); SaveForest(TerrainManager1.ForestVec4, 4, std::string("forestLoc4"), playerInfo); SaveForest(TerrainManager1.ForestVec5, 5, std::string("forestLoc5"), playerInfo); SaveForest(TerrainManager1.GoodForestVec, 6, std::string("forestLoc6"), playerInfo); SaveForest(TerrainManager1.GoodForestVec2, 7, std::string("forestLoc7"), playerInfo); //create integer for size of various vectors (used when loading) int entVecSize = entityVec.size(); playerInfo["entVecSize"] = entVecSize; //open datafile std::ofstream DATAFILE; DATAFILE.open("Save1.json", std::ios::out); //stream json values to it DATAFILE &entityVec, EntityManager &EntityManager1, TerrainManager &TerrainManager1){ try { ////open json file//// std::ifstream DATAFILE; DATAFILE.open("Save1.json", std::ios::in); //create root and reader Json::Value root; Json::Reader reader; //parse json file bool parsedSuccess = reader.parse(DATAFILE, root, false); if(not parsedSuccess) { std::cout jPlayerLocVec; for(int i =0; i .location = glm::vec3(jPlayerLocVec[0].asFloat(), jPlayerLocVec[1].asFloat(), jPlayerLocVec[2].asFloat()); //make temp json values const Json::Value tempHealth(root["plhealth"+tempI]); const Json::Value tempMana(root["plmana"+tempI]); const Json::Value tempAffinity(root["plaffinity"+tempI]); //set entity values to json values entityVec.health = tempHealth.asInt(); entityVec.mana = tempMana.asInt(); entityVec.affinity = tempAffinity.asInt(); } else { std::string tempI = NumberToString(i); //create minion EntityManager1.CreateMinion(EntityManager1.getEntityTurn(), glm::vec3(0,0,0), TerrainManager1.ForestFloorVec[TerrainManager1.selectedTile].itileType); //set location entityVec.location = glm::vec3(jPlayerLocVec[0].asFloat(), jPlayerLocVec[1].asFloat(),jPlayerLocVec[2].asFloat()); //create temporary json values const Json::Value tempHealth(root["plhealth"+tempI]); const Json::Value tempMana(root["plmana"+tempI]); const Json::Value tempAffinity(root["plaffinity"+tempI]); //set entity values to json values entityVec.health = tempHealth.asInt(); entityVec.mana = tempMana.asInt(); entityVec.affinity = tempAffinity.asInt(); } } //make vector of json values std::vector jMountLocVec; //set mountain locations for(int i = 0; i .location = glm::vec3(jMountLocVec[0].asFloat(), jMountLocVec[1].asFloat(),jMountLocVec[2].asFloat()); } //load forests LoadForest(0, std::string("forestLoc"), TerrainManager1.ForestVec, root, TerrainManager1, glm::vec3(0,100,0), TerrainManager1.ForestVertices, TerrainManager1.ForestUvs2, TerrainManager1.ForestNormals); LoadForest(2, std::string("forestLoc2"), TerrainManager1.ForestVec2, root, TerrainManager1, glm::vec3(0,100,0), TerrainManager1.ForestVertices2, TerrainManager1.ForestUvs2, TerrainManager1.ForestNormals2); LoadForest(3, std::string("forestLoc3"), TerrainManager1.ForestVec3, root, TerrainManager1, glm::vec3(0,100,0), TerrainManager1.ForestVertices3, TerrainManager1.ForestUvs3, TerrainManager1.ForestNormals3 ); LoadForest(4, std::string("forestLoc4"), TerrainManager1.ForestVec4, root, TerrainManager1, glm::vec3(0,100,0), TerrainManager1.ForestVertices4, TerrainManager1.ForestUvs4, TerrainManager1.ForestNormals4); LoadForest(5, std::string("forestLoc5"), TerrainManager1.ForestVec5, root, TerrainManager1, glm::vec3(0,100,0), TerrainManager1.ForestVertices, TerrainManager1.ForestUvs5, TerrainManager1.ForestNormals5 ); LoadForest(6, std::string("forestLoc6"), TerrainManager1.GoodForestVec, root, TerrainManager1, glm::vec3(0,600,200), TerrainManager1.GoodForestVertices, TerrainManager1.GoodForestUvs, TerrainManager1.GoodForestNormals); LoadForest(7, std::string("forestLoc7"), TerrainManager1.GoodForestVec2, root, TerrainManager1, glm::vec3(0,600,200), TerrainManager1.GoodForestVertices2, TerrainManager1.GoodForestUvs2, TerrainManager1.GoodForestNormals2 ); //set floor tile types//// for(int i = 0; i .itileType = tempFloorType.asInt(); } DATAFILE.close(); std::cout &ForestVec, int forestNumber, std::string jsonForestName, Json::Value &playerInfo){ std::vector Forest1Vec; for(int i = 0; i .append(ForestVec.location.x); Forest1Vec.append(ForestVec.location.y); Forest1Vec.append(ForestVec.location.z); playerInfo[tempI+jsonForestName] = Forest1Vec; } std::string tempI = NumberToString(forestNumber); //create integer for size of various vectors (used when loading) int forest1VecSize = ForestVec.size(); playerInfo[tempI+"forestVecSize"] = forest1VecSize;}void FileManager::LoadForest(int forestNumber, std::string ForestName, std::vector&ForestVec, Json::Value &root1, TerrainManager &TerrainManager1, glm::vec3 lightPos, std::vector &verticesIn, std::vector &uvsIn, std::vector &normalsIn){ //create forest 1------------------------------------------------------------------------------ std::vectorForestVector; std::string strForestNum = NumberToString(forestNumber); //load size of forest Json::Value jforestVecSize; jforestVecSize= Json::Value(root1[strForestNum+"forestVecSize"]); int forestVecSize = jforestVecSize.asInt(); //reallocate forest object locations for(int i = 0; i .location = glm::vec3(ForestVector[0].asFloat(), ForestVector[1].asFloat(), ForestVector[2].asFloat()); ForestVec.lightPos = ForestVec.location + lightPos; } else//if new forest object needs to be created { std::string tempI = NumberToString(i); ForestVector.emplace_back(root1[tempI+ForestName]); ForestVec.emplace_back(TerrainManager1.ForestShader, glm::vec3(ForestVector[0].asFloat(), ForestVector[1].asFloat(), ForestVector[2].asFloat()), ForestVec[0].imageNumber, glm::vec3(0,0,0), verticesIn, uvsIn, normalsIn); ForestVec.location = glm::vec3(ForestVector[0].asFloat(), ForestVector[1].asFloat(), ForestVector[2].asFloat()); ForestVec.lightPos = ForestVec.location + lightPos; } } //clean up any extra trees//// if(ForestVec.size() > forestVecSize) { for(int i = 0; i forestVecSize) ForestVec.erase(ForestVec.begin()+i, ForestVec.end()); } }}
The second thing I had been putting off is utilizing accessor functions for my classes. I'm in a terrible habit of throwing absolutely everything into "public." Which seems to be fine when coding small programs by myself, but is probably a horrible habit to get into. So, I started the slow process of moving everything into protected/private and using accessor functions to retrieve/write them. I've only done a class or two, but it hasn't been as painful as I feared. It's rather slow, but overall not that bad.

Actual game changes:
Not much, sadly on this front as I mentioned I've been sick and working a lot. I've only had a couple hours in the evening each night to do much of anything. However, I did implement the "affinity" attribute for characters. It's a variable that will add bonuses to attack/defense/movement/etc that is dependent upon the day/night cycle, the tile the character stands on (i.e. if a good character is in a good forest, they get a bonus to this trait), and proximity to other like-aligned characters (this last part isn't implemented yet).

Additionally, I threw the character attributes into the UI as they had just been half implemented before. I question spending time doing this, as it's a half-measure really. The UI I got from opengameart.org, and plan on redoing it myself at some point, but for the moment it works. However, I end up spending twice the time as my workflow tends to go something like "placeholder art"->"temporary-but-slightly-better-placeholderart"->"finished artwork". I really ought to just use placeholders, finish the game, then do the artwork, but I find I get really discouraged if the game looks incredibly shoddy, so I end up doing things this way, which really takes a lot longer, with extra work, but looks slightly better along the way.

For Next week:
I'm torn between working more on game mechanics or adding more artwork. The game mechanics kind of require at least some placeholder work. I'm planning on adding more minion types for the players (right now it consists of the evil player's spiders).
For game mechanics, the most pressing things are:
Player upgrades: buildings, skill tree, minions, player-levels/xp
Player creations: power fonts, fortresses, etc
NPC villages, AI

I still need to really implement more UI functions, clickable skill casting, character selection by mouse select, rather than tabbing, etc. Just generally clean up the playability of everything.

Those seem like a good foundation before moving on to anything more complicated, and should get the game up to a playable state. We'll see what I actually manager to get done

Lastly:
I've been using github to host the code, but I've decided to use the github pages (their website hosting....thingy) to update things. Right now it's just blank, but it seems pretty snazzy, customizable, and it's free, so for the time being, that will be where I update development progress (other than this journal). Additionally, it's linked to my github account, and hosts the game files that are easily downloadable from the website. http://hobogames.github.io/Eviiil-Empiiire-Extremely-Alpha/

Screenshots, other than the UI, are pretty much like last week. You can't see in the picture, but I've loaded a saved game )
skybox and UI credit here and here.
Full game code here:
Feel free to leave thoughts, criticism, comments, encouragement, or even discouragement, it's much appreciated
Cheers all!

Misantes

Misantes

 

Ending and Beginning

Hey everyone. This is my first journal entry here on gamedev.net. I thought I would try to get in the habit of making a weekly entry here, if only to gather my thoughts and try to think critically about what I'm doing I know this is the final day of the Week of Awesome (which I sadly didn't participate in), so it'll likely be drowned in a sea of entries, but, if I didn't do it today, it would be postponed another week, so. thanks to anyone who takes the time to read it

Since this is my first entry, a little background: I'm 36 years old, and just began programming earlier this year. I started with java, then moved into python, then finally into c++. I started work with SFML and c++ and was making 2D games. I recently started a new project with OpenGL. While I tend to learn quickly, there are certainly some giant gaps in my programming knowledge, as I'm using online resources primarily, and learning as I go. I would love any critical feedback on anything I post here, but please keep in mind I am not a seasoned developer and so much of the code may be less than ideal.

I'm currently abandoning my first project (perhaps only temporarily). It was a space survival/gathering simulator and my first 3D project.
I sadly don't have a github for this project, though could probably upload one if anyone wanted to take a peek.
My current thoughts and lessons learned:

Tools:
OpenGL, c++, SFML for audio.

Game:
3D survivalish space sim. You control a spaceship and can explore different star systems, suck out the atmosphere of the planets, or drill for minerals or beam up the lifeforms on the planet. The goal was supposed to be to create your own planet to live on and make it sustainable.

Approach:
As this was my first project, it truly began with just opening a window, and as I learned OpenGL and c++ I incorporated more and more into the program. While this was a fantastic way to learn, in hindsight, it is perhaps not the best way to develop a game So much of the code had to be rewritten, parsed down, rearranged etc. Additionally, the lack of planning began to make adding new elements to the game difficult as they had to be shoehorned into the existing code. A little bit of planning beforehand would have saved me weeks of rewriting code in order to incorporate the new elements. As this was my first 3D game, and first foray into anything resembling a complex game, I don't think I could have done it any differently and I'm hoping that much of this just comes with experience. I'll address some of the specific lessons in the journal below. But, all in all, I learned the value of having a good deal of planning beforehand

Obstacles:
Movement: Quaternions! Initially the bane of my existence, now my dearest friend. As a full 3d space sim, I quickly learned the limitations of trigonometry and game development (and my understanding of matrix math). Ultimately, they turned out much easier to implement and use than I was making them out to be. I was a little thrown off by how difficult everyone on forums described them. I found tutorials overly complex and less than helpful in actually describing what I was doing. Ended up having a eureka moment when I realized they were just rotations along an axis

Shaders:
I still don't have the greatest handle on shaders, but am finally able to implement at least basic lighting, a simple geometry shader, particle shader, etc.

Efficiency:
My lack of a computer science background is biting me here. I am generally able to limit unnecessary or needlessly repetitive code, and streamline OpenGL a little so as not to unnecessarily bind and rebind different shaders or VBO's etc. Perhaps it's not as bad as I imagine but it's "what I don't know that I don't know" that I worry about here. Ultimately I was able to generate about 900 solar systems with about 7 planets each having their own orbits, atmosphere, etc. and still get it to run at 60fps on my graphics card. It could certainly be more efficient and if I continue development, it certainly will need to be as I add elements into the game.

3D modeling and artwork:
Well, I'm not an artist. I have skills enough to be described as amateur at best when it comes to art. I was learning how to 3D model at this same time, but did not spend nearly as much time on it. Luckily, being a space game, it was mostly spheres Either I need to make friends with a 3D artist or dedicate much more time learning the ins and outs.

Fun:
This ended up being the reason why I am abandoning development. I initially wanted the game to play a little like "Don't Starve" or really any other survival type game. But, as mentioned above, I didn't really plan things out. After the game systems were in place I was smacked in the face with the reality of making a game fun. The first problem was that there was really no sense of urgency or danger, or really a need to make a livable planet. So, I added a "family" to your character. I plopped them down on a barely habitable planet, and set the gravity so that the atmosphere would slowly leak away, and the animals were imbalanced and killing each other off. This helped a little, but I have to admit, it felt weird being a space traveling creature who had to survive off meat Additionally, it made every creature in the game serve the same purpose, which wasn't terribly interesting, and the only game obstacle was making the creatures play along with each other(they all had randomly assigned "attributes" and when placed together on a planet, would either kill each other off or balance out).

I could go on about the "fun" factors or lack thereof, but honestly, when it came down to it, the game just wasn't all that fun. It was overwhelming because none of this had been planned out or implemented in the code and really it felt like starting from scratch, but worse, because any game implementations had to be roughly forced in to the existing code, making progress much slower and so much less enjoyable. Especially since I had already been working on the game for about 3 months. Since I had no goals when I started this game, I have to admit I didn't really feel a sense of obligation to continue. So, I've decided to cut my losses, learn some valuable lessons and start anew.

so, to the new game:
Sorry for the lack of originality But, the new game is a hex based strategy game of fantasy good v evil I've been working on it for a few weeks.
Github is here: https://github.com/Hobogames/TestGames
I've decided (as of this morning ) to use github to handle different forks and backup my code. Up until now I've been using copy.com and local backups.

Tools:
OpenGL, c++ SFML for image loading, input, audio, UI, window-handling.
Things I've implemented that I wanted to but didn't implement in my first game
More SFML:
I've incorporated OpenGL into an SFML window. My first game I had to hand create a dds of any font that I wanted to use. With SFML, I can use system fonts, which is great, simple and easy. Additionally, the UI is far simpler to handle using the 2D elements of SFML. It was a little more complicated to set up than I had hoped, but now that it is, I'm rather pleased with things. In addition to input and audio, SFML is turning out extremely handy.

Texture Arrays:
I've successfully implemented a texture array to handle my images. Though, I've already screwed up (I think) and used 1000x1000 sized images, which is probably less than ideal both in terms of size (too large?), and (maybe) its inability to be divisible by 32. I'm uncertain about that last part, but my limited experience tells me I should probably worry about efficiency there If anyone knows for certain whether that matters, I'm currently torn between resizing everything, or just leaving it be. I'm going to redo all of the artwork and modeling at some point before releasing this (certainly for free), so this isn't a pressing concern at the moment.

Planning!:
So, I've sat down and worked out my game mechanics on paper. It's a pretty standard hex based game, so I'm hoping to not run into the wall of the previous game. Additionally, I've decided to rely a little more heavily on class "managers." I'm uncertain if this is really ideal, but thus far it has been extremely helpful in adding new elements, as the framework is there to incorporate new things. Whether it is new spells, new minions, etc. So, even if things change pretty drastically, it should be rather trivial to implement those changes. Hopefully this new system will make things clearer and less of a jumbled mess of code.

What's implemented so far
Sort of random tile and object generation:
As for as terrain generation goes, this is extremely archaic, but it's generating various "biomes" with good/evil forests, water and mountains. I'm trying to decide whether to delve into the intricacies of random terrain generation, or just tweak the current set up. I don't require too much here, it's not a huge game board, and there aren't that many complicated elements, so I'm unsure if it's necessary to complicate things.

2 Player Turns, with Minions:
Overlay to show how far player is allowed to move, players have magic and health. Rudimentary particle engine is in place so players can cast spells, which drain magic/health. Players can summon minions (currently just one ), which also have their own turns. Can build home base, that will ultimately be upgradeable, and serve as the players central hub.

Dynamic Camera:
I'm rather proud of this. For each turn, the camera will search out and focus on the player whose turn it is. I'll alter it later to let you tab through the characters, ala the civilization games(or really any strategy game). There are a couple bugs in it currently. 90% of the time it works beautifully. But it changes the height, rotation, and x/z axis simultaneously but independently, so if you're too high, and it reaches the x/z location of the player before it's fully lowered itself it gets a little bumpy in its movements as it alters one, which changes the distance of the other so it moves again. I just need to have it calculate the angle and distance as one directional movement and change that, instead of each independently.
day/night cycle:
Since it's good v evil, the game will switch from day to night. Currently, I'm just dimming/brightening the skybox at the end of every turn, but whether it is day or night will have an effect on the players depending on their affinity.

2D billboarding and animation
I've spent a little more time on the art and 3D modeling out of necessity, though it's still extremely placeholder. I'm going to be honest and admit, I don't actually know how to bumpmap the textures, so everything looks a little cell-shaded. Additionally, I've billboarded the players to compensate for my lack of knowing how to animate 3D models (other than the archaic stop-motion method). It does add a bit of charm I think, and additionally, developing this alone, I'm unsure if i'll have time to really do a lot of skeleton rigging, etc for a whole slough of minions and everything. So, 2D billboarding for players, and simply animating those is far easier and far less time consuming.

To be Implemented:
Villages and NPC's. AI is going to take a lot of learning on my part and I've already started my reading on it. Being a 2 player game, I may scrap the AI as it's not intrinsically necessary.

More spells, characters, upgrades, etc:
The basics of movement and attacking are in place, but little else. So, the slow process of adding and balancing skills, minions, etc.

Options:
My first game didn't really have slidable options for volume, screen size, etc. I still need to implement all of this. I've at least taken the initial steps to set a variable to the screen size that is changeable, and with SFML handling the window, it scales things automatically. I've yet to add audio and am waiting until I've set up the options module.

Audio:
I've actually been a musician all of my life, playing piano, guitar and violin. Though, for my first game I used assets from freesound.org as music is time consuming, and I'm already stretched pretty thin. I'd like to rely less on open assets and create my own. But, this would be a pretty large undertaking in addition to programming and the artwork, so.....I don't know. Perhaps I'll do some light work and make the atmosphere rather minimalistic.

Thoughts:
I'm sitting down with a friend who is a DM and plays waaay too much D&D, to go over some of the intricacies of the game mechanics. Though the initial framework is laid out, the specifics are definitely not, and I don't want to implement too much if there's a danger of it changing too drastically.

I've already let the code become far more messy than I had originally planned. I had these great intentions of keeping everything neat and documented, but over time it's becoming less so. And, I'm only two weeks in. I try to periodically go through and clean/document things, but I'm already lapsing into bad habits with mixed cases and poor naming. If I ever do want to collaborate with anyone, I definitely need to rehabitualize myself. I'm working on it

That's about it. Feel free to go through the code and let me know what you think. Just remember I'm still quite the beginner and please let the criticism be constructive. I'll definitely appreciate the feedback though Additionally, I've only compiled this on linux, as I've wiped my Windows drive and haven't bothered to reinstall it (it tends to bork my boot loader, and is a pain to fix). If anyone tries to run it on windows, feel free to let me know what's missing to compile it on windows, I'll do my best to include it and get an .exe working for it.

Here are a couple screenshots from the abandoned game, and the new one. Bear in mind, especially in the shots of the "spells" that it's placeholder art :
Credit:
All the artwork ought to be my own terrible art, other than the skyboxes and UI in both images.
skybox credit: here and here
UI credit : here and here

Misantes

Misantes

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!