My New Game ... still untitled

There's only need for one forum for now. Discuss development. No advertising or thinly veiled attempts at advertising. Create a single thread for your project and be prepared to show and tell.
User avatar
Deckhead
Site Admin
Posts: 92
Joined: Fri Feb 21, 2020 5:44 am
Location: Sydney, Australia
Contact:

My New Game ... still untitled

Post by Deckhead »

So; I'm burnt out on The Last Boundary. I've spent a long time on it, and I don't even like Visual Novels. The whole story of how that game turned into what it is is sort of funny. But long story short, I woke up one day and said "oh shit, I'm developing a Visual Novel"...

Anyway, I got a somewhat completed game out the door, and I'm sick of it, so time to move on. Total budget spent on that game... $0.

The New Game

I'm going to make a game like Dwarf Fortress / Rimworld. It will be 2D, use graphics, have some minor animation for character actions. There will be a Z-Level, game will be top-down.

I'm going to present it in a sort of Cyberpunk aesthetic. The player will start with a small group of people who have figured out that if they want to survive in the post-collapse city, they're going to need to stick together. The starting point will be an abandoned building, and the player will go from there.

Rival groups will be simulated and may attack, or trade, or sneak/hack into your camp. You can expand, etc, build up your camp. I think I'm going to go with "clan" rather than "colony" or "fortress". "Clan" to me is reminiscent of online game clans (if they're still a thing). New people may join your clan.

In similar games, you start with a small amount of supplies, I think that's appropriate for this game. You then start to scavenge what you can from your immediate surroundings, in my case that could be wiring and electronics from surrounding buildings, or even the building you're in. Essentially it's all the same mechanics you've seen before, but a sci-fi bent to it.

Later, as the game progresses, I'll add a little more to it so that it has new mechanics not been done.

So far I have done a couple things:
  • Thought about the game
  • Decided on this genre, because I can iteratively build on it once the core concept is in there (big thing for my hobby time allowance)
  • Decided on the setting
  • Decided that I will need an Entity Component System that focuses on Data Locality
  • Developed an ECS above from scratch
  • Decided I will need to use some variation of G.O.A.P for the A.I.
  • Decided on JSON for the game data format
  • Halfway written a JSON file reader
A lot of people would say I should use an existing engine, but I won't. I like doing it all myself. The ECS I made is pretty cool, you use it like:

Code: Select all


#include "ecs.hpp"

struct Position
{
    float x;
    float y;
};

struct Velocity
{
    float x;
    float y;
};

int main()
{
    ECS ecs;

    ecs.RegisterComponent<Position>("Position");
    ecs.RegisterComponent<Velocity>("Velocity");

    Entity ent1(ecs);

    ent1.Add<Position>({1,2});
    ent1.Add<Velocity>({.5f,.5f});

    Entity ent2(ecs);

    ent2.Add<Position>({5,24});

    System<Position,Velocity> system(ecs);

    system.Action([](const float elapsedMilliseconds,
                     const std::size_t& numItems,
                     Position* p,
                     Velocity* v)
    {
        for(std::size_t i = 0; i < numItems; ++i)
        {
            std::cout   << i << " -----------------\n"
                        << "P: (" << p[i].x << ',' << p[i].y << ")\n"
                        << "V: {" << v[i].x << ',' << v[i].y << ")"
                        << std::endl;

            p[i].x += v[i].x * (elapsedMilliseconds / 1000.f);
            p[i].y += v[i].y * (elapsedMilliseconds / 1000.f);
        }
    });

    for(int i = 0; i < 100; ++i)
        entityManager.RunSystems(1000);

    return 0;
}

Which to me is pretty elegant. Anyway, back to working on the JSON data loader.
Developer of The Last Boundary and webmaster of IndieGameDev.net

100goats
Posts: 42
Joined: Mon May 04, 2020 9:29 pm

Re: My New Game ... still untitled

Post by 100goats »

Nice.

I want to play this game.

What new mechanics are you thinking of adding?

User avatar
Deckhead
Site Admin
Posts: 92
Joined: Fri Feb 21, 2020 5:44 am
Location: Sydney, Australia
Contact:

Re: My New Game ... still untitled

Post by Deckhead »

I'm thinking about "augmentations" firstly. I think people in the future could have like inbuilt plugs that they can equip augments into, interchangeable like. Because the game is set in a post collapse cyberpunk world, I can see these augments being found rather than being manufactured by the player.

One of the overarching things is that from the players perspective it's post-collapse, but it's just how the world is. There's still a "government" and some megacorps around, and you can come across them, but for the average person, it's all about survival. I'm thinking about the player raiding augment labs/factories when they are very strong.

