FeXoR Posted December 19, 2012 Report Share Posted December 19, 2012 (edited) As far as I know, Atlas does not rely on scripting at all - it's written in C++. As for simulation, AI and RMS, those need to be separate - if I download an RMS someone made, I don't want to have to worry that it might be hacking the simulation to give my opponent an unfair advantage, for instance.It's an open source game. How would you prevent someone from hacking? OK, games will get "out of sync". But I'm sure it's relatively easy to cheat/hack anyway.BTW: That means that you fear a scenario may include some cheats? I can't really think you would not play a scenario because of this ^^.It may include:Trigger event: playerEntersChatString("Hiho")Trigger condition: chattingPlayer == getPlayerIdByName("FeXoR")Trigger action: GivePlayerResources(getPlayerIdByName("FeXoR"), 1000000)How do you want to avoid this? Though since it's a script it will be easy to find such hacks. But I think the best way to go here is trust ^^. Edited December 19, 2012 by FeXoR Quote Link to comment Share on other sites More sharing options...
zoot Posted December 19, 2012 Report Share Posted December 19, 2012 (edited) It's an open source game. How would you prevent someone from hacking? OK, games will get "out of sync". But I'm sure it's relatively easy to cheat/hack anyway. That's a poor argument. That's like saying: since there will always be some people breaking the law, we should not do anything to prevent it. It's not a tenable position.BTW: That means that you fear a scenario may include some cheats? I can't really think you would not play a scenario because of this ^^.It may include:Trigger event: playerEntersChatString("Hiho")Trigger condition: chattingPlayer == getPlayerIdByName("FeXoR")Trigger action: GivePlayerResources(getPlayerIdByName("FeXoR"), 1000000)How do you want to avoid this?Simple: don't allow actions/effects like that unless every player agree to it. If you just throw all sorts of scripts into one scripting environment, you don't have that kind of fine-grained access control. They can even be overwriting each other's functions unintentionally - it would be a mess. Edited December 19, 2012 by zoot Quote Link to comment Share on other sites More sharing options...
FeXoR Posted December 20, 2012 Report Share Posted December 20, 2012 (edited) To make triggers powerful all those functions have to work. Here are some examples for all used functions in the cheat - but this time ones making sense:(TE: Trigger Event, TC: Trigger Condition, TA: Trigger Action):TE: playerEntersChatString("-stats"), TC: true, TA: showPlayerBoard("kills", "losses")TE: playerEntersChatString("-stats"), TC: getPlayerType(chattingPlayer) == "observer", TA: showPlayerBoard("kills", "losses", "food", "lumber", "stone", "mettal", "population", "populationCapActual")An example for a king of the hill scenario:TE: turnEnds(); TC: endingTurn % 100 == 0, TE: givePlayerResources(getVariable("kingOfTheHill"), 1))TE: unitEntersArea("hill"), TC: getPlayerType(getOwnerOf(enteringUnit)) == "activePlayer", TA: setVariable("kingOfTheHill", getOwnerOf(enteringUnit)) Edited December 20, 2012 by FeXoR Quote Link to comment Share on other sites More sharing options...
zoot Posted December 20, 2012 Report Share Posted December 20, 2012 Not all maps need powerful triggers. It should still be possible to choose to play on a plain map without all sorts of stuff going on behind the scenes. Quote Link to comment Share on other sites More sharing options...
FeXoR Posted December 20, 2012 Report Share Posted December 20, 2012 Well, if I talk of triggers I mean really powerful stuff like in Warcraft 3 (as said before).You couldn't do much with e.g. AoK/AoC Map editor triggers. Quote Link to comment Share on other sites More sharing options...
zoot Posted December 20, 2012 Report Share Posted December 20, 2012 Well, if I talk of triggers I mean really powerful stuff like in Warcraft 3 (as said before).You couldn't do much with e.g. AoK/AoC Map editor triggers.What was the difference between them? (I've never used either.) Quote Link to comment Share on other sites More sharing options...
FeXoR Posted December 20, 2012 Report Share Posted December 20, 2012 (edited) In WC3 there are e.g. the trigger event "generic unit event" just saying "a unit [action]". The action could e.g an action or "state change" like "attacks" or "gets attacked" or "dies" or "returns resources" or something. Then (for that specific trigger) some variables where set like "triggering unit" or "attacking unit" (if the units action was "attacks" both are the same but they get also set if the units action was "gets attacked"). So you could use those variables for e.g. the condition. You could set own variables and conversion functions where available like intToString(playerNumberOf(ownerOf(pickedUnit))) or something. It's hard to explain because it was mainly a programming language itself:http://en.wikipedia.org/wiki/JASSHere's an example of a function that sets the start locations for players on a random map I've written (and the triggers where never "meant" to be able to do that):NOTE: I got the German version so some words may be in German (Most parts where not translated though, Auslöser = trigger, Ereigniss = event, Bedingungen = condition, Aktionen = action(s)).NOTE: The trigger is NOT called by an event but from another triggerSince the post editor refuses to allow indentation here's a text file and a screen-shot as well as the entire map (not sure howplayable it is, it's an older version):Screen-shot: Text (not code!): Trigger Example WC3 - RMG - Place Start Locations.txtAs code: (12)FEXOR - RandomMap 2010-6-4 - Triggers.txtEntire WC3 random map: (12)FEXOR - RandomMap 2010-6-4.zipSo to say it short: You could do close to everything (The minimap refuses to get updated if you change the terrain). If a function missed you could just convert the trigger in question to a script (like above the "(12)FEXOR - RandomMap 2010-6-4 - Triggers.txt") and add the function you need. Here's the documentation of what triggers can manipulate in the engine:[still searching for it...]More information can be found:http://jass.sourceforge.net/doc/http://www.wc3jass.c...page/Main_Page/In AoK/AoC you could only add some types of variables and there where no type conversion functionality. That and the fact that no generic events like "a unit ..." could be used (and so somehow "pick" that unit and do something with it in the action) the possibilities where very limited (I not even managed to get a tower defense map to work properly). Instead only specific unit events could be used like a unit already placed in the map and named could be selected and then used for a trigger. Or any unit could activate the trigger but in the condition/action it was impossible to manipulate this unit because it was not stored. Edited December 20, 2012 by FeXoR Quote Link to comment Share on other sites More sharing options...
zoot Posted December 20, 2012 Report Share Posted December 20, 2012 (edited) I see. But none of that really implies throwing all scripts into a big hodgepodge like suggested above. We can make one trigger API into the UI and another one into the simulation, without compromising their separation on non-trigger maps. Edited December 20, 2012 by zoot Quote Link to comment Share on other sites More sharing options...
FeXoR Posted December 20, 2012 Report Share Posted December 20, 2012 Yes, It would be indeed a good Idea to warn the player if the map contains triggers (perhaps only those containing specific action types?).But in the end you can't make powerful triggers without security issues I think. Quote Link to comment Share on other sites More sharing options...
zoot Posted December 20, 2012 Report Share Posted December 20, 2012 It's not just about security, it's about integrity. What if two different scripts both define an object named 'MyObject' in the same scripting environment? You get some kind of collision, and one of the scripts break. These issues can be avoided by running separate things in separate environments. Quote Link to comment Share on other sites More sharing options...
FeXoR Posted December 20, 2012 Report Share Posted December 20, 2012 (edited) I see. But none of that really implies throwing all scripts into a big hodgepodge like suggested above. We can make one trigger API into the UI and another one into the simulation, without compromising their separation on non-trigger maps.True. But isn't it a bigger mess if we need to write the same functions several times and maybe all acting differently?E.g. wall towers placed ingame will always face the same side than one of the appending walls. In RMGEN that's not always the case (as you can see for Iberian civ bonus walls). Still both have to be compatible (They are AFAIK).It's not just about security, it's about integrity. What if two different scripts both define an object named 'MyObject' in the same scripting environment? You get some kind of collision, and one of the scripts break. These issues can be avoided by running separate things in separate environments.You say: "keep the name-space small" I say "keep the name-space unique" like e.g. calling every events TE_BlaBlub etc.Then use the triggers to make random map libraries called like RM_wall_builder.js or something and import them wherever you like.That way collisions can be avoided commonly. Even if you got a function called getEntity() in several libs you can import them save.Darn, it's not Python! Bad, bad... still you could name them unique as mentioned above.You could also bundle the libs in associative arrays/dictionaries when importing them (like Python does) and run each property of the dictionary after import. Ugly as well...(The darn editor messes around with my pasted text and newlines again! Could anyone fix that???)EDIT: I think in the end stands the decision how restrictive we whant to be. I don't like encapsulating and restriction. I'm aware of the problems arising with it from harder to debug scripts to the mentioned name-space problem as well as its harder to keep the overview over one big area of code. And I think it IS an argument that you can hack anyway in an open source game relatively easy. That means you have to grand the scripting community at least some trust. And I hope the "bad" maps/AIs/whatever will be sorted out by the community as well so it's a dynamic social process to keep things clean.As said before I think for now we will not go this ways (making AIs/RMS based on triggers) anyway so we don't need to focus on that. But Triggers should be as close to the engine as possible to be powerful and fast.In general I forgot something about triggers. They can be active or inactive at the beginning meaning they will be checked at event occurrence or not. The can also be "repeated" or "single shot" while the first will stay active after it fired and the second will turn itself off if fired. It then can be turned on/off again by other triggers actions. Edited December 20, 2012 by FeXoR Quote Link to comment Share on other sites More sharing options...
zoot Posted December 20, 2012 Report Share Posted December 20, 2012 (edited) True. But isn't it a bigger mess if we need to write the same functions several times and maybe all acting differently?We don't need to rewrite any functions, we just create a thin wrapper in each context, which then calls the original function.E.g. wall towers placed ingame will always face the same side than one of the appending walls. In RMGEN that's not always the case (as you can see for Iberian civ bonus walls). Still both have to be compatible (They are AFAIK).That sounds like an RMS feature request, more than a trigger feature request.You say: "keep the name-space small" I say "keep the name-space unique" like e.g. calling every events TE_BlaBlub etc.And what if someone else picked the same namespace? Also, namespacing does not prevent the type of error modes that may arise when two different scripts unknowingly manipulates the same globals: http://en.wikipedia....mputer_science)EDIT: I think in the end stands the decision how restrictive we whant to be. I don't like encapsulating and restriction. I'm aware of the problems arising with it from harder to debug scripts to the mentioned name-space problem as well as its harder to keep the overview over one big area of code. And I think it IS an argument that you can hack anyway in an open source game relatively easy. That means you have to grand the scripting community at least some trust. And I hope the "bad" maps/AIs/whatever will be sorted out by the community as well so it's a dynamic social process to keep things clean.It's not about trust, it's just bad design. Honestly, it's a bit like wanting to run everything as root just for the sense of power it grants Edited December 20, 2012 by zoot 1 Quote Link to comment Share on other sites More sharing options...
historic_bruno Posted December 21, 2012 Report Share Posted December 21, 2012 Here is a outline of how a trigger reader could work:https://github.com/z...117879701525d07If anyone wants to help out, fork dat repo and get on with it.I don't know that it should be implemented in C++. For comparison, technologies (including template loading) were implemented entirely in JS. The advantage of using JS is it's much more convenient to access simulation and UI state (IMO) rather than passing it back through C++. It's also much more cumbersome to work with JSON on the C++ side of things -- assuming we'd want to use JSON to define triggers/conditions/effects.For how this might work, we already parse and store the JSON map settings when reading a map, the same could be done with triggers (in a separate object I think) and then it would call some JS init function that initializes the "trigger manager" and parses the triggers object.Accessing them in Atlas will be messy either way, because AtlasUI runs in a separate thread and uses message passing to communicate with the engine, however it does have a script interface and the ability to parse JSON objects (it does this for map and player settings). Quote Link to comment Share on other sites More sharing options...
Spahbod Posted December 21, 2012 Report Share Posted December 21, 2012 I don't know that it should be implemented in C++. For comparison, technologies (including template loading) were implemented entirely in JS. The advantage of using JS is it's much more convenient to access simulation and UI state (IMO) rather than passing it back through C++. It's also much more cumbersome to work with JSON on the C++ side of things -- assuming we'd want to use JSON to define triggers/conditions/effects.For how this might work, we already parse and store the JSON map settings when reading a map, the same could be done with triggers (in a separate object I think) and then it would call some JS init function that initializes the "trigger manager" and parses the triggers object.Accessing them in Atlas will be messy either way, because AtlasUI runs in a separate thread and uses message passing to communicate with the engine, however it does have a script interface and the ability to parse JSON objects (it does this for map and player settings).I'm really not that sure about using json to define events/effects/etc. Wouldn't it be better to define the events in C++ and use them in a JS file that has access to the simulation (Something like AI)? This way we don't need to "define" effects. We can directly change the simulation state using its own functions. Quote Link to comment Share on other sites More sharing options...
zoot Posted December 21, 2012 Report Share Posted December 21, 2012 (edited) I don't know that it should be implemented in C++. For comparison, technologies (including template loading) were implemented entirely in JS. The advantage of using JS is it's much more convenient to access simulation and UI state (IMO) rather than passing it back through C++. It's also much more cumbersome to work with JSON on the C++ side of things -- assuming we'd want to use JSON to define triggers/conditions/effects.For how this might work, we already parse and store the JSON map settings when reading a map, the same could be done with triggers (in a separate object I think) and then it would call some JS init function that initializes the "trigger manager" and parses the triggers object.Accessing them in Atlas will be messy either way, because AtlasUI runs in a separate thread and uses message passing to communicate with the engine, however it does have a script interface and the ability to parse JSON objects (it does this for map and player settings).After having looked at it, I am not sure how to do it entirely or almost entirely in JS. If it was done in JS, where would it run? If it runs in the simulation, how would it know of UI events? If it runs in the GUI, how would it know about simulation events - to my knowledge the GUI does not receive messages sent out by simulation components?So unless there is some other way, I am leaning towards having a 'trigger manager' in C++ which both the UI and the simulation invokes to pass events and the like. Edited December 21, 2012 by zoot Quote Link to comment Share on other sites More sharing options...
plumo Posted December 21, 2012 Report Share Posted December 21, 2012 Triggers are crucial for me as well. I can't count the hours I spent playing all the AOE campaigns and I think I downloaded & tried the majority of campaigns and scenarios on aok.heavengames.com (as well as making some scenario's myself).I (personally!) don't care much about skirmish or AI battles, but I do enjoy the occasional Age of Kings LAN party with a couple of friends.I agree with Mythos that we don't have the manpower to create campaigns/scenarios but I think if we could provide some triggers, we'll be amazed what the community will come up with. I can't wait to get started. Quote Link to comment Share on other sites More sharing options...
zoot Posted January 1, 2013 Report Share Posted January 1, 2013 I decided to pursue a JSON-based solution anyway:https://github.com/z...ompare/triggersWhen I insert an element like this in a map's script settings, a trigger is created which shows a message if one of player 1's units is attacked.So this would just need a few more conditions and effects and it would basically work. Of course, none of it is supported in Atlas, but it would still be good enough for making, say, a tutorial, by hand. Quote Link to comment Share on other sites More sharing options...
FeXoR Posted January 12, 2013 Report Share Posted January 12, 2013 (edited) Looks a bit long-winded to use but I'll give it a try. Don't have much time right now though. Edited January 12, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
zoot Posted January 12, 2013 Report Share Posted January 12, 2013 Looks a bit long-winded to use but I'll give it a try. Don't have much time right now though."Long-winded to use"? What does that mean? Quote Link to comment Share on other sites More sharing options...
FeXoR Posted January 13, 2013 Report Share Posted January 13, 2013 (edited) "Long-winded to use"? What does that mean? Well, I mean 30 lines of code for a simple trigger (in the map data) seams a bit long to me. Not sure how to say this short ^^(cumbersome?)Most of them are brackets of cause. Edited January 13, 2013 by FeXoR Quote Link to comment Share on other sites More sharing options...
Pureon Posted January 13, 2013 Report Share Posted January 13, 2013 I decided to pursue a JSON-based solution anyway:https://github.com/z...ompare/triggersWhen I insert an element like this in a map's script settings, a trigger is created which shows a message if one of player 1's units is attacked.I must have missed this. Even though it may not be the solution we end up using, it's still good to see your efforts Quote Link to comment Share on other sites More sharing options...
zoot Posted January 13, 2013 Report Share Posted January 13, 2013 Well, I mean 30 lines of code for a simple trigger (in the map data) seams a bit long to me.As opposed to what? Quote Link to comment Share on other sites More sharing options...
FeXoR Posted January 13, 2013 Report Share Posted January 13, 2013 Something like:def event = new TriggerEvent("unitGetsAttacked");def condition = new TriggerCondition("playerToIndex(ownerOfUnit(attackedUnit)) == 1");def effect = new TriggerEffect("sendMessageToPlayer('Player 1 is under attack!', 1)");addTrigger(new Trigger(event, condition, effect));I don't know how the code in maps work.It's for sure bad to give code as a string.But in principle my idea is like that. Quote Link to comment Share on other sites More sharing options...
zoot Posted January 13, 2013 Report Share Posted January 13, 2013 (edited) It's for sure bad to give code as a string.It's not code, it's a JSON-formatted object (equivalent to a Python dict).But in principle my idea is like that.Does your idea come with an implementation? Edited January 13, 2013 by zoot Quote Link to comment Share on other sites More sharing options...
Pedro Falcão Posted January 13, 2013 Report Share Posted January 13, 2013 Wouldn't it be better to list the possible event into enums? It would be more organized and working with integers is faster than with strings, but the string can still be included... Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.