MKelm / mct

"Mass Control Tycoon" a GPL game for Windows, Mac and Linux
Other
5 stars 1 forks source link

Game Events #23

Closed ghost closed 8 years ago

ghost commented 10 years ago

Events where something good or bad happens to the company. Example: A: Oh, NO the machines are malfunctioning. What should we do?

MKelm commented 10 years ago

It's a good approach from you to combine it with decisions, that is a good reminder for me. I had the idea to add random events with yes / no decisions in my initial concept, but I missed to transfer it correctly.

Your example might be a little bit more complex, because you can e.g. do:

I changed the issue title from "Story events" to "Company events" because the story concept contains "story events" already. So company events are your new idea, instead of an extension of story events :) I want to separate this, for a better understanding about the relations/dependencies of events.

Story events are not the same like the described company event about a technical problem. Story events have a direct connection to story elements, like a planet story. The player company has no real own story elements. But story events can have effects on the market and the related companies.

I do not know, if story events can contain decisions, because they are more superior events. And I do not think that the player has the permissions to decide about that. Additionally the story must contain processes with multiple dependencies for that, depending on the amount of random story events and available decisions.

That might be too complex! I know more or less complex quest lines from RPGs which can depend on decisions in conversations which includes story elements. But that is another story concept, which do not fit exactly on the current MCT story concept. And the MCT game genre mix has more a focus on decisions the player makes for his business.

But if you have some ideas how to handle it in a better way, I am open for concept improvements ...

MKelm commented 10 years ago

jackery4444 wrote an answer to my comment and the current issue, here: https://github.com/MKelm/mct/issues/32

1st short version, for company events:

I think that you should have to do something rather that selecting an option and then getting some sort of reward, you should be presented with courses of action to take. An example event might be something like this: Employees Strike! (...) If you chose to give them a pay rise then you spend a bit of money but nothing else happens. If you chose to fire them then you'd have to hire some new staff. If you left the matter unresolved for a certain amount of time then they would all quit and take some of your money with them. I haven't explained it very well, but I hope you get the gist of what I am trying to say: that you have to actually do something rather than just choosing an option.

2nd short version, for story events:

I think that the player should be able to both trigger them and in some cases be able to have involvement in them. I think it would be a really nice idea to let the player shape the story so that each play through is different.

MKelm commented 10 years ago

Your idea for the company event consequences reminds me to my scenario idea, https://github.com/MKelm/mct/issues/31

The scenario idea contains preconditions, e.g. for story events, and you can use them in relation to objectives. But the scenario concept is less dynamically than the sandbox mode.

So your approach contains objectives too, in combination with an event. The feature for objectives can be implemented in a generic form, to use it for different types of events in sandbox and in scenarios.

To your second approach: Yes, that's good.

For both approaches: The preconditions feature from the scenario idea can be implemented generically, to use it in the sandbox mode with more open conditions, to generate semi-random or full-random events. And to use it with more fixed preconditions in scenarios.

How about that?

jackery4444 commented 10 years ago

I'm not really sure what you mean. If we define an event as a popup box with a description one or more missions then that would be able to be used for sandbox and scenario mode. I think this generic format for creating events would make their creation so much easier. We could simply have a file for each different scenario and one for the sandbox.

Example: Scenerio 1.xml (Sorry about having to use [ & ] instead of < & >.

[event id=1] [trigger]if(game.mode = sc1) // Javascript code to start the event.[/trigger] [title] A solar system of opportunity![/title] [desc] In the far reaches of the milky-way galaxy, space piles have discovered a new galaxy and the rush is on to capitalise![/desc] [mission id=1] [desc] Get a ship and a crew assembled [/desc] [/mission] [/event]

By creating chains of these events that trigger after one another scenarios would be created and possibly there could be a longer campaign?

MKelm commented 10 years ago

Yes, that can be the basic idea for a scenario definition file. I use JSON files for definitions :)

In the meanwhile I wrote an article about events and story elements. It is an abstract and might be more understandable. It does not have too much in-depth details, because it should describe the basic mechanisms of events only.