Another mechanic I wanted to add to the genre was stealth. Games like Dwarf Fortress and RimWorld, to my knowledge, don't have stealth. I can see sending lone characters around outside your base could be done stealthily, or not.

Allows them to steal equipment etc from rival groups.
Developer of The Last Boundary and webmaster of IndieGameDev.net

User avatar
Deckhead
Site Admin
Posts: 92
Joined: Fri Feb 21, 2020 5:44 am
Location: Sydney, Australia
Contact:

Re: My New Game ... still untitled

Post by Deckhead »

Update 23/05/2020

I've implemented:
  • An Entity Component System - made some changes to what I had before, so much that I think I should update that article I wrote
  • Thread Pool - I already had an A* algorithm, but while testing against 100 clan members (that's what i'm calling them), in a 400x400 tile map; I found performance a little lacking. For example, trying to calculate all their paths in the first frame, gave a couple seconds pause. The thread pool, on my machine it uses 4 threads, but it's adaptable to the system it runs on, brought this hiccup down to a second or so on my machine in testing. Good improvement, I can change it so that I never calculate 100 paths at once :)
  • Graphics - lol, they're just squares; but the map scrolls, renders super fast, and even when you zoom out as far as the graphics memory will allow, it's still go a frame time of about 16ms on my toaster-machine (which is about 60fps)
  • Tile Picking - no matter the zoom-level, player selects a tile and it's registered as the right one
Right now; a world is created which has two resources randomly thrown about on tiles. The guys randomly pick a spot to go to, go there, then pick another spot. I'm reading up on GOAP now to give them goals, one of the resources will be something they implicitly need (like food for example), the other will be resource I command them to collect (a job). What I want to do is have them either go and find food to eat, or, to my job. Which they do, and when they swap to something else, will be based on how "hungry" they are.

Here's a picture of a bunch of guys, going around randomly.
Capture.PNG
Capture.PNG (77.39 KiB) Viewed 1329 times
Developer of The Last Boundary and webmaster of IndieGameDev.net

User avatar
Deckhead
Site Admin
Posts: 92
Joined: Fri Feb 21, 2020 5:44 am
Location: Sydney, Australia
Contact:

Re: My New Game ... still untitled

Post by Deckhead »

Update 26/05/2020
I don't have any new images to show, it all looks about the same:
  • I've added walls to tha game and ensured Pathfinding works as expected
  • Created a Job Queue system where your guys will take a job off the list when they're ready to do a new one
  • Jobs/Tasks result in a list of Actions for the guy to complete. Goto, PickupItem, and DropItem are all I have so far
  • Player can multi-select with a box
  • There's a stockpile that they take everything to
  • Tiles have a stack of items on them
The next things to implement I think will be
  • Player defines the stockpile area
  • Guys will require food/rest so will stop work to complete an Eat or Sleep Task
  • Player can define a Build Wall Task with associated BuildWall action for the guys
  • Refactor some spaghetti
As an aside, after reading some more about GOAP, it's not going to be used for a while if at all. If it is ever used, it will be in combat/stealth, which is a long way off implementing.
Developer of The Last Boundary and webmaster of IndieGameDev.net

100goats
Posts: 42
Joined: Mon May 04, 2020 9:29 pm

Re: My New Game ... still untitled

Post by 100goats »

Good progress!

User avatar
Deckhead
Site Admin
Posts: 92
Joined: Fri Feb 21, 2020 5:44 am
Location: Sydney, Australia
Contact:

Re: My New Game ... still untitled

Post by Deckhead »

Update 01/06/2020

