Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message Bus v1 #61

Closed
wants to merge 33 commits into from
Closed

Message Bus v1 #61

wants to merge 33 commits into from

Conversation

vesper-arch
Copy link
Owner

It turns out that restructuring the entire game is a little hard.

@vesper-arch
Copy link
Owner Author

I feel like a good portion of the re-writes are in how combat is done. Changing from a handful of functions to a class is putting my logic skills to the test. Aside from that, converting all of the items to classes is more time-consuming than difficult.

I need a system for registering and unregistering components so enemies only have their callback functions called when they are in combat.
@vesper-arch
Copy link
Owner Author

@miketwo Could you give an example of how this code works?

    def subscribe(self, event_type: Message, callback, uid):
        if event_type not in self.subscribers:
            self.subscribers[event_type] = dict()
        self.subscribers[event_type][uid] = callback
        if self.debug:
            ansiprint(f"<basic>MESSAGEBUS</basic>: <blue>{event_type}</blue> | Subscribed <bold>{callback.__qualname__}</bold>")

The main thing I'm confused about is how the dictionary is structured. I kinda need to know that if I'm going to have an .unsubscribe() method

@miketwo
Copy link
Collaborator

miketwo commented Feb 11, 2024

Yeah. It's a dictionary of dictionaries. The Message is the first key, the UID is the second. So it'll look something like:

{
  'before_attack': {
     uid111: <callback function>
  },
 'start_of_combat': {
    uid111: <callback function>,
    uid222: <callback function>
  }
}

The unique combination of a message and uid gets you a specific callback. Subscribing with the same message and uid overwrites the callback. An unsubscribe would need to know both those values.

I'll push a commit with a test that demonstrates it.

Michael Ricks-Aherne and others added 2 commits February 11, 2024 21:53
…tate during combat instead of them being removed from the enemies list.
@vesper-arch
Copy link
Owner Author

vesper-arch commented Feb 12, 2024

Why won't grandalf install. The tests fail when I run them because of it but even if I use pip install grandalf(and it says its already installed) it still brings up an import error

@vesper-arch
Copy link
Owner Author

Right now I'm struggling with how to manipulate the Combat.active_enemies list to dictate how rewards should be given. My first idea was to take the last alive enemy and see what their state was but its like 8:30 pm and I can't be bothered to figure it out right now.

@miketwo
Copy link
Collaborator

miketwo commented Feb 12, 2024

Why won't grandalf install.

pip and poetry are 2 separate things. So if you're using pip to install in one virtual environment and poetry to run the tests/game in another, they won't see each other's libraries. You need poetry install --no-root

@miketwo
Copy link
Collaborator

miketwo commented Feb 12, 2024

how to manipulate the Combat.active_enemies list to dictate how rewards should be given

Not sure I know what you mean... Cause there's already code around potion drops and gen.cards_rewards, right? So is it erroring out? Or you need something else to happen here?

@miketwo
Copy link
Collaborator

miketwo commented Feb 12, 2024

I'll start rewriting the tests. Cause it's such a big change that I'm sure most of them will break (for not valid reasons).

@vesper-arch
Copy link
Owner Author

The problem I have is that I need to decide whether or not to give the player rewards based on what the last alive enemy did. If the last enemy escaped then I wouldn't give the player rewards. If the last enemy died then I would give the rewards. I'm not sure how to know if the last enemy died or escaped or what the last enemy is in the first place.

@miketwo
Copy link
Collaborator

miketwo commented Feb 12, 2024

Have enemies fire messages on death/escape, catch the message in Combat and check conditions for last enemy/rewards?

@vesper-arch
Copy link
Owner Author

Sounds like a solution!

@vesper-arch
Copy link
Owner Author

vesper-arch commented Feb 12, 2024

I just started using linux(in vm) and I have already phased out the need for docker desktop. I love the terminal. Edit: I need docker desktop lol

@miketwo
Copy link
Collaborator

miketwo commented Feb 13, 2024

WSL2 is pretty cool overall.

Michael Ricks-Aherne and others added 2 commits February 15, 2024 04:35
@vesper-arch
Copy link
Owner Author

Currently getting brainrot from Rust while trying to convert hex to rgb. It's fun tho.

@miketwo
Copy link
Collaborator

miketwo commented Feb 16, 2024