https://github.com/MKelm/mct/wiki/Events

I removed all types of restrictions from previous approaches, because the basic implementation for events does not need restrictions, that can be realized by using the correct preconditions in definition files.

MKelm commented 10 years ago

I added the feature for creating event chains by adding the precondition "event / event results" and the paragraph "results" at the end of the article.

Additionally I added something about an activation count / limit into "Activation" and a new paragraph "Queue" below it. https://github.com/MKelm/mct/wiki/Events

I detected that the activation and some other aspects need a queue ...

jackery4444 commented 10 years ago

Good work on the article. I'm not sure why you would need either activation time or activation limit though as you could put that as the trigger. To make sure that the same event is not called twice you could make the event call only once by checking the event history in the trigger, like so:

<trigger> if($.inArray(this.id, mct.game.data.events.history) == -1) </trigger>

One thing that I neglected to mention is that the function that handles events would have to be called in scenarios whereas in sandbox it could be set on a random cycle.

MKelm commented 10 years ago

Your example does not include an activation limit and activation count, it is usable for an one time event only. And I prefer to use an activation type (more or less randomly) like I mentioned in the article. Your approach to use random events and non-random events depending on the game mode adds a significant limitation to the basic mechanism of the events feature. I do not think that all sandbox events can be fully randomly, that would make some types of events impossible. But the most sandbox events should be more or less randomly, of course. And not all scenario events have to be fixed, because the game can use fixed events for scenario related contents and more or less random events for the rest of the event types (more or less available by scenario definition).

My approach was to remove restrictions / limitations in this feature and to keep them in the definition files. So we do not need to bother about the limitations at the moment and can concentrate on the basic feature. I think it is better to implement basic features with open environments first instead of implementing too much limitations / restrictions, because the game is in an early stage. Another positive effect is, that this approach offers more possibilities for game modding / balancing later.

The basic concept of this was to make an open environment for events and to call the event handler function with a fixed interval for each time unit and make the randomness by using the activation types / queue. (I have added a note in the article)

Depending on the game complexity / memory usage the game can use a mixed implementation. The queue can be a database table (see lib/base/init.js) and an array too. That makes it possible to pre-load events for the next period of time, or reload visible events on special request, like in a log.

I have made some additions in the article:

MKelm commented 10 years ago

An extended scenario definition file in issue https://github.com/MKelm/mct/issues/31 (note uses GitHub gist for syntax highlighting and correct JSON output) and some further notes ...

jackery4444 commented 10 years ago

I can see what you mean, but having so many different conditions would make the file immensely long and complex, thus defeating the objective of a simple easy to use system. By simply having a trigger, or precondition as you call it, that is checked and run by events handler would be much simpler.

"Your example does not include an activation limit and activation count"

No, but it can be calculated quite easily by simply checking an event history array. An array would also provide a lot mote information so things like not having the same event twice would be very easy to accomplish. I'll write an outline for the class to try and make it a bit clearer.


