CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.26k stars 4.11k forks source link

Implement general purpose timer queues #28290

Open mlangsdorf opened 5 years ago

mlangsdorf commented 5 years ago

Timer Queues

CDDA needs a standard API to run a task/function at some specific future date. This API would also need the ability to reschedule a task and cancel a task.

The immediate obvious use would be off-map NPC behavior, but I'm sure there's lots of other uses.

Details TBD

I'm fuzzy on the implementation details. Someone with a better idea should fill this in.

neitsa commented 5 years ago

Mark, I did a simple implementation which can be seen here.

In this implementation you can:

Combining both recurrence and periodicity allows some patterns as: repeat the task every 3 turns but do it only 5 times.

The code is not really complicated if you follow through. The idea would be to replace the timestamp_t type in the example with the calendar type from CDDA (or anything else that expresses time). The queue execution function (execute_tasks) should be integrated somewhere in the game loop (and the queue itself in the game class I guess).

The only downside that I see in this implementation is that you can't really get the return type of the function, unless the function store the result itself somewhere (and honestly I can't do any better c++ here...).

Please let me know if it suits you needs or what you would like to change. If appropriate I can also integrate it in the game and do a PR.

free-coffee commented 5 years ago

Hi guys. So i didn't know about this issue and started working on the same thing - partially as a learning experience. Now that i found this i want to post my so-far code for others potentially working on it: https://github.com/free-coffee/Trigger The implementation relies on the game clock calling a function pointer every frame/second/minute etc. (didn't look into specifics, if there is no point for this in the clock-code maybe an interrupt-like solution?). The Triggers are stored in timing-specific ques and each consist of a condition and a function to call. Upside to this is performance (since in most cases the frame pointer will do nothing), downside is it's harder to understand (since functional programming is less common than procedural & object-oriented). I'm not at the point where i would've communicated my code. I'll try to reach that point within this (or next) month.

kevingranade commented 5 years ago

Seems pretty straightforward. What we really need for v1 is a use case that uses the thing, or ideally several. That will shape the tradeoffs we make when developing it.

free-coffee commented 5 years ago

possible use cases:

  1. map updates outside reality bubble
    • horde movement
    • corruption (fungal/insects/triffids) spreading [design wise dangerous]
    • nomad monsters/NPCs.
    • Map element progression, e.g. a building become ruins once they got enough damage.
  2. setup specific:
    • Fail/Change Triggers in Scenarios/Missions.
    • mod specific events/progression.
  3. map element specific:
    • Monster/items change their behavior based on the spawning game state.
    • Map element progression under special circumstances.
    • delayed spawns/map creation.
  4. Random events:
    • At setup Triggers are chosen from a pool and activated later.

I'm basically thinking of the SC2 Trigger Editor for this Feature.

kevingranade commented 5 years ago

From that list mission triggers are by far the best option. We actually encountered problems with NPC mission structure because we didn't have a mechanism to trigger NPC return to base after completion of a task, so we have a kind of nonsense feature where the player manually calls them back.

Corruption spread for e.g. fungus is also a good idea. Random events would be nice too.

Hordes are not a good match because those will be happening so often they need a custom solution. Same with nomadic monsters and NPCs.

Building ruination is something we handle once we load the map chunk.

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. Please do not bump or comment on this issue unless you are actively working on it. Stale issues, and stale issues that are closed are still considered.