Jump to content

igneous01

Member
  • Content Count

    924
  • Joined

  • Last visited

  • Medals

Posts posted by igneous01


  1. Glad to read so enthusiastic message, thank for using Poseidon ;)

    1/ I'm not really sure about what do you want to mean by setVariable? Maybe highlight all variables (from setVariable) when one is selected? If yes, there is a trick, select one and use one of these shortcuts:

    Something like having your cursor over a variable after a certain amount of time (like mouseOver event) displays a small listbox of all setVariable's on it.

    For example if in my code I have

    obj setVariable ["name", "lala"];
    obj setVariable ["task", _task];
    obj setVariable ["position", _pos];
    // ... etc

    then highlighting obj anywhere in the code would display a small listbox

    -variables-

    name

    task

    position

    ...

    this helps manage lots of variables that were setVariable'd so you don't have to re-check your spelling. Also gives you a nice overview of what the 'object' is currently holding

    2/ That makes sense, I was thinking it also be a third party extension (maybe being able to run it from within Poseidon?)

    I'm not sure if I will finish mine that I started a while ago, but being able to plug it into the editor would make it really convenient


  2. thats just it - it tells me preInit = 1 is an invalid value (expects object?)

    Also to make the 'test' issue a little more clearer:

    if I add a functions via cfgFunctions

    - if it does not use BIS_fnc_param to validate all arguments

    - if it does not validate arguments manually

    - rpt will log a bunch of errors from something trying to call the function like so ["", objNull] call thisFnc at missionLoad!

    - I made sure nothing is calling these functions (init, unit init box, include all clean) at init time


  3. This is excellent, I tried starting a gui editor for sqf before using .net and scintillaNET but man was that a pain to deal with (also got stuck on what parser generator to use for error parsing, boost spirit was too much for me)

    This is the layout I had always imagined - it feels like im working in visual studio all over again (yay)

    although I have some suggestions for things that I wanted for such a long time:

    - show all setVariable names on whatever obj/variable you are highlighting (similar to peaking at an objects methods in OO oriented languages) I use setVariable and getVariable a lot for making pseudo objects in sqf, being able to see everything the object holds would be soo convenient!

    - description.ext generator - some sort of menu that lets you select what classes to add (ie. CfgFunctions, CfgMusic) then maybe some input for class names and some settings and poof - generates the necessary code. A lot of the time any work in description.ext is more or less boiler plate with some value changes for whatever parameters/class names you're using. Having a way to auto generate the boring stuff while adding the important parts would be extremely convenient. Perhaps let us be able to import our own tools into Poseidon?

    Other than that, the layout is fantastic, definitely watching this like a hawk!


  4. I am compiling a collection of functions in a mission using the cfgFunctions in description.ext

    The functions are all added fine and can be called, but upon loading the mission in preview, it takes a really long time to load, and I get this in my rpt:

    if ({_x in _veh} count units _grp == count units _grp) then
    {
    _>
     Error position: <units _grp == count units _grp) then
    {
    _>
     Error units: Type String, expected Object,Group
    File C:\Users\Sapphire\Documents\Arma 3\missions\Random%20Position%20Generator.Altis\Extended Functions\boolean\Efnc_groupInVehicle.sqf, line 14

    This happens for a lot of the functions where I did not use BIS_fnc_params or validated the arguments.

    It looks like while on mission load, something is trying to call each function with some test parameters (notably string, null, nothing at all). If the test fails, than the error is logged in rpt.

    Is this intentional? Would it not make more sense to test this upon compiling of functions rather than at mission load?

    And if it is intentional, why isn't this documented? It's really frustrating to deal with.

    Also, I get this error in game on some functions:

    EF_fnc_singleParam : preInit is of invalid type - default

    here is what I am using in Description.ext

    class EF
    {
    
    	class Functional
    	{
    		class singleParam
    		{
    			preInit = 1; // 1 to call the function upon mission start, before objects are initialized. Passed arguments are ["preInit"]
    			ext = ".sqf"; // Set file type, can be ".sqf" or ".fsm" (meaning scripted FSM). Default is ".sqf".
    			file = "Extended Functions\functional\Efnc_singleParam.sqf";
    		};
    	};

    Based on what I understood from the docs on how to add functions via cfgFunctions

    Can anyone shed some light on these issues?


  5. I think a lot of this would probably be extremely easy to implement if there was a "modified" event handler that would retrieve the file, line and variable that was changed. Then you can log any changes and figure out what happened where.

    @galzohar

    A preprocessor is probably the best solution right now, but I dont like the idea of writing another parser overtop of sqf parser :(

    Maybe callExtension? Does anyone know if the arguments passed are copied, or marshalled?


  6. now I understand, for some reason when I was trying to search for 4 byte values in memory (Aka cheat engine, to see how big script stack space is) I could not find my variables, I was under the assumption that the sizes had to be larger, but I guess I will try to search 4 byte floats instead.

    And no, im not trying to hack the game for malicious intent, I was thinking of making a basic external debugger that would read a scripts stack space (since you cant watch local vars using the console in game)

    Thanks guys for pointing out my error, now I know what to look for.


  7. for the most part I will read as much as I can. If the briefing was put together really well (like strategic map showing lines of conflict, positions of nearby platoons/armor forces) and contains a concise load of information about the situation and how it is 'expected' to resolve. If someone decides to add back-up plans in case the main execution path fails that makes it even better.

    I usually spend a lot of time writing good detailed briefings, including photos of the AO and targets, map outline of forces, etc. The more realistic the situation the better.


  8. This is something up my alley, as I've spent waaaay more time than is healthy screwing around with creating pseudo-datatypes within SQF. You seem to know your stuff pretty well, so a lot of what I'm saying will probably be old news to you, but I figure a fairly thorough explanation of what I'm doing may be of value to others. I've toyed around with trying to create a proper object-oriented substitute before, but never really followed through beyond making what was effectively an associative array.

    Hokay, so to answer the first part of the question, there are only two datatypes in SQF that are passed by reference: Objects and Arrays (As far as I'm aware). Every other value, even those gotten from an object/array, is passed by value. So my solution is to make each class itself an object, then have each instance of it contain a reference, and a few other specified values. To give you an idea, here's what I whipped up:

    Ok, so there's quite a bit happening in here, but it ultimately gives the functionality you're looking for. The functions' descriptions lists their behaviors, so hopefully those are fairly self explanatory, but how exactly this works may be a bit muddled. The most noteworthy thing is how I create an object for every Class itself. Any values you setVariable to this object up in it's pseudo-init area will be effectively a static variable. Each of these classes has 1-2 very important variables: "constructor", and "extends".

    - Constructor is the function that is called when you call fnc_newObject, so any public/instance variables are initialized in there.

    - Extends on the other hand, comes into play in the functions fnc_getField, fnc_setField and fnc_callMethod, as it contains a reference to the master class's object. When looking for a field within an object, these functions first check the object itself. If the field isn't found within the instance of the object, it steps up to check to see if the Class object has that field set. If it doesn't, it'll check to see if the class itself extends any other classes, and checks them if so. Configuring this as such has the benefit that any changes to the field within the class will be reflected immediately in all instances of it. It also opens the door to multiple levels of extension, as briefly demonstrated in the example code.

    Also note that even though this uses the createVehicleLocal command, the object it creates is global to the executing client. So you need to manage your memory just a bit by deleteVehicle-ing it when you're done, or else you may eventually cause issues. Also worth noting that I'm not sure if createVehicleLocal on a "Logic" is the best practice for this, but it's what I know how to do so I've been using it. Any change is negligible to the rest of the code.

    This is my first real attempt at doing something quite like this, so there may be a few quirks to work out. I don't even 100% remember all of the important rules and characteristics of OOP, so I may need to refresh myself before looking at this more. Regardless, this should hopefully give you an idea of what you may be able to accomplish with SQF's fairly clunky objects. If there's an interest (and heck probably even if there isn't) I'll probably clean up and finish off these scripts, as I could definitely see uses where they may come in handy. Also, I know you asked for just a bit of advise on SQF's calling by reference, but I got a bit excited and made my example a bit more in depth than initially planned. :P If you have any other questions about this, I'll be glad to answer!

    very impressive attempt here! I am currently doing something very similar, except replacing gamelogics with invisible helipads to reduce workload involving groups of gamelogics. So far, I have managed to get encapsulation working - fields, methods, and constructor, still need to add a destructor that would simply call BIS garbage collect to delete the object after (too bad RAII is not possible, but I guess that means treat your instances like heap pointers).

    I will probably be spending a few weeks making sure inheritance works as it should.

    I see that you are using a function that wraps getVariable to return a field which makes accessing static data from the class quite easy, I think I will also do that (Im currently using macros) I've set up a unit test and so far class designs look like this for me:

    // Example Player class for unit testing mechanics
    
    _ctor = 
    {
    _params = _this select 1;
    //hint format ["Defined CTOR called: %1, %2", _me, _params];
    _me DOT_S("_player", _params);
    _me DOT_S("_uid", (getPlayerUID _params));
    _me DOT_S("_side", (side _params));
    _me DOT_S("_curWep", (currentWeapon _params));
    };
    
    // parameters: weapon "string"
    // changes the player's current weapon
    _changeCurWeapon = 
    {
    // first remove old current weapon
    hint "called changeCurrentWeapon from somePlayer";
    (_me DOT_G("_player")) removeWeapon (_me DOT_G("_curWep"));
    (_me DOT_G("_player")) addWeapon _args;
    _me DOT_S("_curWep", _args);
    
    // Desc: select default weapon & handle multiple muzzles
    if (count weapons (_me DOT_G("_player")) > 0) then
    {
      private['_type', '_muzzles'];
    
      _type = ((weapons (_me DOT_G("_player"))) select 0);
      // check for multiple muzzles (eg: GL)
      _muzzles = getArray(configFile >> "cfgWeapons" >> _type >> "muzzles");
    
      if (count _muzzles > 1) then
      {
    	(_me DOT_G("_player")) selectWeapon (_muzzles select 0);
      }
      else
      {
    	(_me DOT_G("_player")) selectWeapon _type;
      };
    };
    };
    
    // The actual class design itself, _class is a macro that wraps the call to DECLARE_CLASS
    _class(Player_T, 
    [
    	"_player" _comma
    	"_uid" _comma
    	"_side" _comma
    	"_curWep"
    ],
    _ctor,
    [
    	["changeCurrentWeapon" _comma _changeCurWeapon]
    ]
    );
    
    
    // Unit test
    // The real test
    BOOST_TEST_BEGIN(CLASS_REAL_TEST)
    
    somePlayer = _construct(Player_T, player);
    
    // this passed
    //_exp = format ["%1 == %2", str (somePlayer DOT_G("_player")), str player];
    //BOOST_CHECK(_exp);
    
    _exp = format ["%1 == %2", (somePlayer DOT_G("_side")), WEST];
    BOOST_CHECK(_exp);
    
    _exp = format ["!(%1)", (isNil{Player_T DOT_G("changeCurrentWeapon")})];
    BOOST_CHECK(_exp);
    
    // call changeCurrentWeapon
    _call(somePlayer,changeCurrentWeapon, "arifle_Mk20_F");		// "m16a4" old classname in A2 for testing
    
    _exp = format ["%1 == %2", str (somePlayer DOT_G("_curWep")), str "arifle_Mk20_F"];
    BOOST_CHECK(_exp); 
    
    hint format ["somePlayer: uid = %1, curWep = %2, side = %3", somePlayer DOT_G("_uid"), somePlayer DOT_G("_curWep"), somePlayer DOT_G("_side")];
    
    RELEASE(somePlayer);
    RELEASE(Player_T);
    
    BOOST_TEST_END(CLASS_REAL_TEST)
    

    It is definitely not pretty looking (notice _comma macro to allow nested , ) but at least the design aspect resembles something similar to other languages. Would you think using macros, or wrapping functions would be better for overall readability?


  9. I haven't noticed this until now - but the maximum and minimum limits of a variable is (2 ^ 128) -1 ( (3.4028236692093846346337460743177 e+38) - 1 and (-3.4028236692093846346337460743177 e+38) - 1), this seems to imply that a variable storing numbers is actually 256 bits in length (or 32 bytes) for both integers and doubles.

    Are all variables that store numbers default allocated 32 bytes? If this is the case, then having 100 variables storing numbers would take up 3200 bytes (around 3.2 kb of space). That might not seem like a lot, but doing any sort of manipulation of such huge datatypes would be extremely slow.

    Just to give perspective, in c++ integer is usually 4 bytes (32 bits) with double being 8 bytes, of course there are 64 bit variants, and 128 (that is only supported on a few architectures). I'm wondering how the team managed to make 256 bit signed integers and doubles work in the game. Has any script in sqf actually needed to use numbers this ridiculously big?

    Second question: Is there a way I can create a variable that is a reference to another variable that is stored via setVariable? Im working on a cheap 'adapter' for Object Oriented SQF, and I want to be able to have an instance of a class reference a static member from the class. Ie.

    //Player_T class (contains a static field "myStaticField") - 
    Player_T setVariable["myStaticField", 1];
    
    //create 2 player instances, player_1 and player_2  - 
    player_1 setVariable["myStaticField", (Player_T getVariable "myStaticField")]; // reference the class variable
    
    //If I change myStaticField in either player_1, player_2, or even Player_T, that change is reflected through all of them.
    //ie. player_1 setVariable["myStaticField", 2]; would look like so
    // Player_T::myStaticField = 2
    // player_1.myStaticField = 2
    // player_2.myStaticField = 2
    

    however when I tried testing this, it didn't work, each object had its own copy of the static member, and thats not what I want. I know that SQF doesn't really support references, but they are used when assigning to an array, but I'm hoping there is another way to have it reference the static field. Any ideas?


  10. you don't have to know anything about how the engine functions to know that it performs terribly, looks poor in low light and overcast conditions and uses technology that was defunct since the late 90s(stencil shadows). from there, you can use common sense to deduce the other failings of the engine even if they are not explicitly disclosed.

    the poor performance, doesn't fully utilize gpu or latest pc technology market? if so, bis has got that corned. to be honest, i wouldn't be so quick to criticize other engines, even if they aren't capable of "zomg huge google map terrain! that lags like hell and will barely be used", at least those other engines have working multicore.

    if thats how you feel, and would prefer smaller maps, then you are playing the wrong game. Find something like Crysis 3 or BF3/BF4, maybe some mods for Crysis to suit your needs.

    Also, the multicore works in RV; The problem is that multi-threading with shared/dependent resources causes threads to block. This is why one core will spike around 80% or more, while the other cores remain below 50% (they are waiting for the thread to let go of the resource). However I will agree with you that RV's multithreaded design needs to be improved. I think there are too many dependencies between threads, and this may be causing excessive blocking. But this is only speculation.


  11. That is simply not true.

    You can write extremely fast and robust code in SQF if you know what you are doing. Most people just do not know what they are doing.

    The problem is that SQF needs to be parsed, then executed as native code to the game. Interpreting and parsing code in realtime with the engine causes performance slowdowns. I would prefer working with the native source.


  12. I think the only time I would consider paid mods/addons is if the source for the engine were made available. SQF does not warrant paid addons for me; it is slow, very limited, and terrible to debug. That is not justification to pay for an addon in my opinion, because it will run on a scripting language that does not handle complex features or performance well.


  13. This engine is the best thing we have for this market right now. People claiming that simply swapping engines and releasing two years from now as 'not that difficult' are living in a dreamworld. This is what would happen if the engine was changed:

    - Read the documentation : easily a few weeks, months, whenever a problem occurs in the API

    - Rewrite all code that 'plugs in' to the engine; those api calls that are used in RV are not going to be the same, or even exist in another engine. Consider for ex:

    size_t RV::cacheRsc(Rsc* p_rsc, flags)

    that would exist in RV to cache resources (like graphics or data that is not directly on the players screen), first, they probably designed their own resource class that defines a resource.

    now imagine FrostByte's is

    DWORD FB::commitCacheAllocation(void * rsc, void * dest)

    suddenly, whatever flag options that were provided in the RV engine are not usable here. Maybe there was a flag that would allow the engine to cache a resource to multiple locations. This signature only allows 1 location, also the name is different, the parameters are different, and the return value is also different.

    This is what makes changing engines a very VERY slow process.

    - Deal with technical issues and limitations that exist in this new engine

    changing an algorithm that did some process because the new engine would either fail to process the result, a compile error, or simply not supported. It happens.

    - Systems and performance testing

    - rebuilding the game from the ground up, all over again

    There's a reason why Battlefield 2 to Battlefield 3 gap was so long, because They probably starting working on BF3 a year or so after BF2 released.

    so no, dont change engines, unless people want to wait 6+ years to see a new Arma game.


  14. I am very curious about what can and cannot be done with callExtension. I read the documentation on the wiki which describes what the signature of the dll will be and how to set it up, but what I dont know is, when would I use this over something in sqf?

    I see that the return type is limited to char *, but im assuming some form of casting/conversion might be possible.

    Is the purpose mainly for communicating with other processes? like ie. Ventrilo, database, network process ? Or is there something more that I can do with it?

    Im fairly competent in c++, so Im just curious about what limits are imposed when writing a .dll for RVExtension?


  15. Stratis has to few buildings, try nearestObjects [player, [], 30000000].

    C++11 finally adds native concurrency support, previously it had to be done using API of the target OS (WinAPI or POSIX threads).

    I just want to point this out, but the c11 concurrency library is very much a wrapper over WinAPI/POSIX/etc threads. If running on windows 7, std::thread still calls one of the low level winAPI create threads (CreateThread, _beginthread/_beginthreadex, etc). The library merely hides much of the low level stuff from the programmer. However a generic threadpool library into c++ is still under debate, mostly because the committee cant agree upon what the 'correct' way to implement thread pools is.


  16. you know what would really contribute to the games improvement? SUBMITTING TICKETS FOR ANY ISSUES YOU ENCOUNTER, WITH REPRO STEPS.

    Alpha does not mean 'early access to game', Alpha and Beta stages are all about breaking things in the game and providing feedback to the developer so they can fix it. So please, if you bought the alpha, do your part and submit these tickets to the developers to let them know something is wrong. I see countless speculation from posters with under 400 posts complaining about issues but not providing any evidence, nor bothering to submit a ticket to let the developers know.

    http://feedback.arma3.com/view_all_bug_page.php

    Please people, use this. Thats why the community alpha was released, so that feedback would be provided.


  17. There is no such thing as fool proof anti cheat. For those defending punk buster, watch some defcon talks of game hacking. They admit that Punk Buster is easy to bypass. The only reason there are so many hackers is because someone is selling their exploit to people who know nothing about hacking at all.

    Any game that allows modding is more vulnerable than a game that doesn't. Best line of defense is proper administration of servers, with anti cheat as supplements to that defense. At the end of the day there needs to be a human being responsible for these things to be the most effective.

    for those interested in the defcon talk, here it is:


  18. The low cpu utilization stems from a few problems.

    1. The operating system decides in the end how much cpu time it wants to commit per process. Generally programs are defaulted to a certain percentage use so that the cpu is able to process the other process' in the background. (like the windows process') I suggest people tinker with the priority of arma 3 to force the cpu to do more checks on it. You can do this by right clicking the process in task manager and setting the priority.

    2. Multi/Hyper Threading and core utilization is all dependant on keeping threads synchronized. This requires locking threads out and letting one in, until it finishes, then releasing the lock and letting the next thread in. This is a big problem in all software development right now. The more complicated the interactions between threads are, the more sluggish it will be because of locking.

    about the ai:

    Overly complicated AI coding. Theres a good possibility that the source code for the ai has become so complex that its very difficult to improve or optimize anything. It is so dynamic that you cant even properly QA it because the possibility that it will perform the action is not known. Trying to debug non-deterministic algorithms is really really hard to do. Thats why a lot of game developers avoid having non deterministic ai. However, despite how crude the ai in arma is, its still the best, if not the only, ai of its type that exists in gaming right now. Although I was impressed by Crysis 3 ai decision making.


  19. Does anyone know if it is possible to mod the mission editor? I was thinking of say, creating gui's that would do mundane tasks (like inventory filler, simpler task designer gui, etc) that would be used while in the editor, not in the game when previewing.

    Is it possible to add items to the menu as is?

    I think it would be very beneficial to make some tool kits that you can quickly use while designing a mission. You can do this in certain IDE's which is great.

    If its not doable, maybe someone open up a ticket for request?


  20. programming is not for you. Whether you like it or not games are built on scripts and that requires knowing the language. No game editor will be purely gui driven, just like no programming IDE is purely gui driven. Just dont bother touching the editor for a while. Maybe when you have a cooler head you might try to learn somethings from it.


  21. I am satisfied with the decision. It makes sense from the developer stand point, because distribution and building multiple versions of the same game when doing patch testing is very tedious and long process. I see no problem with their choice.

×