Progress has been slow this last week or so.
  • I found a whole lot of memory bugs in my Entity-Component System implementation. I've managed to fix all of them though it took quite a bit of work to figure it all out. I need to find some time to update the article on the website here for a third time to include all of the changes made.
  • While working on implementing the AI to complete work assignments, I realised that I do need GOAP, or something like it. So I've started work on a GOAP implementation. So far, I've managed to make a simple system that uses an std::variant (instead of boolean values so that I can check for equality across different data types) for the world-state variables. It uses a forward search with A* and produces the expected sequence of actions.

    But I've struggled a lot with proceeding from there. For example:
    • If the agents job is to "collect food"; should the planner decide which piece of food to fetch; or should that be left up to the action when it's actually activated and being undertaken? I.e. should the findFood action actually find the itemID of the food during planning; or during activation? Should the check for context that's run during planning actually find a piece of food and then forget about it, only to have to be found again during activation (that seems wasteful)?
    • If the itemID of the food is found during planning; how is that passed between the actions like goTo which would want a destination. How do you handle multiple goTo steps in that respect? (I wrote a question here https://stackoverflow.com/questions/621 ... m-the-goal)
    • Likewise, should the planner locate a stockpile to put the item; or just have the planner do a findStockpile and leave the actual finding of it until later?
    • How do I handle a goTo action? Does it need to know where to go during planning? Does it need to know that a path is possible during planning? If it does, then I need the variables to understand the path. If using A* regressively, how would that even be possible, you can't determine a path isn't possible if you don't know what you're looking for yet.
    I've studied all of the material written about GOAP; studied the code of 6 different implementations.... and I'm still struggling. Each of these implementations does things differently; and when you read about the theory, it gives you implementation details (for example, you should be able to use variables in planning that are resolved while searching backwards from the goal), but never an explanation of how that's possible etc.

    So I believe I should be doing this
    • Actions use my std::variant for preconditions and effects; later on, I might add arithmetic and different comparison ops to this
    • Actions don't actually find a food itemId or a stockpile. They may do things like check that food exists within a certain radius, or is flagged to be within player territory or something, but won't actually need the food itself, just that food exists and we're reasonably sure we can get it.
    • goTo action doesn't need to know it's path for planning. Just that it has the effect of atLocation=true. It has no preconditions. So if any other action, such as pickUpItem has a precondition atLocation a goTo will be used to set it to true. The effect of any action that requires atLocation should be to set it to false as an effect, leaving it open for another action to use it.
    • If when executing the plan, a path can't be found, or a suitable item can't be found, then the plan can be discarded and a new one found. I think this can't actually occur before the plan is giving to the agent; because at that point a path through the actions has been found, so I can forward-input all the information, so things like the targetId from the findFood action will be set, followed by the path from the goTo action etc.
Anyway; back to it.
Developer of The Last Boundary and webmaster of IndieGameDev.net

User avatar
Deckhead
Site Admin
Posts: 92
Joined: Fri Feb 21, 2020 5:44 am
Location: Sydney, Australia
Contact:

Re: My New Game ... still untitled

Post by Deckhead »

04/06/2020 Update

GOAP is now implemented. I found that I couldn't do regressive planning because many state variables were reused, and so it wasn't really possible to keep track of a goal state that required a state variable to be two different values at different times. I could have instead used several different names for things like "agentLocation" but that just seems to me like I would be defining a million different variables at different times, effectively determining the possible plans.

So instead I kept it with the forward planning, and that's working well. I've discovered that I need to keep the possbility space as small as possible. For example, if the task is to haul an item to a stockpile, there's no point in putting the "findEnemy" or "killEnemy" actions in there, they aren't relevant, and because things like "findEnemy" don't require a starting condition, the exploration space explodes out quite a lot. Even with just a total number of tasks at like 10, just one additional task with no starting conditions baloons the whole thing out by 10x.

So now I've got a Work Queue which the player appends tasks onto. I intend later to have the game create tasks that sit outside the queue as well... for example, if the player sets a zone to be the "rat catching area"; the player wouldn't need to manually add "place traps" and "check traps" tasks. Instead, the worker themselves should somehow determine that this needs to happen. Haven't quite got that figured out, but I think a zone will have a bunch of properties (depending on the type of zone it is), that have defaults but that the player can edit.

As an example, the "Rat Catching Zone" will define the total number of traps per square-meter. The player can increase or decrease this. Your worker guys, when they're looking for a task and have the job of "Rat Catcher" (or Food Gatherer or something), will look at each "Rat Catching Zone" and see if the number of traps is how many are needed and place traps (if there's any available to set). They'll also have a memory on each trap of the last time it was checked, probably a shared-memory between all "Rat-Catchers", so they can then check traps.

The Planning and Path Finding are all done in the Thread Pool, so there's little effect on the games frame-rate. But there is occassionally a little hickup... I think it's because I'm using futures in the threadpool and waiting 1 microsecond on them is causing the hickup...
Developer of The Last Boundary and webmaster of IndieGameDev.net

User avatar
Deckhead
Site Admin
Posts: 92
Joined: Fri Feb 21, 2020 5:44 am
Location: Sydney, Australia
Contact:

Re: My New Game ... still untitled

Post by Deckhead »

Small video example of how it's going so far.

Developer of The Last Boundary and webmaster of IndieGameDev.net

Nastia_Sholokhova
Posts: 5
Joined: Thu May 07, 2020 5:00 am

Re: My New Game ... still untitled

Post by Nastia_Sholokhova »

Looks very interesting!

Post Reply