Jump to content

aiaf

Members
  • Posts

    720
  • Joined

  • Last visited

Blog Entries posted by aiaf

  1. aiaf

    programming
    Didn't post here in a long time , this will be about storing game data.
    There are  a lot of options on how to store your game data structures:
    files (json,xml,yaml , custom etc) databases , nosql dbs memory (if no persistence needed) Also if you use an engine it could provide its own way of storing data.
    Choosing a good way to do persistence is important.
    This depends on lots of factors like game type, complexity of data structures etc
     
    Ill describe below a way to use the sqlite3 database:
    https://www.sqlite.org/index.html
     
    Some code i wrote that generates a class with support for sqlite3 database persistence:
    https://gist.github.com/aiafrasinei/65cb2cfeeb417459e0ab927302168abc
     
    Example how to use:
    SqlHt::GetInstance().Generate("Config title_s height_i width_i fullscreen_i vsync_i", true, true, false); This will generate the file Config,h with this code :
    class Config { private: sqlite3 *db; char* zErrMsg = 0; protected: public: string Title; int Height; int Width; int Fullscreen; int Vsync; Config(string Title, int Height, int Width, int Fullscreen, int Vsync) { filesystem::path p("Config.db"); if(filesystem::file_size(p) == 0) { string sql = "CREATE TABLE Config ( ID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, TITLE TEXT, HEIGHT INTEGER, WIDTH INTEGER, FULLSCREEN INTEGER, VSYNC INTEGER )"; char * sql_const = const_cast<char*>(sql.c_str()); sqlite3_exec_ec(db, sql_const, zErrMsg); string insert_sql = "INSERT INTO Config ( ID, TITLE, HEIGHT, WIDTH, FULLSCREEN, VSYNC) VALUES (NULL,'" + Title + "', " + to_string(Height) + ", " + to_string(Width) + ", " + to_string(Fullscreen) + ", " + to_string(Vsync) + ")"; char * insert_sql_const = const_cast<char*>(insert_sql.c_str()); sqlite3_exec_ec(db, insert_sql_const, zErrMsg); } else { int rc = sqlite3_open("Config.db", &db); } sqlite3_stmt* stmt = NULL; string select_sql = "SELECT * FROM Config"; int ret = sqlite3_prepare_v2(db, select_sql.c_str(), -1, &stmt, NULL); if (ret != SQLITE_OK) { string err(zErrMsg); cout << "Nothing to select, db should contain at least one entry" << endl; sqlite3_free(zErrMsg); } ret = sqlite3_step(stmt); while (ret != SQLITE_DONE && ret != SQLITE_OK) { int colCount = sqlite3_column_count(stmt); for (int colIndex = 0; colIndex < colCount; colIndex++) { int type = sqlite3_column_type(stmt, colIndex); const char* columnName = sqlite3_column_name(stmt, colIndex); string cns = columnName; if (type == SQLITE_INTEGER) { int valInt = sqlite3_column_int(stmt, colIndex); if(cns == "HEIGHT") { this->Height = valInt; } if(cns == "WIDTH") { this->Width = valInt; } if(cns == "FULLSCREEN") { this->Fullscreen = valInt; } if(cns == "VSYNC") { this->Vsync = valInt; } } if (type == SQLITE_TEXT) { const unsigned char *text = sqlite3_column_text(stmt, colIndex); if(cns == "TITLE") { this->Title = string(reinterpret_cast<const char*>(text)); } } } ret = sqlite3_step(stmt); } ret = sqlite3_finalize(stmt); } Config() { } ~Config() { sqlite3_free(zErrMsg); sqlite3_close(db); } sqlite3 *GetDb() { return db; } bool Persist() { string update_sql= "UPDATE Config SET TITLE='" + this->Title + "', HEIGHT='" + to_string(this->Height) + "', WIDTH='" + to_string(this->Width) + "', FULLSCREEN='" + to_string(this->Fullscreen) + "', VSYNC='" + to_string(this->Vsync) + "'"; char * update_sql_const = const_cast<char*>(update_sql.c_str()); return sqlite3_exec_ec(db, update_sql_const, zErrMsg); } bool Persist(string Title, int Height, int Width, int Fullscreen, int Vsync) { string update_sql= "UPDATE Config SET TITLE='" + Title + "', HEIGHT='" + to_string(Height) + "', WIDTH='" + to_string(Width) + "', FULLSCREEN='" + to_string(Fullscreen) + "', VSYNC='" + to_string(Vsync) + "'"; char * update_sql_const = const_cast<char*>(update_sql.c_str()); int rc = sqlite3_exec_ec(db, update_sql_const, zErrMsg); this->Title=Title; this->Height=Height; this->Width=Width; this->Fullscreen=Fullscreen; this->Vsync=Vsync; if(rc != 0) { return false; } else { return true; } } }; This way you can generate the data structures for your game that can be saved to disk.
    Also sqlite3 support in memory databases.
    Purpose of this article is to present some idea on how to store game data.
  2. aiaf
    2019 was slow year  for my gamedev hobby.
    Forth community project really has some good original content, i will make sure it gets released in a form or another.
    Still working on my game when i find the time.
     
    Lurking around and reading about leadwerks 5  progress heh, go Josh!
    Maybe we get another tournament after Le5 is release Somehow the tournament gives good motivation to make games.
    Cheers to everyone and a good new year.
     
    Some pulsating text example:
    #ifndef __S_PULSETEXT_H__ #define __S_PULSETEXT_H__ #include <string> #include "Leadwerks.h" using namespace Leadwerks; class PulseText { private: Leadwerks::Context* context; std::string text; double alphaInitial; float x,y; double r,g,b; bool pulse; float rate; public: PulseText(Leadwerks::Context* context, float x, float y, std::string text); void SetColor(float r, float g, float b); void SetPulse(bool active); void SetRate(float rate); void Update(); }; #endif  
    #include "PulseText.h" using namespace Leadwerks; PulseText::PulseText(Leadwerks::Context* context, float x, float y, std::string text) { this->context = context; this->text = text; this->x = x; this->y = y; r = 0.7; g = 0.7; b = 0.7; alphaInitial = 1.0; pulse = true; rate = 0.005; } void PulseText::Update() { context->SetBlendMode(Blend::Alpha); context->SetColor(r, g, b, alphaInitial); if (pulse) { if (alphaInitial > 0) { alphaInitial = alphaInitial - Time::GetSpeed() * rate; } else { alphaInitial = 1.0; } } context->DrawText(text, x, y); context->SetColor(0.7, 0.7, 0.7, 1.0); context->SetBlendMode(Blend::Solid); } void PulseText::SetColor(float r, float g, float b) { this->r = r; this->g = g; this->b = b; } void PulseText::SetPulse(bool active) { pulse = active; } void PulseText::SetRate(float rate) { this->rate = rate; }  
  3. aiaf
    I had a window popping up every time i was closing the game.Error below:
    Debug Assertion Failed! Expression: __acrt_first_block == header At first i thought is something related to me not deleting all pointers or closing the app the wrong way.So i fix that up same error.
    More investigating i figure it up that somehow is related to poco libs that i use to connect over tcp.If game exit code was before calling poco there was no exception.
    More wtf and curses for not being able to work on game and debug this.
    Finally solution was to rebuild poco with /MTd option, default built was with /MD and was causing incompatibilities seems.
    Glad i got over this , back to entry development
  4. aiaf
    Entry for tournament is on ?
    Check game information on link below and tell me this is not an odd game haha.
    I had  a limited amount of time for this because i go in holiday.Now its done was pretty painful even if i kept things simple , especially the debugging.
    Has multiplayer , and one way to capture territories.
    I will continue with this after tournament.
     
    Future plans:
    Ai clients.
    Adding more ways to capture territories.
    Alerts to players so they know they losing teritories.
    Host a single master server for everyone to play.
    Add end game and reset server data or increase the worlds count , ive not decided yet.
    Code cleanup
     
     
    Cheers
  5. aiaf
    Making a multiplayer game about territory conquest, like a board game.
    The winner will have the most territory.
    Something like risk but no dice rolls and more simple.
     
    So far i have:
    A socket server (written in go).This has the territories stored in db.
    Text communication protocol (using json). For example this is a register packet:  {"t":0, "p":{"name":"test"}}
    Game client that can select territories (using c++ poco network libraries)
    Sqlite3 for game data , i really like this wrapper (makes things less verbose):
    https://github.com/SqliteModernCpp/sqlite_modern_cpp
     
    Working on implementing game play server side.
    Here is main menu trying to be in line with retro theme

  6. aiaf
    I upgraded to Leadwerks 4.5 beta.
    And lots of the errors seen below:
    error C2872: 'byte': ambiguous symbol
    https://developercommunity.visualstudio.com/content/problem/93889/error-c2872-byte-ambiguous-symbol.html
     
    This worked for me and solved the issue:
    In Project Properties -> Language -> C/C++ set The C++ Language Standard to  ISO C++14 Standard (/std:c++14)
  7. aiaf
    Ive decided to plan better and fix milestones so i can actually finish this game, the main problem is lack of time.But i have patience.
     
    I got a domain and in the process to setup a website and a blog.The plan is to have a small release every 15 days.
    Will see how it goes, it would be nice to work full time on this but not possible at this time, still have to go to work for a living.
     
    Currently im about to finish a somewhat starcraft like resource gathering mechanic.
    A mine has a 1 transporter that gather resources from asteroids.
    I limited to just 1 resource transporter per mine so that the user has incentive to expand (build mines) for more resources.
     
    Will come back with a movie.
     
    For development stuff i want to say Object::GetAddress method is great.
    Besides the debugger, really helped to investigate some strange crashes.
     
    http://www.leadwerks.com/werkspace/page/api-reference/_/object/objectgetaddress-r26
     
     
    Cya
  8. aiaf
    Just started with Leadwerks.Heres a way to build a c++ project using cmake on linux.
     
    Start from an existing project (lets call it Proj):
     
    Copy
    ~/.steam/steamapps/common/Leadwerks
    into Source/Libs.
    Now you have Proj/Source/Libs/Leadwerks (this directory contains all the header files and static libs needed).
     
    Can use this Libs dir to add any other external libs you need.
     
    Here is the CMakeLists.txt:
    https://github.com/aiafrasinei/lep.git
     
    Copy to the root of the project.
    cmake . and make
     
     
    Will work on windows also with some modifications.
     
    ~/Documents/Leadwerks/Projects/test/Projects/Linux/Proj check the codeblocks project (Proj.cbp, Proj.depend) if you need to add more to the CMakeLists.txt
     
    Hope this helps
  9. aiaf
    A progress report on Structura
     
    First i want to say im glad i choose Leadwerks engine, easy to use and freedom to choose how you develop.
     
     
    This will be a single player rts game, is a long term project (written in c++, 11k lines of code at moment).
     
    Have some ideas that will differentiate this game from others:
    Game is controlled by a command line and some kind of rudimentary ui.Will see how far i can go with this, its around 100 commands implemented at the moment.
    I added game persistence on disk, want to have a persistent game world that wont restart, your actions should have consequences.Dont know if this would be feasible but i will try.
     
    You start with a unit that can have components attached to it and other units.
    Components that can be built:
     
    socket, tunnel, battery, unit, power_plant, logistic_center, recycler, mine, accelerator, platform, armor, barrier, standard_adapter, fortress_adapter, recon_adapter, deathstar_adapter, jump_drive, scanner
     
    A big part already have some kind of gameplay attached to them.They consume resources when built.
    Resources can be transfered from unit to unit etc.
    Code for building units/components is done and well tested you can build a potential infinite graph of this things if you have resources.
    Its some kind of limited minecraft.
    So far i dont know what will be the performance implications, i just go with it and will try some optimizations later.
     
    On the art department its not good, i use Model::Box , have to make time to learn blender, but i will not use textures it takes too long and i better use time for more gameplay.
     
    Video:


     
    Any feedback is welcome, i know it seems i went overboard with this but im making a game i would enjoy playing , if others will like it at some time will be a bonus.
     
    Regards
  10. aiaf

    postmortem
    Structura Postmortem

    https://store.steampowered.com/app/1422980/Structura/
     
    This game was done in my spare time, was about 4 years till the early access.
    Probably 6 months of full time work at best.
    I want to thank some of my work colleagues , who gave good hints/help about the game, in the coffee breaks (different times , no covid )
    And the Leadwerks community for always being helpful.
     
    Early access release:
    18 Dec, 2020
    Full release:
    6 May, 2021
    Here is the count of number of lines of code, no external libs included:
    cloc . 114 text files. 114 unique files. 1 file ignored. github.com/AlDanial/cloc v 1.90 T=0.08 s (1410.5 files/s, 463364.0 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- C++ 53 4679 738 25809 C/C++ Header 61 1046 206 4972 ------------------------------------------------------------------------------- SUM: 114 5725 944 30781 -------------------------------------------------------------------------------  
    For people in the community releasing their game on steam maybe this will help
    last week:

    all time:

    Overall the  number of sales was very small , but i was expecting that is really a niche game.
    And does not hand held the player.You actually need to put effort to play it.
    Which i completely understand many people just want to have some fun after work or whatever.
     
    So basically this game shouldn't have existed its too complicated for its own good,
    i just created something that i would have loved to play.
    The UI is pretty bad , but under the game play is really interesting and fun.
     
    There are 2 tutorials,  play both of them !!!,  no point to play the game otherwise it will just confuse the hell out of anyone.
     
    Good things:
    The game play is really unique.
    The game graphics style.
    Leadwerks community.
     
    What went wrong:
    The 1.0 release had a couple of bad bugs i didn't noticed.
    Current version is 1.1.7 and is stable but it took a lot of bug fix releases to get there.
    The choice to make my own UI.
    I have no art skills, so i just used what Leadwerks provided by default.
     
    The game is now stable, im proud of how it turned out.
    It has some rough edges, not the best UI.
    But the game play is really unique.

    No hand holding here, it requires some effort to learn.
    Just give it a chance and play the 2 tutorials.
    Standard tutorial play through:
    Advanced tutorial play through:
    I will continue to improve and bug fix Structura,
    the core of the game will not change.
     
    And with this article i finish the Structura devblog on this forum.

    In other news
    There will be another game in the Structura universe.
    And will use the Ultra Engine hopefully.

    Stay tuned for more info
     
     
  11. aiaf
    Draws a box from one vector to another.
    To be used as some kind of arrow.
     
    Need feedback if its a better way to do this, but so far seem to be ok for my purposes.
     
    Example usage:
    ArrowUi *t = new ArrowUi(Vec3(0.0, 0.0, 0.0), testshadow->GetModel()->GetPosition());
     

    class ArrowUi { private: Model *model; Entity *pivot; Vec3 from; Vec3 to; float distance; public: ArrowUi(); ArrowUi(Vec3 from, Vec3 to); void From(Vec3 from); void To(Vec3 to); void Draw(); }; ArrowUi::ArrowUi() { model = NULL; surface = NULL; pivot = NULL; from = NULL; to = NULL; } ArrowUi::ArrowUi(Vec3 from, Vec3 to) { this->from = from; this->to = to; Draw(); } void ArrowUi::From(Vec3 from) { this->from = from; } void ArrowUi::To(Vec3 to) { this->to = to; } void ArrowUi::Draw() { pivot = Pivot::Create(); pivot->SetPosition(from, true); distance = from.DistanceToPoint(to); model = Model::Box(0.05, 0.05, distance, pivot); model->Move(0, 0, distance/2); pivot->AlignToVector(to - from, 0); pivot->AlignToVector(to - from, 1); pivot->AlignToVector(to - from, 2); }
  12. aiaf
    Want to share this maybe will help someone.
     
    Its pretty basic but it has missile effect by distance and at certain time.
    Should be easy to extend.
     
    trigger the missile:
     

    tm3 = new Missile(Vec3(5.0f, 5.0f, 0.0f)); tm2 = new Missile(Vec3(0.0f, 0.0f, 0.0f), tm3->GetPosition(), true);
     
    and call the Loop method in the game loop
     

    #ifndef __S_MISSILE_H__ #define __S_MISSILE_H__ #include "Leadwerks.h" using namespace Leadwerks; class Missile { private: Emitter *mem; Material* unitexpmat; Model *model; Vec3 targetDirection; float mass; long creationTime; long detonationTime; void Init(); void Effect(Material* mat); public: Missile(); Missile(Vec3 pos); Missile(Vec3 pos, Vec3 targetDirection, bool launch); void SetDetonationTime(long detonationTime); void SetPosition(Vec3 pos); void SetDirection(Vec3 targetDirection); void SetMass(float mass); Vec3 GetPosition(); Vec3 GetTargetPosition(); void Launch(); void Loop(Material* mat); }; #endif
     

    #include "Missile.h" void Missile::Init() { model = Model::Box(0.1, 0.1, 0.1); model->SetColor(0.1, 0.1, 0.1); mass = 0.01; model->SetMass(mass); model->SetGravityMode(false); Shape* shape = Shape::Box(0,0,0,0,0,0,0.1, 0.1, 0.1); model->SetShape(shape); shape->Release(); creationTime = Time::Millisecs(); detonationTime = -1; } Missile::Missile() { Init(); } Missile::Missile(Vec3 pos, Vec3 direction, bool launch) { Init(); SetPosition(pos); SetDirection(direction); if(launch == true) { model->AddForce(direction[0], direction[1], direction[2], true); } } Missile::Missile(Vec3 pos) { Init(); SetPosition(pos); } void Missile::SetPosition(Vec3 pos) { model->SetPosition(pos); } void Missile::SetDirection(Vec3 targetDirection) { this->targetDirection = targetDirection; } void Missile::SetMass(float mass) { this->mass = mass; } void Missile::SetDetonationTime(long detonationTime) { this->detonationTime = (creationTime + detonationTime); } Vec3 Missile::GetPosition() { return model->GetPosition(); } Vec3 Missile::GetTargetPosition() { return targetDirection; } void Missile::Launch() { model->AddForce(targetDirection[0], targetDirection[1], targetDirection[2], false); } void Missile::Effect(Material* mat) { Vec3 nd = targetDirection.Normalize(); mem = Emitter::Create(200); mem->SetMaterial(mat); mem->SetEmissionShape(1); mem->SetEmissionVolume(Vec3(.50,.50,.50)); mem->SetDuration(300); mem->SetVelocity(nd[0],nd[1],nd[2],0); mem->SetColor(.30,.0,.0,.5,0); mem->SetColor(.20,.10,.10,0.4,1); mem->AddScaleControlPoint(0,0); mem->AddScaleControlPoint(.9,3); mem->AddScaleControlPoint(0.1,0); mem->SetLoopMode(false); } void Missile::Loop(Material* mat) { if(detonationTime > 0) { if(Time::Millisecs() >= detonationTime) { Effect(mat); mem->SetPosition(GetPosition()[0], GetPosition()[1], GetPosition()[2],true); model->Hide(); detonationTime = -1; } } else { if(model->GetPosition().DistanceToPoint(targetDirection) < 0.5) { Effect(mat); mem->SetPosition(targetDirection[0], targetDirection[1], targetDirection[2],true); model->Hide(); } } }
  13. aiaf
    I just updated my laptop to ubuntu 15.10 (from 15.04).
     
    And got into some intereasting issues.
     
    I rebuild my game with the new compiler, and it doesnt link anymore.
     
    I got a bunch of undefined references like below:
     
    undefined reference to `Leadwerks::Window::Create(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, int, int, int, int)'
     
    This didnt make any sense, the program was linking just fine with the previous version of gcc (4.9.2).
     
    After some digging i found the explanation:
     
    https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
     
    It seems in gcc 5.1 a new abi was introduced, and the Leadwerks static lib was built with some previous version causing the above problems.
     
    The solution i used was to add this macro at the begining of every cpp file in the project (in case of linux)
     
    #define _GLIBCXX_USE_CXX11_ABI 0
     
    Ths forces the use of the old abi and the game links just fine.
     
    I suppose this wont be really a problem for Leadwerks, but was annoying to me.
     
    Regards
×
×
  • Create New...