All good. I can't really code anything until the mega-PR-rewrite is done (cause it'll have conflicts). Do you want to do it in smaller chunks?

@vesper-arch
Copy link
Owner Author

Like smaller commits? I could do that.

@miketwo
Copy link
Collaborator

miketwo commented Feb 16, 2024

Yeah more like keeping the branch-commit-merge cycle tight. Cause if there's a branch that changes a whole bunch of files, any other branches made while that's open run the risk of conflicts.

@vesper-arch
Copy link
Owner Author

vesper-arch commented Feb 16, 2024

Ah, ok. I'm just struggling with finding out how to make the enemies communicate with the combat class when they die/escape.
The idea that I'm trying to work through is using the message bus so that messages can be sent through the message bus and into the combat class.

@vesper-arch
Copy link
Owner Author

Forgot to add that I fixed combat not initializing.

@miketwo
Copy link
Collaborator

miketwo commented Mar 24, 2024

Re-enabled the tests. Why is items.cards done as a generator?

@vesper-arch
Copy link
Owner Author

That was not intentional. I meant to make it a tuple but didn't realize that using parentheses made a generator. I had to fix that when making the death message system but I didn't remember that I made the same mistake with items.cards.

@vesper-arch
Copy link
Owner Author

I don't know why items.cards didn't show up there.

@vesper-arch
Copy link
Owner Author

vesper-arch commented Mar 25, 2024

@miketwo Could using a Mock class work as a default value for functions like blocking that can not have a card source? It looks like its designed to be used in tests but I don't know another solution at the moment. P.S. I also realized that I've forgotten to change the type annotation for the card parameter there.

@vesper-arch
Copy link
Owner Author

Edit: No. I can just make the relics and such that activate only when cards are used return early if the card parameter is None.

@vesper-arch
Copy link
Owner Author

Neovim is the best editor I've used.

@vesper-arch
Copy link
Owner Author

Working on adding potions rn

@vesper-arch vesper-arch linked an issue Mar 31, 2024 that may be closed by this pull request
@vesper-arch
Copy link
Owner Author

@miketwo Should I try and remove global variables whenever necessary? I'm trying to get rid of player and active_enemies and it feels like I'm making the code more complicated than it needs to be.

@miketwo
Copy link
Collaborator

miketwo commented Apr 1, 2024

Yes. Global constants are ok, but anything mutable should have a smaller scope. Otherwise it couples together very distant parts of the code.

It can be annoying to pass context around, but it shows where things are connected. The alternative is untraceable bugs that happen when something mutates your global when it's not supposed to.

@vesper-arch
Copy link
Owner Author

vesper-arch commented Apr 2, 2024

O_O
image
Edit: Class variables exist lol

@vesper-arch
Copy link
Owner Author

Never doing a big pr like this again. It feels like development is going very slow right now.

@miketwo
Copy link
Collaborator

miketwo commented Apr 19, 2024

Correct.

@vesper-arch
Copy link
Owner Author

Definitely keeping this in mind once this whole brainrot session is over with. Is there anything I can do right now to improve it?

@miketwo
Copy link
Collaborator

miketwo commented Apr 19, 2024

Is there anything I can do right now to improve it?

Mikado Method works sometimes. Which is like figure out all the things you were trying to do simulateneously here (rewrite combat system, remove globals, change Game into a class, ....) and break them all apart. Revert and work your way down the pre-reqs. You know a lot more now about the problems you're going to run into, so you can just solve those pre-reqs first. Don't try to boil the ocean, just start with a pot of water. So long as you've got the branch, you can always refer back to it or copy code over. But do it in much smaller chunks.

For example: A PR that only removes 1 global var, not all of them. Or a PR that only uses the message bus once, for like START_OF_COMBAT or something. Little improvements that stack.

@vesper-arch
Copy link
Owner Author

vesper-arch commented Apr 20, 2024

Okay. It took me a while to fully understand what the process was but I have a general plan laid out here:
image
I haven't really done anything like this before, so I'm not sure if this is the best way to lay it out.
Also, I looked at the diff for this pr for the first time and it is a nightmare.

@vesper-arch
Copy link
Owner Author

No more.

@vesper-arch vesper-arch deleted the message_bus_fixed branch April 20, 2024 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unknown encounters do nothing.
2 participants