I'm writing a Mafia (Werewolf)-style game engine in C#. Writing out the logic of an extended mafia game, the model:
A Player (Actor) has one or more Roles, and a Role contains one or more Abilities. Abilities can be Static, Triggered, or Activated (similar to Magic the Gathering) and have an "MAction" with 0 or more targets (in which order can be important) along with other modifiers. Some occur earlier in the Night phase than others, which is represented by a Priority.
MActions are resolved by placing them in a priority queue and resolving the top one, firing its associated event (which can place more actions on the queue, mostly due to Triggered Abilities) and then actually executing a function.
The problem I see with this approach is that there's no way for an MAction to be Cancelled through its event in this mechanism, and I see no clear way to solve it. How should I implement a system so that either MActions can be cancelled or that responses with higher Priorities end up executing first/delaying the initial MAction?
Thanks in advance. I've spent quite some time thinking (and diagramming) this through, can't quite get over this hurdle.
Would it be possible to implement a cancellation stack that is checked by each MAction function and only executes if the MAction you are trying to execute is not in that stack. That way any time an action is popped it would only do something if it wasn't canceled already.
The situation as I understand it:
You have a series of things that happen with complicated rules which decide the order of what happens, and the order of what happens decides the quality/magnitude of the effect.
First things first, in order to make your life easier I'd recommend you limit your players to making all their moves before action resolution takes place. Even if this model is abandoned later it should make it easier for you to debug and resolve the actions. This is especially true if later actions can undo the effects of earlier actions like in the following example:
Dave transforms to a werewolf because he triggers the Full Moon ability. Then with werewolf powers he jumps over a wall and bites Buffy. Before Buffy dies she activates her time reverse ability and kills Dave before he jumps over the wall.
Regardless, your dilemma makes me think that you need to use a rules engine like NRules1, or implement your own. The primary goal of the rules engine will be to order/discard the stuff that happens according to your business logic.
Next you put these actions into a queue/list. The actions are applied against the targets until the business rules tell you to stop (Werewolf Dave died) or there aren't any more actions to apply. Once you stop then the results of the battle/actions are reported to the user.
There are other ways to accomplish your goals but I think this will give you a viable pathway towards your end goal.
1: I've never used this library so I don't know if it is any good.
Related
I am developing in Unity using C#, and would like to ask if it is appropriate to use IEnumerator Coroutines to determine an application's execution of user logic? And if there are any other optimal solutions to implement this.
To clarify as a series of strict sequential actions...
User triggers GUI action.
Open Form, and waits until it is filled out.
Begins checking if winning condition is satisfied in task (4.), if completed, jump to (5.)
Series of sequential tasks for user to complete, returns a result back to (3.) after a cycle is complete. Keep cycling between stages (3.) and (4.) until winning condition is satisfied.
Winning condition is met, inform user of final result. Exit co-routine.
I do hope that my logic is sound, and apologies for the vagueness of the specific task involved.
Using coroutines is completely fine for the right reasons. Although from what i read what you are making is a manager that checks the state of the game.
What i would do in that case is having a simple manager that doesn't utilize the update loop or coroutines at all, instead any gameobject which can change the state of the game tells the manager about the change. By basically turning it around the manager does not have to know a single game object and also doesn't use any performance to check all the relevant objects.
Using this architecture you could also add an event handler architecture which solves the problem of gameobjects knowing the manager, now you have a completely decoupled manager from the game :)
While what you have in mind is certainly possible, it will be hard to maintain once you will have multiple winning conditions, perhaps losing conditions, and more than one player.
If you think that this will be an issue for you, I suggest making a "game state" as a singleton, and allow different game objects to change the status within their respective Update() calls.
(I would also like to point out that creating singletons in unity is rather easy - during Awake() save the object itself as a static variable)
In my plugin I have a code to check the execution context Depth to avoid infinite loop once the plugin updates itself/entity, but there are cases that entity is being updated from other plugin or workflow with depth 2,3 or 4 and for that specific calls, from that specific plugin I want to process the call and not stop even if the Depth is bigger then 1.
Perhaps a different approach might be better? I've never needed to consider Depth in my plug-ins. I've heard of other people doing the same as you (checking the depth to avoid code from running twice or more) but I usually avoid this by making any changes to the underlying entity in the Pre Operation stage.
If, for example, I have code that changes the name of an Opportunity whenever the opportunity is updated, by putting my code in the post-operation stage of the Update my code would react to the user changing a value by sending a separate Update request back to the platform to apply the change. This new Update itself causes my plug-in to fire again - infinite loop.
If I put my logic in the Pre-Operation stage, I do it differently: the user's change fires the plugin. Before the user's change is committed to the platform, my code is invoked. This time I can look at the Target that was sent in the InputParameters to the Update message. If the name attribute does not exist in the Target (i.e. it wasn't updated) then I can append an attribute called name with the desired value to the Target and this value will get carried through to the platform. In other words, I am injecting my value into the record before it is committed, thereby avoiding the need to issue another Update request. Consequently, my changes causes no further plug-ins to fire.
Obviously I presume that your scenario is more complex but I'd be very surprised if it couldn't fit the same pattern.
I'll start by agreeing with everything that Greg said above - if possible refactor the design to avoid this situation.
If that is not possible you will need to use the IPluginExecutionContext.SharedVariables to communicate between the plug-ins.
Check for a SharedVariable at the start of your plug-in and then set/update it as appropriate. The specific design you'll use will vary based on the complexity you need to manage. I always get use a string with the message and entity ID - easy enough to serialize and deserialize. Then I always know whether I'm already executing the against a certain message for a specific record or not.
My question is how programmers create, code, and organize subforms in general. By subforms, I mean those groups of controls that make up one UI experience. I'm looking for hints to help me better organize my form codes and to speed up the process of creating such forms. I swear to God, it takes way too long.
I've identified three broad groups of subform elements:
-Subforms have commands to do something.
-Subforms have data elements to carry out those commands.
-Subforms have states used to track things that aren't data.
The approach I use is to focus on what it takes to perform the commands which will determine which data elements are needed and how they should be validated.
Also, do programmers use check lists when creating forms?
p.s. I program as a hobby.
This is incredibly fuzzy. There is however a red flag though, you seem to be talking about UI as a starting point instead of the end result. That's a classic trap in winforms, the designer is rather good and makes it way too easy to endlessly tinker with form layouts. You forever keep adding and removing controls and event handlers as your ideas about how the program is supposed to work evolve.
This is backward and indeed a huge time sink. Effective design demands that you grab a piece of paper and focus on the structure of the program instead. The starting point is the model, the M in the MVC pattern. As you flesh out how the model should behave, it becomes obvious what kind of UI elements are necessary. And what commands should be available to the user.
The V emerges. Instead of jumping into the designer, sketch out what the view should look like. On paper. Make a rough draft of an organized way to present the data. And what operations are available to the user to alter them. Which selects the type of controls and the menus and buttons you'll need. Once that congeals, you can very quickly design the form and add the C. The event handlers that tie the UI to the model.
There's a very interesting tool available from Microsoft that helps you to avoid falling into this trap. I love the idea of it, it intentionally makes the UI design step imperfect. So you don't spend all that time pushing pixels around instead of focusing on the design of your program. It draws UI designs in a paper-and-pencil fashion, there are no straight lines. Incredibly effective not just for the programmer, also a "keep the customer focused and involved" fashion. So that the customer doesn't fall in the same trap either, nagging about a control being off by one pixel. It is called SketchFlow, link is here. It is otherwise the exact same analogue of paper and pencil, but with a 'runs on my machine' flourish.
Try CAB I'm not sure you should use it, but the pattern will help you understand how to write your gui layer in a good way.
I was thinking of centralizing this functionality by having a single method that gets passed an AppState argument and it deals with changing the properties of all GUI elements based on this argument. Every time the app changes its state (ready, busy, downloading so partially busy, etc), this function is called with the appropriate state (or perhaps it's a bit field or something) and it does its magic.
If I scatter changing the state of GUI elements all over the place, then it becomes very easy to forget that when the app is in some state, this other widget over there needs to be disabled too, etc.
Any other ways to deal with this sort of thing?
Emrah,
Your idea is good. You need to limit the state structure and this is the only way to ensure reliable UI. On the other hand do not follow the "one function" idea to strictly. Rather continuously follow its direction, by creating a function and then do progressively refactoring all attributes to a single "setter" function. You need to remember about a few things on your way:
Use only one-way communication. Do not read the state from controls since this is the source of all evil. First limit the number of property reads and then the number of property writes.
You need to incorporate some caching methodology. Ensure that caching does not inject property reading into main code.
Leave dialog boxes alone, just ensure that all dialog box communication is done during opening and closing and not in between (as much as you can).
Implement wrappers on most commonly used controls to ensure strict communication framework. Do not create any global control framework.
Do not use this ideas unless your UI is really complex. In such case using regular WinForms or JavaScript events will lead you to much smaller code.
The less code the better. Do not refactor unless you loose lines.
Good luck!
Yes, this is the most time consuming part of the GUI work, to make a user friendly application. Disable this, enable that, hide this, show that. To make sure all controls has right states when inserting/updateing/deleteing/selecting/deselecting things.
I think thats where you tell a good programmer from a bad programmer. A bad programmer has an active "Save"-button when there is nothing changed to save, a good programmer enables the "save"-button only when there are things to save (just one example of many).
I like the idea of a UIControlstate-handler for this purpose.
Me.UIControlStates=UIControlstates.EditMode or something like that.
If having such object it could raise events when the state changes and there we put the code.
Sub UIControlStates_StateChanged(sender as object, e as UIControlStateArgs)
if e.Oldstate=UIControlStates.Edit and e.NewState=UIControlStates.Normal then
rem Edit was aborted, reset fields
ResetFields()
end if
select case e.NewState
case UIControlStates.Edit
Rem enalbe/disable/hide/show, whatever
Case UIControlStates.Normal
Rem enalbe/disable/hide/show, whatever
Case UIControlStates.Busy
Rem enalbe/disable/hide/show, whatever
Case Else
Rem enalbe/disable/hide/show, whatever
end select
end sub
#Stefan:
I think we are thinking along the same lines, i.e. a single piece of code that gets to modify all the widget states and everyone else has to call into it to make such changes. Except, I was picturing a direct method call while you are picturing raising/capturing events. Is there an advantage to using events vs just a simple method call?
I haven't programmed games for about 10 years (My last experience was DJGPP + Allegro), but I thought I'd check out XNA over the weekend to see how it was shaping up.
I am fairly impressed, however as I continue to piece together a game engine, I have a (probably) basic question.
How much should you rely on C#'s Delegates and Events to drive the game? As an application programmer, I use delegates and events heavily, but I don't know if there is a significant overhead to doing so.
In my game engine, I have designed a "chase cam" of sorts, that can be attached to an object and then recalculates its position relative to the object. When the object moves, there are two ways to update the chase cam.
Have an "UpdateCameras()" method in the main game loop.
Use an event handler, and have the chase cam subscribe to object.OnMoved.
I'm using the latter, because it allows me to chain events together and nicely automate large parts of the engine. Suddenly, what would be huge and complex get dropped down to a handful of 3-5 line event handlers...Its a beauty.
However, if event handlers firing every nanosecond turn out to be a major slowdown, I'll remove it and go with the loop approach.
Ideas?
If you were to think of an event as a subscriber list, in your code all you are doing is registering a subscriber. The number of instructions needed to achieve that is likely to be minimal at the CLR level.
If you want your code to be generic or dynamic, then you're need to check if something is subscribed prior to calling an event. The event/delegate mechanism of C# and .NET provides this to you at very little cost (in terms of CPU).
If you're really concerned about every clock cycle, you'd never write generic/dynamic game logic. It's a trade off between maintainable/configurable code and outright speed.
Written well, I'd favour events/delegates until I could prove it is an issue.
The only way you'll truly know if it is an issue for you is by profiling your code -- which you should do anyway for any game development!
It's important to realize that events in C# are not queued asynchronous events (like, for example the Windows message queue). They are essentially a list of function pointers. So raising an event doesn't have worse performance implications than iterating through a list of function pointers and calling each one.
At the same time, realize that because of this, events are synchronous. If your event listener is slow, you'll slow down the class raising the events.
The main question here seems to be:
"What is the overhead associated with using C# Delegates and Events?"
Events have little significant overhead in comparison to a regular function call.
The use of Delegates can create implicit and thus hidden garbage. Garbage can be a major cause performance problems especially on the XBox360.
The following code generates around 2000 bytes of garbage per second (at 60 fps) in the form of EntityVisitor objects:
private delegate void SpacialItemVisitor(ISpacialItem item);
protected override void Update(GameTime gameTime)
{
m_quadTree.Visit(ref explosionCircle, ApplyExplosionEffects);
}
private void ApplyExplosionEffects(ISpacialItem item)
{
}
As long as you avoid generating garbage, delegates are fast enough for most purposes. Because of the hidden dangers, I prefer to avoid them and use interfaces instead.
In my extra time away from real work, I've been learning XNA too.
IMHO (or not so humble if you ask my coworkers) is that the overhead of the event handles will be overwhelmed by other elements in the game such as rendering. Given the heavy use of events in normal .Net programming I would be the underlying code is well optimized.
To be honest, I think going to an UpdateCameras method might be a premature optimization. The event system probably has more uses other than the camera.
XNA encourages the use of interfaces, events and delegates to drive something written with it. Take a look at the GameComponent related classes which set this up for you.
The answer is, "As much as you feel comfortable with".
To elaborate a little bit, If for example you take and inherit from the gamecomponent class into a cameracontroller class and add it to the Game.Component collection. Then you can create your camera classes and add them to your cameracontroller.
Doing this will cause the cameracontroller to be called regularly and be able to select and activate the proper camera or multiple cameras if that is what you are going for.
Here is an example of this (All of his tutorials are excellent):
ReoCode
As an aside, you might be interested to know that Shawn Hargreaves, original developer of Allegro, is one of the main developers on the XNA team :-)
Before going into what is the impact of an event in terms of performance you must first evaluate whether or not it is needed.
Assuming you are really trying to keep a chase cam updated and its not just an example, what you are looking for is not an event (though events might do the trick just as well), if you are following an avatar likelihood is it will be moving most of the time.
One approach I found extremely effective is to use hierarchic transformations, if you implement this efficiently the camera won't be the only object to benefit from such a system, the goal would be to keep the camera within the coordinate space of the object it is tracking.
That approach is not the best one if you want to apply some elasticity to the speed and ways in which the camera tracks the object, for that, it is best to use an update call, a reference, and some basic acceleration and resistance physics.
Events are more useful for things that only happen from time to time or that affect many different aspects of the application, like a character dying, probably many different systems would like to be aware of such an event, kill statistics, the controlling AI, and so on, in such a case, keeping track of all the objects that would be have to constantly check if this has happened is far less effective than throwing an event and having all the interested objects be notified only when it happens.