{"action":"created","issue":{"url":"https://api.github.com/repos/GoranM/bdx/issues/678","repository_url":"https://api.github.com/repos/GoranM/bdx","labels_url":"https://api.github.com/repos/GoranM/bdx/issues/678/labels{/name}","comments_url":"https://api.github.com/repos/GoranM/bdx/issues/678/comments","events_url":"https://api.github.com/repos/GoranM/bdx/issues/678/events","html_url":"https://github.com/GoranM/bdx/issues/678","id":159557447,"number":678,"title":"Suggestion: Notification System","user":{"login":"SolarLune","id":4733521,"avatar_url":"https://avatars.githubusercontent.com/u/4733521?v=3","gravatar_id":"","url":"https://api.github.com/users/SolarLune","html_url":"https://github.com/SolarLune","followers_url":"https://api.github.com/users/SolarLune/followers","following_url":"https://api.github.com/users/SolarLune/following{/other_user}","gists_url":"https://api.github.com/users/SolarLune/gists{/gist_id}","starred_url":"https://api.github.com/users/SolarLune/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SolarLune/subscriptions","organizations_url":"https://api.github.com/users/SolarLune/orgs","repos_url":"https://api.github.com/users/SolarLune/repos","events_url":"https://api.github.com/users/SolarLune/events{/privacy}","received_events_url":"https://api.github.com/users/SolarLune/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":16,"created_at":"2016-06-10T04:38:46Z","updated_at":"2016-06-12T17:01:29Z","closed_at":null,"body":"Hey, there.\r\n\r\nI was thinking while thinking about Gearend that a notification system might be a good idea to add to the engine. The idea is to reduce the amount of complexity of organizing the timing of events by abstracting informing GameObjects out to a global messaging system.\r\n\r\nLet's give a basic example of a platformer where you reach the goal and the level ends. During this time period, the player character might play a little dance animation, then the score tallies, and then some particles fly around, and so on.\r\n\r\nIf you were to do this manually, you'd be doing a lot of variable setting and checking, and every involved object would be touching at least one other involved object. \r\n\r\nUsing a notification system, though, you could more easily compartmentalize the process, and make it where each object only is concerned with doing its part when it's supposed to, and then “handing it off” for the next object to pick up. \r\n\r\nWhen the player character reaches the end goal, it would play the dancing animation. Once that's done, he'd broadcast that he's done with that animation. When the score tally receives that message, it would start counting up for every second left on the time counter. When that's done, it'd broadcast a message, and so on, down the line.\r\n\r\nThis would be to turn this:\r\n\r\n```java\r\n--Player.java--\r\n\r\nif (hit(\"EndGoal\")) {\r\n    spriteAnim.play(\"Dance\");\r\n}\r\n\r\n--ScoreCounter.java--\r\n\r\nPlayer player = scene.objects.get(\"Player\");\r\nif (player.spriteAnim.onLastFrame() && player.spriteAnim.active.name.equals(\"Dance\")) {\r\n    tally = true;\r\n}\r\n...\r\n```\r\n\r\ninto something like this:\r\n\r\n```java\r\n--Player.java--\r\n\r\n...\r\nif (touching(\"EndGoal\")) {\r\n    spriteAnim.play(\"Dance\");\r\n    if (spriteAnim.onLastFrame())\r\n        Bdx.notifications.broadcast(new Note(\"Player Dance Done\"));\r\n}\r\n...\r\n\r\n--ScoreCounter.java--\r\n\r\npublic void onNote( Note note ){\r\n    if (note.name.equals(\"Player Dance Done\")) \r\n        tally = true;\r\n}\r\n```\r\n\r\nNow it doesn't matter what exactly the dancing animation is for the player (i.e. if it's \"Dance\", \"Dance2\", \"Dance10\", etc), but rather just that whatever it is is over. It doesn't even have to be an animation; the player could run off screen, or do anything else with his \"time\".\r\n______\r\n\r\nSo, the notification system would allow for informing GameObjects about the state of the game through Note objects. Each Note object would have some information like so:\r\n\r\n```java\r\nclass Note {\r\n    public String name;\r\n    public float timestamp;\r\n    public HashMap<String, String> arguments;\r\n    public boolean read;\r\n}\r\n```\r\n\r\nThe name is the identifier of the notification (and the only thing you need to fill in). The timestamp allows you to tell when a notification was first sent (automatically set to Bdx.time when it's created), and the arguments HashMap can be modified to send additional data (like, say, the ID of the GameObject who created the Note, or whatever you need). `read` indicates whether the Note has been seen / received or not (see point 2) below).\r\n______\r\n\r\nThe Notifications class itself could work in two ways.\r\n\r\n1) Broadcasting.\r\n\r\nThe system can immediately broadcast data to interested parties. GameObjects can register with the Notifications class thusly:\r\n\r\n```java\r\nBdx.notifications.register( GameObject );\r\n```\r\n\r\nThis adds the GameObject to an internal list of listening GameObjects. To announce information, one can use:\r\n\r\n```java\r\nBdx.notifications.broadcast(Note note)\r\n```\r\n\r\nWhen some information is announced using the broadcast() function, all listening GameObjects will have a callback, `GameObject.onNote( Note )`, run. Only registered GameObjects will receive Notes this way – immediately.\r\n\r\n```java\r\nBdx.notifications.send(Note, GameObject)\r\n```\r\n\r\nwould allow you to send a Note to a specific GameObject. Useful for quick, special notifications.\r\n\r\n2) Queueing.\r\n\r\nThe Notifications class would also extend an ArrayList, allowing notifications to stack over time. This way, any GameObject can “post” Notes through a basic `Bdx.Notifications.add( Note )`, and any GameObject can read these public Notes whenever necessary. You could then appropriate a GameObject to act as a manager to deal with the Notes as you wish. To facilitate this more easily, a function to return the unread Notes (which, if this is run every frame, would basically be the accrued Notes between the previous frame and the current one) would be provided:\r\n\r\n```java\r\nBdx.notifications.getUnread() - ArrayList<Note>;\r\n```\r\n\r\nThis would return all Notes that haven't been read in the Notifications stack, and would automatically set those Notes to have been read. Notes broadcast are not put in the stack.\r\n\r\n2b) System Events.\r\n\r\nWe could also have BDX add system events to the stack, like window resizes, joystick connections or removals, scene endings, and so on, for whatever necessary. This could be toggled (i.e. no need to waste time and memory adding Notes for events the user's not paying attention to).\r\n_______\r\n\r\nSome other use cases:\r\n\r\n- Notifying the game world (NPCs, the GUI, etc.) of time and weather changes for visualization and different NPC behavior (i.e. \"It's now evening\", \"It's now morning\", \"It's now raining\", \"It's now snowing\").\r\n\r\n- Notifying the game world when the Player moves to another zone / area.\r\n\r\n- Notifying when transitions between scenes start and have finished, and when it's OK to teleport / switch to another scene.\r\n\r\n- Notifying AI NPCs when the world physically changes, signaling to update their pathfinding.\r\n\r\n- A stealth system in which NPCs investigate nearby ( `broadcast()` ) sounds.\r\n\r\n________\r\n\r\nSo what do you guys think? The TL;DR of this is that the Notifications system would allow the user to abstract out information passing between GameObjects, to make it easier to compartmentalize and structure. This would be effective across scenes as well, of course.\r\n\r\nEDIT: The Note class was originally called Message. That makes more sense, but I feel like Note is snappier and easier to conceptually tie to Notifications?\r\n\r\nEDIT 2: Maybe it might be nice to have Bdx.notifications just be a HashMap of names to different NotificationStacks (which acts like Bdx.notifications as proposed above), so you can register and broadcast to specific groups of GameObjects, rather than everyone at once? "},"comment":{"url":"https://api.github.com/repos/GoranM/bdx/issues/comments/225448076","html_url":"https://github.com/GoranM/bdx/issues/678#issuecomment-225448076","issue_url":"https://api.github.com/repos/GoranM/bdx/issues/678","id":225448076,"user":{"login":"GoranM","id":2141814,"avatar_url":"https://avatars.githubusercontent.com/u/2141814?v=3","gravatar_id":"","url":"https://api.github.com/users/GoranM","html_url":"https://github.com/GoranM","followers_url":"https://api.github.com/users/GoranM/followers","following_url":"https://api.github.com/users/GoranM/following{/other_user}","gists_url":"https://api.github.com/users/GoranM/gists{/gist_id}","starred_url":"https://api.github.com/users/GoranM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoranM/subscriptions","organizations_url":"https://api.github.com/users/GoranM/orgs","repos_url":"https://api.github.com/users/GoranM/repos","events_url":"https://api.github.com/users/GoranM/events{/privacy}","received_events_url":"https://api.github.com/users/GoranM/received_events","type":"User","site_admin":false},"created_at":"2016-06-12T17:01:29Z","updated_at":"2016-06-12T17:01:29Z","body":"> the more behavior I want to program in, the larger and more complex the GameState class would become\r\n\r\nYour message network would also become larger and more complex.\r\n\r\nOn top of that, the fact that you have a message network presents a whole new dimension of complexity, because now instead of being able to see what happens on \"level end\" in one place, one would have to hunt down all the objects that send and receive relevant messages, in order to piece together that there is a \"level end\" sequence, and then to understand what actually happens when it runs.\r\n\r\n> You, along with others, wouldn't find this feature useful, or would think it's troublesome, which is fine. However, I believe I, and others (which there is precedent for), would.\r\n\r\nA lot of people believe a lot of different things, silly and otherwise, in surprisingly large groups.\r\n\r\nIt's not about how many other people believe what you believe. It's about *why* you believe it, and whether those reasons can stand up to basic scrutiny."}}
{"actor":{"display_login":"GoranM"}}