function SandboxEvent() {
    //Called after the end of every turn.
    if(mct.game.data.events.history.last.turn <= (mct.game.turn + 4)) { //has been x turns since last event?
        for(mct.game.data.sandboxEvents as evt) { //loop through all of the sandbox events
            if(eval(evt.trigger)) { //Check if the preconditions are met
                callEvent(evt); //Call the event
                return; //Stop the function
            } else {
                continue; //Continue checking if the preconditions are not met
            }
                return; //If no event is suitable stop the function
        }
}

function CheckScenarioEvent() {
    //Called after the end of every turn and after certain events are completed.
   for(mct.game.data.sceanrios.events as evt) { //cycle through all events.
        if(evt.scenario == mct.game.mode) { //is the event for the current scenario?
            if(eval(evt.trigger)) { //chek if the preconditions have been met.
                callEvent(evt) //call the event
                return; //Stop the funtion
            } else {
                continue; //Continue cycling through the events.
            }
            if(mct.game.data.scenarios.events.current.Limit > 0) { //Checks if the current event has a time limit.
                if(mct.game.data.scenarios.events.current.limit > (mct.game.turn - mct.game.data.scenarios.events.current.start) { //Checks if the time limit has passed
                    mct.game.stop(2) //Stop the game because we failed.
                } else {
                    continue; //If the time is not up, do nothing.
                }
           }
}
(An Event)

"event" {
    "id" : "0",
    "title" : "Strike",
    "desc" : "Oh no!",
    "trigger" : "if($.inArray(this.id, mct.game.data.events.history) == -1)", // Preconditions
    "success" : "mct.game.data.events.scenario.events.this.completed", // What happens upon completion (trigger new event, win scenario, etc)
    "fail" : "sendDialogue('You Lose!');" // What happens if you fail the mission
    "limit" : "5" //x turns time limit
}

The above code won't actually work, I realize that, but it gives an outline of how events work. The parser could also be expanded to allow for a a bit less coding in the trigger field.

MKelm commented 10 years ago

In the meanwhile I wrote an comment into the scenario issue and a new paragraph into the wiki article about how to reduce the size of definition files, and the events should not be part of scenario definition files, because they are independent.

You approaches by using an array are not wrong, but my approach contains an optimization to load / use required data only, and to backup all other event data into the database. That is important, because if the general event definition has large time event chains, they do not have to be in the memory. And additionally the database solution is needed in every case, for save games.

About "easy to use": If the basic functionality has more restrictions the later development / balancing process gets more complex in my opinion, and the conditions logic has to be implemented only once, then it works, it is up to you, which condition combination you use to design e.g. scenarios, and that makes up the complexity at the end.

jackery4444 commented 10 years ago

I agree my way could get increasingly complex if left as is, but with you could call functions instead and that is my personal preference; to use scripted logic. Your idea works perfectly fine also, it's just I have a dislike for json and I try to avoid it where possible.

Maybe we could merge the two ideas together. Use your idea of defining the parameters of the scenario and creating a chain of events and then my easily extendable method for creating the events themselves?

MKelm commented 10 years ago

I had an idea for that some minutes ago, because the concept for event effects should use an action dispatcher*, and all actions are logic functions.You can reduce the definition complexity by using simple events list in the first phase which can be implemented by using action definitions using this action dispatcher to call predefined functions in a special library file. If a later phase needs more definition options it can be extended. The action function approach should not limit the possibilities in event handling by reducing the complexity of definitions, maybe a larger set of possible event action library functions helps.

*More information about an action dispatcher, the action dispatcher in my favorite web application project I worked for seven years yet: http://en.wiki.papaya-cms.com/wiki/Action_Dispatcher I am using this dispatcher e.g. for this action function https://github.com/MKelm/pcms-advanced-community/blob/master/papaya-lib/modules/external/ACommunity/Connector.php#L343 The dispatcher logic is located here: https://github.com/MKelm/papaya-cms/tree/master/papaya-lib/modules/free/actions

My current approach is compatible with your example implementation more or less, but you do not have to write the logic into definition files and you can reuse event action logic in different events / event lists.

I used XML/XSLT a lot yet, but JSON looks more native for me in a JS application, because the object / values syntax is quite the same, and the benchmarks look even nicer: http://www.navioo.com/ajax/ajax_json_xml_Benchmarking.php

I have an idea to reduce JSON editing effort in future :) https://github.com/MKelm/mct/issues/34

If you want to start development on a first version of action dispatcher / event lists you can, I changed the issue assignment to you.

I changed the issue title to "Events" because the issue development is successful for event ideas.

MKelm commented 10 years ago

I forget this / Note: The window builder contains a simple, customized version of an action dispatcher already, each button definition has a (target) action property a more advanced version of this is the action to open a new layer in combination with a button elements definition

The second action needs a special target layer parameter and all actions can have a default parameter, in relation to elements definitions they get a default parameter which contains the element handle value (fp variable in the dynamic elements values).

Here is the logic to execute an action function call by using eval with a concatenated string, containing two or more parameters.

This action dispatcher logic can be abstracted to use it in more than one source part.

jackery4444 commented 10 years ago

I'll start working on an events handler and some events now.

Edit: how do I create files?

MKelm commented 10 years ago

I got your first commit, yeah!

Create a file in your file system, then:

To avoid conflicts use

before each commit

I got a conflict and had to use

to make a merge commit for my changes, I committed first without a remote update of your changes

it might be useful to use dev branch(es) in the later dev process, but the current changes should not create too much breaks

MKelm commented 10 years ago

try { mct.scnenario[x] = { used : [], data : $.parseJSON($.get('../base/data/scnearios/sc'+x+'.json').responseText) }; } catch(err) { console.log("Failed to load scenario " + x); }

The parseJSON function does not create any exception error, because the sandbox.json is missing too in the current repository, and it still works

jackery4444 commented 10 years ago

Oh, I work with java normally so it's a force of habit to use try and catch for anything to do with files. I've "committed"(?) the event management system, but can you take a look at the Json file because I'm not sure if I've done it correctly.

MKelm commented 10 years ago

Ok, it is correct, I had to click on play to get an error I forgot that the logic is inside a function, so it is correct with try catch, it is better!

MKelm commented 10 years ago

What did you do exactly, because I have only one file of you in my repository.

I cannot get the rest, because it is in your fork, you have to redo your action with all files or make a pull request, I do not know exactly how to handle it.

I can see a scenario.json in your fork, it looks ok, in relation to your status, if you want to add the functionality without extended functions for sucess first.

But all text elements should use the lang object with "ltNNNNN" language text keys. You have to extend the language file.

A language text file has some ranges, but you should use a new notation for it, I am going to change it for the rest too.

For events it should look like: "lt.9.0" - "lt.9.100" e.g. for 100 texts or you can use "lt.9.1.100" / "lt.9.2.100" / lt.9.3.100" and so on to seperate between title / descriptions / sucess messages and so on

Use the 9 it's ok, that should be enougth distance to the rest.

jackery4444 commented 10 years ago

I added sanbox.jason and EventsManager.js and I've done a pull request. I'll try and figure out how to use the language object.

MKelm commented 10 years ago

As collaborator you can push too, try this:

I am open for every workable extension push :)

jackery4444 commented 10 years ago

Edit: It worked :)

MKelm commented 10 years ago

Done https://github.com/MKelm/mct/pull/35

You should do

to get my updates, I added e.g. a catch statement for scenario.json

MKelm commented 10 years ago

Ok, sometimes you use a direct push right? https://github.com/MKelm/mct/commit/a46469bd3bd323937264dfb0df5d22da19ecaae5

Or how it works? I am confused I had to use

now, to get your commit

jackery4444 commented 10 years ago

I can edit files that already exist on github.com and that just magically works, but If I need to add new files I have to do that locally and then do some sort of merge, push, commit... thing...

MKelm commented 10 years ago

The file is a little bit broken and your try / catch is missing: https://github.com/jackery4444/mct/blob/6763391365486be8bca392359dc58964740c3796/lib/base/game.js

You have to edit the file manually and then use:

And something is broken in my game.js with your try catch block ...

Update: The scenario.json has an error ""event" : {" the : was missing

jackery4444 commented 10 years ago

Edit: Problem resolved?

MKelm commented 10 years ago

Your last 3 updates made a magical break to the game, I can only see my changes, after a pull request from origin I am getting a blank / black screen without an error :(

You should try to use pull requests instead, that makes trouble for me ...

jackery4444 commented 10 years ago

Do you get the blank screen after the title screen?

MKelm commented 10 years ago

I am getting a black screen not title screen.

MKelm commented 10 years ago

You replaced the display init.js completly! There is no display initialization anymore

MKelm commented 10 years ago

Make a pull request to get the new language text keys, and I recovered the display init.js

jackery4444 commented 10 years ago

The problem is with game.js.

The lines

mct.game.eventList = {
   used : [], data : $.parseJSON($.get('../base/data/events/sandbox.json').responseText)
};

stop it working for some reason. When I comment them out the game works perfectly.

MKelm commented 10 years ago

My version works fine. https://github.com/MKelm/mct/blob/master/lib/base/game.js#L60

MKelm commented 10 years ago

I moved the repository to an organization that offers a better rights management for collaborators, I am going to re.add you with read only rights.

jackery4444 commented 10 years ago

Ok. I really don't understand repositories though, as you have seen.

MKelm commented 10 years ago

Yeah, my initial approach was to use pull requests only, but the private repositories do not offer real rights management, so you are back in team https://github.com/mctteam?tab=members the new group I have created is "Developers" with pull rights

jackery4444 commented 10 years ago

So, let me get this right. I write an update locally, then I use "git add (file)", then I sync and do a pull request for you to accept?

MKelm commented 10 years ago
MKelm commented 10 years ago

I added something about the new language text keys... https://github.com/mctteam/mct/wiki/Modifications#language-text-keys ... but read my new comment to use a solution like in planets.json instead

jackery4444 commented 10 years ago

I have done exactly what you said, but nothing seems to happen. Why has it got to be so complicated? >.<

MKelm commented 10 years ago

You have added a pull request in your private account (fork) not in the mctteam account! here is your request https://github.com/jackery4444/mct/pull/1 but you have to add it here: https://github.com/mctteam/mct/pulls

It should be jackery4444 to mctteam not from

I changed the configuration for planets, I have added a planets.json You should use event translations in event list json files, look into the planets.json file, the solution should be easy. It is a first approach to use the display/txt/lang files for real display texts only and to define all game content related configurations / translations in lib/base/data

MKelm commented 10 years ago

Aem, I cannot pull (manually) any changes from your fork, and your last online commit in your fork is 2 hours old.

Do you have a correct upstream remote too?

Update: And closed ... https://github.com/mctteam/mct/pull/36

If you have further problems google around a little bit for git fork / pull related topics, git can have different conflict / sync / management problems when differences between sources exist, sometimes it can be confusing ....

jackery4444 commented 10 years ago

I'm sorry but I just don't think that I'll be able to help with the project at all via gitub. I simply don't understand it and I'm afraid that I will accidentally break the game by submitting the wrong thing, or using a fork, or... whatever. Best of luck with the project though.

MKelm commented 10 years ago

You can not break the game any longer, because I changed the rights, git needs some days to learn it ...

But you do not have to use GitHub for file changes!!!! You can upload your packages and post a link into an issue. But you will not receive any statistics by that.

I added some notes to use clones / remote updates or zip downloads with manual upload / issue links here https://github.com/mctteam/mct/wiki

If you have small / single file changes you can use https://gist.github.com too, to paste your code, Gist allows to review the code too, and to post comments

MKelm commented 10 years ago

I tested to make a fork and a pull request with your EasyNote project, I detected that I made a mistake in https://github.com/mctteam/mct/issues/23#issuecomment-21747431 you have to add the pull request in your own repository not in mctteam my shell commands to fetch upstream and add the change https://gist.github.com/MKelm/0829678a4682523dc1a3

Here is the pull request https://github.com/jackery4444/EasyPost/pull/1

MKelm commented 10 years ago

You made a successfull pull request but in mctteam which created the pull request for your private repository https://github.com/jackery4444/mct/pulls that is not wrong in general because you need the changes from the upstream repository, maybe it is easier for you to use the interface for that, instead of using the fetch / merge upstream commands.

Now I know how the pull request feature works, the "Add pull request" takes the changes from the relatated repository and put it into the other repository not vice versa.

MKelm commented 10 years ago

I have to learn it too :)

The event manager file did not have any linebreaks: https://github.com/mctteam/mct/commit/698436131f1a04e663d0344592dd560f29ea3149 Updated ...

I have added some notes for editor settings which can fix this problem: https://github.com/mctteam/mct/wiki/Modifications#editor-settings

jackery4444 commented 10 years ago

Perhaps what I said earlier was a bit hasty of me. I'm sorry, I was just a bit frustrated. I'll search online to try and fine some instructions on how to use github, but until such a time that I figure it out, I'll stick to just editing the files via the website.