Jump to content


  • Content Count

  • Joined

  • Last visited

  • Medals

Community Reputation

69 Excellent

1 Follower

About Sparker

  • Rank

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Sparker

    [MP][COOP] Vindicta (Alpha)

    Every playthrough is different, sometimes you spawn next to police, sometimes you have to talk to civilians to find police and then drive to them. Livonia map is not finished yet, and very few towns have the police stations unfortunately. Talk to locals to learn where the police stations are.
  2. Sparker

    [MP][COOP] Vindicta (Alpha)

    > this campaign surely seems awesome Thanks! > maybe better than the Old Man. It's wrong to compare them, the Old Man is very rich in story, while our mission is rich with dynamic things. > could u please upload the files on Google Drives or other file storage sites? Hmm but why? You can get everything from Workshop, that's how we release it ATM. At some point we will have it auto-pushed to Github release too.
  3. Sparker

    [MP][COOP] Vindicta (Alpha)

    Are you saying it doesn't show up for you? Currently it can be found in the list of MP missions, but not in the 'orange' list, but in the white list: Also players asked to be able to play it in SP, so it can be found in the main arma menu -> singleplayer -> scenarios as well: It is not listed in Steam subscribed content. Lots of confusion comes from the fact that it is technically a mod which is adding scenarios. Just like most of BI's content. I've made it to avoid uploading 5 missions to workshop when we have 5 map ports.
  4. Sparker

    [MP][COOP] Vindicta (Alpha)

    @LSValmont 1) Civilians have a simple behaviour FSM running on them. I check on client when player points a gun at them or interracts with them, then call some code remotely on the server. The FSM reads these values and adjusts civilian behaviors. Its very basic, they can either walk, run away in panic, talk or be scared. 2) No we don't (right now). 3) How AIs work, it's a very complicated system described in my 2nd post here. Maybe you could refine your question? 4) Right now it's not needed. But in the future friendly and enemy bots will be able to carry their cargo boxes around, and static guns, and ACE has a nice cargo loading system which is generic for all vehicles. So, seeing the problem ahead (I don't want to invent my own cargo loading, and most players I know play with ACE anyway), I have made ACE a requirement, as well as sorted out some issues with it ahead of time. 5) PBO is needed to add: 1. Location modules for the editor to set up maps for the mission (place outposts, bases, set up their border). 2. Inventory items (build resources, tablets and intel items). 3. Markers for the map UI (the markers you can click on the map). 4. Danger.fsm for civilians All of the above can only be added by addon. Is the need for an addon such a big issue? Right now joining servers and loading addons is easy as ever with the launcher. People load lots of addons for all sorts of features, so why not load one more for a feature rich mission? On the other hand, having an addon gives many more possibilities for mission creator. @.kjuOh I get it now! I have added SP capability now. Main problem was the BI's respawn screen which does not work in SP, and does not look nice with our mission. Now in the recent version there is a new respawn screen which works in SP as well.
  5. Sparker

    [MP][COOP] Vindicta (Alpha)

    Hi Kju! Thanks a lot! > you can't pause it It totally slipped out of my memory where I said that, I am not sure what you are talking about. Could you quote me better on that? 😄 Yeah I am generally bad with presentations, hope to make some more good screenshots and tutorial, guides, etc, at some point. Currently need to fix the most game breaking things. AI questions are OK, that's what interests me most personally as well, let's discuss that when you want, preferably here.
  6. Sparker

    [MP][COOP] Vindicta (Alpha)

    @LSValmont That's a cool idea and I wish you good luck with implementing it! If it lasts one hour, probably save system is not needed that much. Our saving system is tied with the code a lot, because of the OOP framework we use. We have everything written in it, therefore we can save the variables in a hugely automated way. Maybe you could benefit from OOP as well, I have noticed huge improvements in code quality after I switched to it.
  7. Sparker

    [MP][COOP] Vindicta (Alpha)

    @LSValmontThanks for such a precise review! Very good points, enjoyed reading a lot. Very nice to see such good reviews!
  8. For your problem, you could do it with making some functions which are wrapping the addAction, for instance: pir_fnc_addDragActionClient = { params ["_targetUnit"]; // The other unit to add action to when this client will be looking at him // Adds action to player on client's computer // Must be run on client private _id = _targetUnit addAction [...]; _targetUnit setVariable ["pir_dragActionID", _id]; }; pir_fnc_removeDragActionClient = { params ["_targetUnit"]; // Removes a previously added drag action private _id = _targetUnit getVariable ["pir_dragActionID", -1]; if (_id != -1) then { _targetUnit removeAction _id; }; }; Then you would execute these functions on client from server like this: [_target] remoteExecCall ["pir_fnc_addDragActionClient", 0, _target]; // Execute it on all clients. On every computer an action will be added to _target [_target] remoteExecCall ["pir_fnc_removeDragActionClient", 0, _target]; // Execute it on all clients. On every computer action will be removed from _target I might be wrong somewhere, it's pretty late now. However I like another kind of approach with addAction. You can add action to player (local player I mean). Then in condition you check if player is looking at something draggable. If something is draggable or not, you can dictate by setting some variable on that target object globally. This way you don't need to add actions to all units on all client's computers for instance.
  9. So you are having code on server which then adds actions on client's computer? But then you need to have server remove that action from client, right?
  10. Hi, I see you are doing this: [_unit] remoteExecCall ["removeAllActions",0]; When unit respawns, which seems to remove actions from players. I didn't look at the code long enough to understand why exactly it's needed, but it's not ideal because other missions or mods might be adding actions to the action menu. Of course considering that I have understood how your code works and if it's actually the case, if not then sorry for my mistake. And if I'm right, maybe there's a better way to achieve what you wanted to do?
  11. Sparker

    [MP][COOP] Vindicta (Alpha)

    Thanks a lot @LSValmont! Sure, questions are welcome! Regarding your previous questions: 1) Admin saves manually through in-game UI, he can save as often as he wants to. 2) Saving is GTA-like, only main things are saved: garrison/location compositions, commander AI state, gathered intel, etc. Things like exact positions of all infantry units are not saved. 3) There is no strict end objective right now. Campaign can last for a week maybe, or more. Enemies bring reinforcements into airfields, so when all airfields are under control, the rest can be finished fairly easy since there won't be more enemies.
  12. Sparker

    [MP][COOP] Vindicta (Alpha)

    Hi! You just need to download Vindicta (Alpha) from Workshop. The collection you have found was for us developers to keep the right mod set organized. Vindicta-Dev workshop item is not needed for public at all, probably I will hide it.
  13. Sparker

    [MP][COOP] Vindicta (Alpha)

    Technical description Have a good read if you are interested in AI or the technical side of the project! - OOP - Almost all code is written in my OOP own implementation for SQF, OOP-Light. I think this is the first mission of such class written entirely in OOP, correct me if I am wrong. In a few words, the OOP macros create namespaces for individual objects in missionNamespace, by concatenating object reference and variable name in form: objName_varName. It supports basic OOP features such as classes, methods, static members, inheritence. There are more advanced features, like member attributes accessible at run time, a lot of run-time assertions (wrong class names, null-objects, wrong class member names), which can be disabled to release build, public object creation. Benefit of OOP has been huge. First of all it has allowed us write code by operating with data structures, which happens naturally a lot, whatever kind of component is being written. We were able to organize the code base properly. Class inheritence was hugely benefitial for AI OOP classes (more about them later) and for UI OOP classes. Finally, member variable attributes have let me do automated (de)serialization of objects for transmission across network and for storage of saved games. Although, even with these macros, it is still SQF with all its disadvantages. Looking back, I think I should have gone with Intercept or a similar thing, because IDE support of code base matters a lot for such a big project. - AI - Although this is definitely not a general purpose AI addon, and it doesn't aim to be one of those addons, half of all the code of the scenario is actually AI code. You could have seen that most features are AI-related, AI is the main feature of the mission. - Low Levell AI: Goal-Oriented Action Planning (GOAP) - Low level AI is composed of all AI levels except for the topmost commander level. There are several logistical unit classes in the mission: Unit(soldier, vehicle, drone, ammo box), Group(several units of any kind), Garrison(several groups and ungrouped vehicles). All of these objects run one of AI classes: AIUnit, AIGroup or AIGarrison, inherited from common AI_GOAP class. I chose Goal-Oriented Action Planning AI architecture for the low level AI architecture. GOAP AI was first used in F.E.A.R. game in early 2000s. It is much better than traditional FSMs in a lot of ways. It is well described in lots of articles by Jeff Orkin, for instance: (Three States and a Plan: the AI of F.E.A.R., Jeff's page with lots of resources), you can also find F.E.A.R. AI source code in F.E.A.R. SDK. Also, since there is OOP in this project, it helped a lot to implement this architecture. Now let me describe GOAP briefly. Step 1. Goal selection The game world seen by our AI agent (can be unit, group or garrison in our case) is formally described as a world state structure (an just an array of values). On each update a current goal is chosen (each goal is an OOP class), based on the world state and any other factors. We calculate relevance of all potential goals and choose the most relevant one. The goal describes the desired world state in world state terms. Step 2. Action Planning All actions are configured to modify one or more world state properties. Actions can be chained together by the planner. The planner uses A* algorithm to choose the proper action plan to achieve the goal world state from the current world state. Generally one would like to run A* to fine a route between nodes on 2D plane for instance. Here it's similar, but we can have 5D or 10D space or whatever we like, depending on the amount of world state properties, and actions connect the 'nodes'. The final generated action plan is also sorted by precedence of actions, to make the plan make more sense in some cases. The planner can also resolve parameters for actions, for instance if a 'move' action is specified to set the 'pos' world state property to desired value, the planner can pass the desired position to this parameter, derived from desired position from the goal. Actions Actions are actually mini-FSMs which have a few states, such as active, inactive, completed, failed. Action-class objects make agents do something, like moving, getting into vehicles. Multi-level operation The multi-level AI operation is achieved in the following manner. All agents have internal and external goals. Relevance of internal goals is calculated all the time, the amount of such goals includes mainly relax behaviors(low relevance, if there is nothing else to do), self-defence, escaping severe danger (grenades and such things, although not implemented in the mission right now). External goals behave same as internal goals, except that they are generally added by some higher-level entity: Commander (or player commander) sends goals to Garrisons, Garrisons send goals to Groups while performing some action, Groups send goals to Units. Performance and optimizations SQF performance leaves extremely low amount of computation, so original GOAP had to be optimized. Most of goals match uniquely to some actions, for instance GoalUnitRepairVehicle directly matches to ActionUnitRepairVehicle. This is true for most of Unit and Group level goals/actions, therefore there is no need to run the costly A* planner for them(although still possible in the framework). For such cases the action is specified as 'predefined action' for a goal. It is also possible to bypass the A* planner and plan the actions manually, it is sufficient for most cases, for instance: (1. if in vehicle, get out of vehicle; 2. move to destination). In the end, planner usage is a fascinating concept, but I have only used it for management of convoys in Garrison AI, both because of low performance (we don't need to update garrisons as often as groups), and because of higher complexity of action plans by garrisons. It helps with making new action plans, but in the end the action plans can be also written manually with almost same amount of time spent as to tweaking costs of actions to achieve the action plan which makes sense. Results GOAP is a nice architecture for low-level AI, much better than FSM because new goals and actions can be added easily, avoiding the general clusterduck of 1000 links in FSM. This is mostly due to reevaluation of goal priority on each update, and choosing of the goal with highest priority. In FSM it typically results in links from all states to all states with higher priority. - Commander AI - Commander AI has been made by billw. The Commander AI operates entirely above garrison level, sending goals to garrisons. The core component of the Commander AI is the WorldModel object, which represents the way the game world is perceived by commander. The WorldModel contains GarrisonModels, representing the Garrisons to be commanded, and LocationModels, representing Locations it is aware of. The planning consists of several steps: 1. Synchronize the WorldModel with the real game world, by iterating all garrison and location models. 2. Make a copy of WorldModel - the Future WorldModel. 3. Project currently active actions onto the Future WorldModel. For instance, if we are currently running an action which captures Location B, then the location B is marked as captured in the future. This way we can prevent generating multiple 'capture' actions for the same location while the current one is active. 4. Generate actions. The planner generates all actions it considerers possible. For instance: if we have 10 garrisons, it can generate a 'reinforce' action from each of them to each of them. This results in hundreds of potential actions typically being generated. 5. For the number of actions we want the Commander to start: a. Calculate 'score' of all actions. Scoring depends on lots of variables: distance between source and destination, resources available, the types of the locations, known enemy activity, the Commanders active strategy, and so on. Importantly scoring is done using the Future WorldModel, so as to consider the results of all currently in progress actions. b. Take the top scoring action, activate it, and apply it to the FutureWorldModel. This allows scoring on the next iteration to take into account this new action. This is important in such cases as when two actions take resources from the same location. If the first action uses up the resources, then the second action must be re-scored to take this into account. c. If there are potential actions left, and we want to activate more, go back to a. Actions Each commander's action is actually an FSM (finite state machine), not BI's FSM, but an FSM made with our OOP. Each Commander Action consists of several ActionStateTransitions. Examples of such transitions can be: giving a 'move' order to garrison, splitting garrison in two, giving an 'attack' action to garrison, etc. Actions have an important feature - 'action variables', implemented as array with values. They are needed to let one transition provide data to another transition, for instance when we Split a garrison to give it a 'move order', the 'split garrison' transition must provide the new garrison ID to the 'move garrison' transition. This is analogous to the "blackboard" method used in other AI systems, such as behaviour trees. Performance and results Although FSMs have some limitations, the simplicity of the garrison actions makes them sufficient in this case. It can manage operation of an arbitrary amount of actions, and we have had a lot of fun observing bots planning and executing attacks on each other. The performance is also fine: it generally takes 0.5...2 minutes (despite the huge amount of potential actions) for one iteration of planning. This is acceptable for the Commander AI, as it deals only in strategic decisions that occur on timescales of minutes to hours. - Why did I write all that? - Well, as you can see that I like AI topics, and I hope someone reading this will get inspired to extend the existing set of goals and actions with new ones, or base his own AI mod on this. I am sure that the AI framework we've made is the biggest achievement of the whole project. - Scheduling - With the given execution options in SQF (PFH or spawn), it's quite challenging to manage such high amount of computation, multiple steps of which can take more than several milliseconds sometimes. I have decided to base whole mission framework (and AI too) on the SQF scheduler. Several 'threads' are spawned: Commander AI threads (one per each commander), Main thread with Garrison AI and all Garrison operations, Group AI thread, and several other auxiliary threads. AI processing is scheduled in slightly different manner, though. Typically the thread runs 'process' method of one of the assigned AI objects(the object updated longest time ago), then processes up to a certain amount of messages in the queue, then repeats it all again. Comms between threads are done as message queues. It all works good enough, but has a drawback that it is totally asynchronous with the game frame rate, meaning that at low frame rates we get horrible latensies from user input for instance. At 40+ FPS it runs good enough though. At dedicated server I also cheat a bit, and use startLoadingScreen (which increases scheduler limit from 3ms to 50ms) for a while if the queue of threads gets too big. Or alternatively I could have used this SQF command if it was implemented.
  14. [COOP] Vindicta (Alpha) I'm very excited to show to Arma community the scenario we have been working on for more than a year. This all started several years ago inspired by the amazing Antistasi scenario made by @barbolani. The main goal was to make a large scale guerrilla-themed mission with main focus on simulation of all resources controlled by enemy side. For me personally it has been a great journey through topics such as AI, multiple programming languages, software architecture concepts, Arma addon creation, collaborative code development, and many others. Allright, enough for that, let's get to mission features. Main features Dynamic game world. At game start everything is relatively peaceful and not all outposts are occupied by enemy, players can travel around without opposition. Persistence of all units at all garrisons and locations (outposts, bases, roadblocks, and so on). As player activity rises in specific area, commander AI will react by deploying quick reaction forces (QRF) and patrols, occupying outposts, constructing roadblocks, and more. Players start only with handguns and slowly build up their guerrilla movement by capturing equipment and by recruiting civilians. Intel discovery: actions planned by the enemy commander AI can be discovered by players through intel items or radio interception. Players can use this advance knowledge to intercept supply convoys, patrols, and attacks. Since all enemy logistics are calculated, guerrilla tactics are the most effective way to reduce enemy forces and to deplete enemy supplies. For instance, destroying enemy transports will force enemies to either counter-attack on foot or to send support from elsewhere, until transportation is resupplied from another outpost. At the start of a new campaign no enemy locations are known to players. They can be discovered by talking to civilians or by scouting. A multi-level AI system which controls AI behavior from commander level down to unit level. Undercover functionality, which calculates "suspiciousness" of players based on their behavior, clothes, stance and visibility in vehicles. Players can deploy as many camps, outposts, and roadblocks as they need if they have enough resources. The enemy can also capture those locations. Campaign customization: you can choose factions to fight against, and the initial number of enemies. The "unit virtualization system" coupled with AI of units: AI units despawn if they are too far away from enemies or players, but are still able to perform their actions "virtually". This also drastically reduces the chance of AI units getting stuck while attempting to reach the enemy. Links The releases can be downloaded from Workshop: https://steamcommunity.com/sharedfiles/filedetails/?id=1964186045 Our GitHub page: https://github.com/Sparker95/Vindicta Credits Authors: Sparker - OOP, core framework, AI. billw - OOP enhancements, Commander AI, tools. Sen - Tools, map design, addon development, several AI actions. Marvis - Design of graphics and UI appearence, undercover system, map design. Jeroen Not - Limited Arsenal, tools, civilian presence and civilian dialog UI. Sebastian - factions, custom unit loadouts. Special thanks: Barbolani, the author of Antistasi, whose work hugely inspired us to develop this. Stef from Antistasi community, for sharing lots of ideas for this and other projects. Used 3rd party SQF components: GPS by AmauryD - https://github.com/AmauryD/A3GPS Huge thanks to these developers, without whom SQF development would have lasted several times longer: Arma Debug Engine and Arma Script Profiler by Dedmen Miller (https://github.com/dedmen/), which has saved lots of time by providing proper SQF debug information in game. SQF-VM by X39 (https://github.com/SQFvm/vm), which has let us simulate a large portion of our code without running Arma. Big thanks to developers of these tools: KP Liberation builder - https://github.com/KillahPotatoes/KP-Liberation/tree/master/_tools gulp-armapbo by winseros - https://github.com/winseros/gulp-armapbo-plugin Arma3 AddOn Project template by ACE team - https://github.com/KillahPotatoes/KP-Liberation/tree/master/_tools SQDev by Krzmbrzl - https://github.com/Krzmbrzl/SQDev SQFLint by SkaceKamen - https://github.com/SkaceKamen/sqflint VSCode_SQF by Armitxes - https://github.com/Armitxes/VSCode_SQF