#arma3_tools
1 messages Β· Page 28 of 1
so _probabilityThold[0] is probability[0] but _probabilityThold[1] is _probabilityThold[0] + probabiolity[1], _probabilityThold[2] is _probabilityThold[0] + _probabilityThold[1] + probaility[2]
etc
so the order doesnt matter
and surf is array of characters as in CfgSurfaceCharacters
I've updated tabler
https://github.com/bux/tabler/releases/tag/v0.9.0
enjoy π
it still uses forms? urgh
it does Β―_(γ)_/Β―
What's wrong with it? It just works π
no one likes Win Forms π
@obsidian sluice WinForms is just outdated AF
there is now WPF for desktop applications
Oh, I was making fomr WF Arma launcher some time ago π
but they still work
or UWP if you are idiotic (as UWP essentially was useful but nowadays without actual windows mobile it is just some underdeveloped WPF)
It had some cool listbox or something which WPF didn't have as default π
UI stuff is like all of JS
you can't follow
so can it even be outdated is the question!
@obsidian sluice well ... it is just different in WPF mostly π€· but i do agree, that some things (eg. the datagrid) are neater in forms
I'd totally use WPF if I'd rewrite tabler Β―_(γ)_/Β―
I'd use Qt and make it work on Linux as well
electron π
Just download more RAM dummy 
sideways to make it faster
@rotund rampart no ... just no to electron
if i would have time, i could link you to like a thousand links telling you why running applications in a browser container is a bad idea
Yeah it doesn't sound good π
you need links for that? XD
^ π
@nocturne basin i'm just teasing jonpas
WPF should also arive soon on linux btw
they said it won't
open-source yes
and .NET Core whatever version
but not WPF
just go to their GitHub WPF project
and check issues π
there
wait
I meant to link this https://github.com/dotnet/wpf/issues/48#issuecomment-444198305
instead I linked the drama post, oh well, enjoy
it is not really that much of a problem
as i already said "soon" in a way that ment "the moment somebody ports this to OpenGL (or vulkan)"
@vague shard the sum of probabilities should be <= 1. For example [0.5,0.5,0.1] will result in first 2 been chosen 50/50 and third one never chosen. [0.5] will result in first one chosen 50 % and default clutter chosen 50%
`probability[] = {0.98,0.03,0.02,0.015};
the way the community understood it so far:
- sum may not be >=1
- its a probability for each clutter
where above source suggests it checks a position for each probability one by one, and breaks if the random value is below probability
which also implies the values would need to be ascending, or would never be true`
- sum cannot be > 1 , sum ==1 is ok
- wrong. no particular order is required
- if sum is < 1 means default clutter will be chosen as well, default as first clutter defined in >> "Clutter"
@rotund rampart not sure if i do repeat myself (could be that i forgot to mention) but, feel free to pick up what i did and continue on working inside of it π€·
the StringtableEditor thingy i created and linked to here, is far from finished but written in WPF
and already contains the required basics
excellent research @smoky halo
it now makes perfect sense why all entries after the 1.0 threshold has been reached, are ignored
bushlurker was right all along.
Well it would take an extra line of code to normalise sum to fit it in 0..1 range
But this would remove fun out of arma config
true again, but even the solution as-is is more elegant than i thought.
https://github.com/X39/StringtableEditor everybodies time is limited @rotund rampart
but you already took the time to update, so you may want to spend those other hours to upgrade
@dawn palm yes this 100 y.o. game continues to surprise π
Honestly what microsoft tried to do with WPF was nice but kinda was unwiedly and shit
There is a reason why most games run a fuking browser to render thier UI nowdays, just easier to work with.
Getting things to work nicely in WPF is a awful sometimes
The 3.0> of swifty is written in WPF, took longer then rewrtiing the whole backend :P
also everyone should check out Swifty 3, it's a lot better.
SwiftPbo is also used in DokanPbo π
Is there any valid critic on wpf besides β¬had no idea what I was doing so took ages" @orchid shadow ?
@nocturne basin Heh trying to bait me into a worthless dicussion with you.
No thanks sir.
Go back to your lair
There is no actual discussion present here
But barking "it is shit because It took me long to do it" is no valid critics
is no valid critics take that advice for yourself
I've been ok with WPF so far, but I'm not trying to do anything too complex with it
@smoky halo thanks for the research and helping understanding it properly π
@nocturne basin π
Moving here from #arma3_scripting as this channel makes more sense.
Thinking about making a Database extension using Intercept.
These are my ideas currently:
DB_Connection = db_createConnection [ip, port, username, password, database];
//or db_createConnection "configName" not sure if seperate config file or Arma config, probably seperate
DB_Cache_InsertQuery = db_prepareQuery 'INSERT INTO positions (name, x, y, z) VALUES (?,?,?,?)';
private _insertQuery = db_copyQuery DB_Cache_InsertQuery; //Such that you can prepare queries that you often reuse, maybe even with values already bound to the query
_insertQuery db_bindValue (name player); //Binds value to next available placeholder
_insertQuery db_bindValueArray (position player); //foreach value {Binds value to next available placeholder}. So this sets x, y and z
private _asyncResult = DB_Connection db_queryAsync _insertQuery;
_asyncResult db_bindCallback [{
params ["_result", "_arguments"];
private _affectedRows = db_resultAffectedRows _result;
systemChat format ["The query has completed! %1 rows affected", _affectedRows];
private _result1 = db_resultGetColumn 0; //_result is DBValue type.
db_valueGetType _result1; //"ARRAY"
private _resultRowArray = db_valueToArray _result1; //Converts DBValue which is array of more DBValue's to a SQF array out of string/number/arrays
systemChat ("row1: " + str _resultRowArray);
}, argument1];
Thoughts and ideas? bindCallback will act like a eventhandler.
what for? What is the benefit of doing this in Intercept?
There already are extensions for database handling π€
You should limit database comunication to calling stored procedures and be done with it
No need to plug everything into strings. Async callbacks. No need to compile/parseSimpleArray the returned values
Anything a user would want to do can be made into a stored procedure like you make functions for sqf
π‘
Yeah stored procedures are good for bigger projects. But for something where you just wanna quickly add some DB stuff.
If you want stored procedures you can just do a CALL query. Then you also control the security of all this on your db server, you can disallow everything besides CALL for example
- DBCONNECTION
- DBSET
- DBCMD
Commands:
- createConnection STRING -> DBCONNECTION
- DBCONNECTION createCommand STRING -> DBCMD
- DBCMD addParameter [Name:STRING, Content:ANY] -> NIL
- execute DBCMD -> SCALAR (Affected records)
- executeQuery -> DBSET
- isReady DBSET -> BOOL
- next DBSET -> NIL
- headers DBSET -> ARRAY (strings)
- row DBSET -> ARRAY```
and again: there is reasons for instead of having a single row DBSET command to have a DBSET getValue Index:SCALAR -> ANY command
Don't know if I really need that stuff. Could just turn the whole result into a [[col,col,col], [col,col,col]] array and let the user do the rest in SQF if he wants.
Performance wise ofc not a good idea to deserialize everything to SQF if you don't need everything. But if you don't want to have all the results of your query, why did you query for them then :u
getValue over row is actually just a size concern + the advantage of being able to use DBSET getValue "column"
oh right. Didn't think about retrieving values by colum name
if you allow multi result quires, the array returned is quite deep
turning a whole result into a gigantic array is stupid for many reasons i do not have to explain i guess π
it cannot be @smoky halo
select always returns a single table
in all dbs
you can have multiresult
--> A.Column, B.Column
still single table
query;query;...
that again would be against the command idea
jup. I guess then _result would be an array of result sets
just avoid it at all
as alternative: can be done with the above commands too
but then at some point headers would change
there simply never is nested results
just multiple you receive
only nesting beyond the row->column would be if there is a array datatype in the column. like position
@nocturne basin you dont want to go to the database for every single value, you often want to get user shit out and it could contain many items as well as you might want to do that for several users at once.
@smoky halo if you fucked up your queries that is your fault
what about catering for idiots philosophy?
idiots would not do something like query "select * from users; select * from whatever"
and even if, you could provide them with, as i said, just a next method that is suddenly changing the actual result set
Man.. building armake is made hard by you having to get the openssl library.
It doesn't have to be hard at all though. Add a git submodule for wolfssl, link in cmake project, boom everything is handld automatically...
or concat the headers for them (depending on the DB used)
@nocturne basin you forgot adding some params without escaping
no i did not @scenic canopy
no need for remote execution at any point in any software
query format ["select * from users; select * from whatever where id = %1", _number]
then you don't need stored procedures or prepared statements!!
what exactly you wanted to show me with that?
Took me just an hour to get the project set up. Mysql c++ connector with wolfssl and intercept. All in a cmake project.
And it just successfully built into a single statically linked dll. (after adding a include that's missing in the mysql connector library, don't ask me why)
If only the build experience would always be that nice...
Now I guess I only have to find out if t works π
if you have, i would gladly join your efforts
@glossy inlet you can add the release download link to cmake and avoid the git submodule
@scenic canopy i also don't understand the point you're trying to make with that sql
Are you saying that you should be able to format like above???
if I add a troll face, would it be better? π
c++ connector looks like Java port, π€’
Much better! :D
@smoky halo the JDBC is actually some extremly good design for generic DB access
You could use something like that format for a more "convenient" bindValue thing. But I don't really like that.
I mean something like queryWithBoundValues = db_formatQuery [SourceQuery, value1, value2, value3] ugh
no
just no
stick with what i gave ya
just ... instead of ? use ?name
and then people can do DBCMD addParameter [name, value]
or with just ? only DBCMD addParameter value
Call a function once for each parameter? Why?
because named parameters are a thing @karmic niche
and thats how you do it in frameworks
In Frameworks, you can use several named parameters at once
uhm ... yup? that is why i propose for a addParameter
Calling the function once for each parameter would be tedious
Don't really see the need for named parameters. Also hard to implement with the database connector library.
setParameters, if anything imo
<14:13:36 SimplifySoft.Pecuniarius.Server.Database.PecuniariusContext> (#42446020)
<14:13:36 SimplifySoft.Pecuniarius.Server.Database.PecuniariusContext> (#42446020) -- p_0: '1/10/2019 2:13:36 PM' (Type = DateTime, IsNullable = false)
<14:13:36 SimplifySoft.Pecuniarius.Server.Database.PecuniariusContext> (#42446020) -- p_1: '{
"SimplifySoft.Pecuniarius.Data.Net.AccountingRepository.Receipt": {
"TimeStampCreated": "2019-01-10T14:13:36.4133742+01:00",
"TimeStampLastChanged": "2019-01-10T14:13:36.4133742+01:00",
"Entries": []
}
}' (Type = Object, IsNullable = false)```
inb4
that is how postgres receives values
mysql won't be any different
that is why the design in many top level interfaces is addParameter not addParameters
Disclaimer: I'm spoiled by ORMs and can't stand regular SQL
why not both?
same deal there @karmic niche π
just stop using the implementation APIs and rather use the top-level interfaces
i dont know shit about sql OR ORMS (srry stack), but using qgis features or so you wanna add attributes to shapefiles? You can either add a single, or just use addAttributes in a list straight away
both would require array checking
connection whatevercommand [["key", "value"]]
// or
connection whatevercommand ["value1", "value2"]```
Okey take it back. Named parameters are not hard.
How about
db_bindNamedValue ["name", value]
db_bindNamedValueArray [["name", value], ["name", value]]
ππ»
do not forget to check each entry
personally, i would still prefer the addParameter syntax simply because it will look cleaner in code
Edited my above post. If there is an array variant there ofc is one without array too. That's essentially the same as yours
can live with that π€·
though ... maybe combining both would be better π€
ohh ... and i hate your naming π
I don't want to conflict with anything that might exist elsewhere. So db_ prefix it is
was not talking about the prefix
Well in normal mysql connector it's called bind, so I use bind too.
Also it's called a database query, so I use query too instead of command
No need to make up new naming if naming already exists
mysql is braindead
better to use actual database interface names then the ones mysql, postgres or whatever one wants to use
Oh nice. {params ["_row"]; ...} forEach _resultSet So many ideas π
nah ... do not do that @glossy inlet
bad idea
or only in spawn
so you can suspend the script until the next result is ready
Good idea too. But so far I've only written unscheduled forEach loops in Intercept. Scheduled means I need special callstack stuff
yup ... and if you want to implement something like that for something that requires waiting seconds in worst case, you want to avoid at all cost that some idiot is comming along (or just by accident) and uses it inside of a forEach loop
if they want to make that mistake ... one can use a while loop with waituntil or whatever
Also nice for async results. Implement a sleep like thing that just waits till result is done in scheduled.
VS a waitUntil loop calling the extension every half second like it's done now with extdb
I could hide it inside the forEach loop. Would be easier to use.
π€·
but requires you to actually halt the VM until it is available
the way i imagined it was no actual waiting
but rather all just work on existing data
this way, you have less trouble and can just get it done
doing the fancy things later
I prefer doing the waiting on engine level. Rather than the user having a loop that waits for him
doing the fancy things later
do what you have to π i might be one of the first users when it is done
ye ... and i now left the DayZ Modders Discord
still gonna make that enscript VM at some point probably though
(as long as somebody can provide me with what i need for that π)
Why exactly did you leave?
Was not granted the access to the internal channels
Also... They are not really helpful there for what I planned on doing
Have you submitted something through the google form?
You could easily get access to the tools role, IMO
"check leaked Code" was the answer to the question wether somebody could hint me at interna of enscript
Yes, did so
That's probably because "we actually don't know how the language works, yet" isn't something they felt like saying π
Especially that that discussion was in september
There are very few people in there that operate on the level that you need to get that info
btw. you reminded me that I was planning to apply myself, there
So yeah, what Dedmen said. Also, I think they didn't fully understand the extent of the work that you wanted to do.
And checking the leaked code is um... problematic. On one hand, it will give you the most accurate answer. On the other hand, it's not exactly ( π ) legal, and is certainly out of date at this moment
Applied the day that Annoncement Was made (maybe 10 Minutes later)
Did not received anything yet
I explained everything multiple times... Answers always have been the same "no need for that" "check leaked source" etc.
And I am Well aware that there are only a few people capable of telling me what I need to know
not entirely sure how much of a good idea is it to have an important discord like that run to by community members either
inb4 political drama surrounding mods ππ»
DayZ discord exists too. And it also has modding channels..
They probably are not there because illegal stuff that violates EULA get's banned on sight there..
In their own Discord in their private channels they can hack and violate EULA all they want
That was easy..
DB_Connection = db_createConnection [ip, port, username, password, database];
_insertQuery = db_prepareQuery 'INSERT INTO positions (name, x, y, z) VALUES (?,?,?,?)';
_insertQuery db_bindValue (name player); //Binds value to next available placeholder
_insertQuery db_bindValueArray (position player); //foreach value {Binds value to next available placeholder}. So this sets x, y and z
_result = DB_Connection db_query _insertQuery;
systemChat (str db_resultToArray _result);
already all implemented. Should be enough to test. I might test when I get home in half an hour. Just missed my bus just to get this released first
I pushed a test build https://github.com/dedmen/Intercept_database/releases It is called sqf-assembly because I don't have a pbo packer to hand right now
No async stuff yet, that'll require quite a bit more work
thanks for inspiring me to get started with intercept plugins again π
exactly 3 hours of work, from 0 to a working Intercept based database extension with CMake build :u
That almost went too swiftly
Do you use dynamic linking?
no
I would need to put other libraries into arma directory.... Or fix the Intercept workaround that I should've implemented months ago.
So you static linked c++ connector?
yeah
Ok
Well. I just set BUILD_STATIC to true in cmake... π
I forgot to register db_prepareQuery π€¦
ah ffs. There is a new very nice database interface that's not JDBC, but that only works with mysqlx which is some oracle specific crap :u
Switching to the "legacy" JDBC interface requires me adding boost -.- but atleast I get easier async
There is nothing wrong with boost
size
compiletime
size
size
compiletime
think i got everything wrong with it π€
You don't need the entirety of boost
Compile times aren't ideal, but they are a bucket load of headers
Takes like 10 minutes to clone the git submodule. I'd have to make my own git repo for the exact subset that I need
Which repo?
Will do that someday. boost-cmake
last time i tried to use anything from boost, the "not all needed" thing needed more and more subsets
boost-cmake repo..?
https://github.com/boost-cmake/boost this. Hoping it works out correctly with cmake
Last time you mentioned that it wasn't true @nocturne basin
What exactly is that repo for?
we already had the entire conversation
and asio required more then "just" that to get the examples working or ... itself
I just skip any answer on stack overflow mentioning boost
Why?
Because I like shit lean
What's not lean after your compilation has eaten it?
Or do you prefer to use the newer standards, which are just ported boost modules π
boost is just a gigantic pile of neat code
but utterly useless unless you have a copy already locally ready of it in entirety
Did you read the answers?
especially if you just need a simple subset
i did post it for the actual reasons in the top post
C++ is already full of goodies will take ages to explore stuff they added just with c++17 donβt want to learn a 3rd party lib on top
You can blame the state of C++ for that, unfortunately
it is a sorta meta post anyways
Most of the features you're going to learn in C++XX are simply from boost
As will continue
main difference: i do not need to download boost in its entirety to use those features afterwards
which is the whole point
Yeah donβt mind that as long as it is part of std
and the reason dedmen said "at some point i may create a subset repo of boost cmake"
No instead, you faff about with gcc for ages π ?
You don't need all of boost, especially if you're using a build gen like CMake
What do you mean?
you will still need to download the whole boost suite ... regardless of what you do ...
in the end, you include a small subset, yes
No, you do not
but to get that subset working, you need to download all bloody whooping crap
Depends entirely on the deps
No I mean what is faff about?
hmm?
No instead, you faff about with gcc for ages π ?
I seem to remember X39 having a fist fight with compiling a later version of gcc
Oh I see it was for X39
mostly because it was the same problem as with asio
after trying to compile the first module, another baffled me
going on and on
and in the end ... a simple old gcc installation caused troubles
which to find took the longest frking time -.-
to realize, to uninstall fully etc.
because hur dur long story and many dependencies
Might also be worth noting, keeping an installation of boost around, means you don't have to mess around. Don't have to download it every time you use it
If you're using linux, then the world is your oyster, and a stress free one
If you're using VS, take a look at vcpkg, worked well for me last time
Might also be worth noting, keeping an installation of boost around, means you don't have to mess around.
which defeats its usage pretty much entirely for github
hell even those fancy projects utilizing test suites etc. are stupid for github simply because they contain a gigantic set of tests in their main repo which, most of the time, is 4x the size of the sources
I'm not sure what you mean, boost is a dependency
You don't need to run the test suites either?
Upload it all if it floats your boat
tried to let cmake auto-install boost.. Ran out of disk space π
π
@glossy inlet why not use some key value based database layout. Fits Arma way better actually. I rewrote the Epoch database extension which originally used redis. Made it so that it could also use MySQL
Planned on integrating SQLite and maybe another pure key value db option
I already have key-value hashmaps in intercept_cba
key-value is not really efficient though is it?
In case of redis it actually is. Also when implemented well, MySQL can keep up quite well too
- you only need a single table with 2 fields
Maybe 3 if you want TTL or something like that
I don't know what other people need. But I feel like key-value is a little to cumbersome if you want anything relational
People can just implement key-value stuff with my extension if they want to Β―_(γ)_/Β―
Actually I don't know any use case in Arma scripts which actually needs a select query that is way different from 'where x = id'
performance optimization, only spawn vehicles if player get's in range
life server messaging system. Find all messags from player1 to me
Can be done with the key name actually ^^
As I said. If people want they can implement key-value with my extension
I don't know why I should limit it so that it becomes unusable for anyone who wants something else
Also key -value would need to be strings, Would be inefficient if you'd store numbers like object positions
True that
Just wanted mention it
How about actual query commands
Like dbUpdate, dbInsert
BTW, is somebody interested in a general purpose Arma Dockerimage?
If so, I need someone to test it π
Whatβs that?
Don't see what use DBInsert would be. What would the difference be to a normal query?
Ease of use for binding
But.. What is the difference. I don't see any difference vs normal query?
normal queries are already easy to bind. Don't see what I would do differently with a seperate insert command
Except maybe that I return just lastInsertID instead of a result type. but that's just one line of code saved.
@smoky halo Just Google for docker, basically a kind of virtualization
It's about creating an isolated environment for the Gameserver
Well.. I just think that people would create sqf function wrappers for all the queries
yeah.. But... Still. What difference would a seperate insert command make?
In what way would it be any different than a normal query
Saving some lines of code.. nothing other than that
Which line? I don't see any that would be saved
you still have to write the insert query, just same as with the db_query command
That's both.. 1 line of code
_query = prepareQuery "INSERT INTO..."
db_executeQuery _query
vs
_query = prepareQuery "INSERT INTO..."
db_insert _query
Where is the difference?
I think of something like this: connection dbInsert [tablename, [values]]
ah. Well.
_query = prepareQuery "INSERT INTO tablename .."
_query bindValueArray _values;
db_executeQuery _query
vs
dbInsert [tablename, [values]]
? Meh.
Scripters usually want as much abstraction as possible
Well, "sqf scripters" at least π
the level of abstraction you expect is impossible to archive without numerous checks
a dbInsert command in the way as you propose it, would not be possible unless one checks how many columns are available
And then the user also always has to provide all columns. leaving something null is not possible.. Okey I guess you can insert nil's.
you actually have to allow nil for null
Nope. The columns just need default values
And even if you write sqf queries, you would need to do that to make it fail save
But that hurts readability alot. With inesrt query you have the column names right there and know what's what.
Your method would break when someone adds a column. And the scripter wouldn't see it. He also doesn't see if he mixes up two values
I see your point there tho
assuming the following:
User
-------------
Id: Scalar (default: DBGenerated on Insert)
Created: String (default: DBGenerated on Insert)
Username: String (default: unset)
Money: Scalar (default: 200)
how would your "idea" look like?
what would make things simpler
Optionally you could also have an array for column names and one for the matching values
_query = db_prepareQuery "INSERT INTO User (Username, Money) (?,?)"
_query db_bindValueArray [name player, 0];
_connection db_execute _query;
vs
_connection db_insert ["User", [nil,nil, name player, 0]]
Oh wait.. Now Id and Created are nil. Oof.
I have the feeling it's more overcomplicating things rather than making it easier.
Yeah the users don't have to write SQL anymore with your method. But they still have to know how to set up the database, so they probably also know how SQL works
Mod contributers who can't write SQL could still use DB commands
- you can integrate other DB types (non SQL) more easily
I don't dislike the way you currently use, just throwing in some ideas
_connection db_insert ["User", [["Username", name player], ["Money", 0]]]
You can also do it the "bind stuff" way, if you want to have the actual arguments be in a separate line of code
having db_select, db_insert, db_update and db_delete would make much sense IMO
Sure, you can do everything with a db_query, but in the same way, you can do everything with PUSH xxx, CALL yyy commands in asm, instead of using higher-level languages and calling functions "normally" π
even though i do like that "syntax" i am still against it
simply because it is not really required at all
also, what should db_insert return?
- all of those are just saving literally the "db_execute*" commands
I can also see that being potentially a bit more bulletproof - prevents typos in "select", "insert" etc...
how would you want a db_select to look like? you cannot make this "bulletproof"
only thing this does is saving a single command + a few words
also, what should db_insert return?
does it need to actually return anything other than success/failure?
as the whole show is techincally async
saving a single command + a few words
And this is a bad thing? This is literally why people write wrappers. Why not do that for them, in that case?
some people might want last insert id
Yeah, whatever, my point was that there is no point in making the library harder to use than it can potentially be, especially that it's not like anyone will spend hours implementing that feature.
because connection db_select ["table", ["field"]] is literally SELECT field FROM table
I'd still use the former. I don't have time to spend my time debugging my typos
you still will spend that time
can still typo the table name or column names ^^
No, guys... seriously?
Will implement them. But don't see the usefulness really
A hundred of wrappers simplifying writing code for programmers by one single line of code each time is a hundred of lines saved in total (just please, don't take that literally...)
Less code written outside a library = less potential bugs, typos, mistakes. Yes, you can mistype the field name. Sure! But if I had the choice, I'd use the function that lets me make less mistakes, and does that for free...
we talk about queries
unless you can abstract away literally everything, there is no sense in abstracting away those few commands
with the exception being, if there would be multiple end points
that would use different languages
Let's just say that I disagree and end the discussion here π
Also, how about performance in this case.
Only one invocation instead of multiple
Sure the array creation has a cost, but its quite low in comparison I guess
better perf in SQF land yeah. Same work in extension. But I can move the work to seperate thread
nice
sooo ... lets start with the endless task of creating a proper life mission now i guess
Nice joke. Almost believed you
you better do
because i am 100% serious
fuck sake ... if UI stuff wasn't that ugly in arma ... even my XMedSys rewrite would have been done already
and in regards of the life mission: i got told "do it better" by those idiots multiple times
and no, i am not really a friend of people telling me i am too stupid to do something (which should not be a surprise to ya π)
though ... arma.studio rewrite still needs to be done
π€
sooo much work
and enscript VM project not even started
ohhh boy
2019 will be a bloody busy project if i do not find some girl to give me an excuse for all of that
just to note: i actually started already back in 2017 https://imgur.com/KXNCzjE
but never got around doing my own db stuff as i hate extdb
Same. extdb is also quite cumbersome to set up with weird memory allocator stuff. I hope this thing will be same kind of plug-n-play on linux too
My Arma game today just dissolved.. So I guess I have time to implement async now... ugh.. I don't wanna...
Back then I just accepted a the name of the function that would be called once the operation was done
Actual code as callback is kinda "meh" I guess
Well.. You can just plug a function name in there too
CODE type variable, or inline CODE doesn't make a difference
I actually meant a string, I fetched the code from mission namespace
Otherwise you will have to pull the code all along to the end
Don't see why anyone would wanna do that
I just store a variable. It's not like that's any effort
If it doesn't have a large performance impact, then that's better yeah π
just moving around a pointer and incrementing a refcounter Β―_(γ)_/Β―
storing a string would be the exact same actually
what is the 'async' thing you are going to do?
Callback once result is ready.
Or scheduled script suspension until result is ready. Like a waitUntil kinda
Database-related?
yes...
We were talking about the Database Extension the whole day.
So yep. It's database related ^^
Here is a example with a callback: https://discordapp.com/channels/105462288051380224/105464579600977920/532888283311767563
I see now, because with intercept you can call your SQF callback from the .dll
but you could pump callbacks from your .dll on the sqf side π€· I guess
what do you mean?
hmm... on each frame, ask the db extention for finished queries, then call the appropriate callback... didn't think much of it tbh
yep that's what people have to do currently with extdb for example.
But I don't want you to waste cpu time by checking every frame
Performance with intercept wouldn't be as bad as extdb if you'd actually do the checking. But still, 0 is better than something
so, am I right that with Intercept I can make such a thing:
make an optional addon which would replace some of my SQF functions with their intercept-based implementations, keeping the interface(parameters and their types) of the functions the same?
yeah. Intercept_CBA has a utility function where you can replace a SQF function (that can be call'ed) directly with your c++ function
damn it's nice... i was going to use some A* but it's quite slow with SQF. thanks.
Async was easier than I expected. The unscheduled one..
Okey.. What next... db_copyQuery done. db_waitForResult done
Okey... Have to rudder back, won't implement the proposed insert command. That's just inefficient, have to first call to the DB to check which columns are available then have to make a new query with that info.. Not worth the time investment right now.. I won't say no to a PR tho.
Rather invest the time into scheduled stuff.
db_makeMeACupOfTea
An HTCPCP-compliant database?
Ah I love Generic Error in Expression without any info about what the error is :u
Wow..
Let's push the result onto the stack which is a ref counted smart pointer.
"Mh.. I don't know what this is.. But I can implicitly convert it to bool! Let's do that and push the bool to the stack!" π€¦
But atleast I now learned how to make async scheduled callstack thingies.
I could now make my script debugger work in scheduled π€
[] spawn {
_query = db_prepareQuery 'SELECT intel_missionen.`name` FROM intel_missionen WHERE intel_missionen.id > ?';
_query db_bindValue 400;
_start = diag_tickTime;
_result = DB_Connection db_query _query; //suspends script until result is ready
systemChat ["got result!", diag_tickTime - _start];
DB_RES = [db_resultToArray _result];
};
This makes it seem so much more professional. And it's so logical too
And it's a good step for Intercept. Before you could only have commands that freeze the game until they return, even if scheduled.
Now there is a example implementation for commands that just suspend in scheduled.
Build: https://github.com/intercept/intercept-database/releases/tag/0.3
nifty π
ported half my AAR thingy to intercept now finally
just need to add fire events etc too
mmmm, I was going to write my own db connection, but if ur doing it already lewl
I was worried extdb3 would bog down too much if I increase polling, so this will be nice
600 games, 27GB of data so far :)
ill try swapping our mission over to it and see how it goes this weekend on test machine
intercept-db should really load connection details from a config file
I like to have a param toggle between connections to swap between dev db and prod db
I also do like the seperate txt config for all the sql statements, loads them from it. don't like having to reload mission/etc just to edit
intercept-db should really load connection details from a config file Yeah that is one of my tasks for today. Don't really know how to properly do it.
I'd really like to load all that stuff from Arma config. But that would require you to pack a mod. or loadFile would be nice, but would require filePatching.
Probably gonna end up using a yaml config in @InterceptDB folder.
I like to have a param toggle between connections to swap between dev db and prod db Swap in the config file? or ingame in script?
It would be db_createConnection "configName"
Also for queries it would then be db_prepareQueryFromConfig "configName".
And I'll make it so that all existing/stored prepared config queries will be refreshed when you do a db_updateConfig. So that you don't need to re-prepare.
Question: rename db_stuff to dbStuff ? I liked the better seperation, but people might prefer proper camel.
Can we also pass some extra args for the callback?
I.e. you insert a vehicle to the database and want to store the insertid on that vehicle in the callback
yeah.
bindCallback [code, arguments]
_this is [_result, _args]
No
Keep the db_ prefix
I consider it the same as with diag
What about cam/ctrl/config/lnb/curator/map/task/tv/waypoint commands tho. That's a valid point
there is a main difference: those are everyday commands
and diag commands are a very specific subset
just like the db commands are
new stuff
dbCreateConnection "configname"
dbPrepareQueryConfig "configname"
dbPrepareQueryConfig ["configname", [binding1, binding2, ...]]
dbPrepareQuery ["INSERT ....", [binding1, binding2, ...]]
dbReloadConfig
And I made the move to camelCase because more voices for it than against.
if you reload config, all config queries update themselves automatically, no need to call dbPrepareQueryConfig again. But the db connection doesn't change itself if you change the ip in config π
Example with a config
accounts:
maindb: #production db, don't break things here!
ip: 127.0.0.1
username: root
password: lulz
database: production
port: 3306 #optional
testdb: #testserver
ip: 127.0.0.2
username: root
password: lulz
database: production
port: 3306 #optional
statements:
insertStuff: INSERT INTO table (a,b,c) VALUES (?,?,?)
deleteStuff: DELETE FROM table WHERE a=?
_connection = dbCreateConnection "testdb";
_query = dbPrepareQueryConfig ["deleteStuff", [15]];
_connection dbExecuteAsync _query;
I think dbExecute is better than dbQuery, more readable right?
there actually is a difference between execute and query for db
which is?
SQL has two parts
one is the query language (select etc)
second is the insert update etc. stuff
need to look up the exact names for those though ...
difference is: execute is usually done for insert, update and delete + all other operations that do not return a set of data
Execute query is more readable than query query though
query is used for sets of data
And so.. Execute is actually correct in most cases
I won't add a query command that does the same as execute just to have the correct names π
dbExecute and dbQuery would be the correct thing π€·
one returning just the affected rows, the other the actual set
@nocturne basin DQL and DML ?
exactly
and Dedmens argument against query query has its roots in wrong naming in first place
dbPrepareQuery should be named dbPrepareCommand or dbPrepareStatement
then DBSET dbQuery ... and SCALAR dbExecute ... make more sense
yeah I name some things statement internally to. As in the config
Let's look at performance
dbCreateConnection "maindb"; 0.0013ms (connection is only established at first query)
dbPrepareQueryConfig ["getMissionName", [400]]; 0.0021ms
dbPrepareQueryConfig "getMissionName"; 0.0008ms
dbPrepareQuery "SELECT intel_missionen.name FROM intel_missionen WHERE intel_missionen.id > ?"; 0.0008ms (to be expected)
dbPrepareQuery ["SELECT intel_missionen.name FROM intel_missionen WHERE intel_missionen.id > ?", [400]]; 0.0021ms (to be expected, It's does the same stuff as the config variants)
DB_connection dbExecute DB_query 59.76ms well my ping to the server is 20ms..
DB_connection dbExecuteAsync DB_query; 0.0349ms
I like that speed for async.. I wonder how it compares to extdb.
For the sync, not even close
For the async (using very poor SQF boilerplate to poll) - close
@glossy inlet why not instal MySQL locally?
Because I don't need it ^^
I just need to test if it works. And I already have a big database with loads of test data to test on
Besides the actual statement execution the perf on sync and async should be about the same.
async still feels a little slow there is probably something I can optimize. Probably the worker thread doing the work interfering with the inserts to the queue as it has to lock the queue when taking out a task.
won't implement the proposed insert command. That's just inefficient, have to first call to the DB to check which columns are available then have to make a new query with that info.. Not worth the time investment right now..
Uhh... I don't get it. Why did you have to check which columns are available? Why not just pass what the dev passed to the function?
Meaning: if you're passed positional arguments, just pass them as positional arguments without using column names.
If you're passed named arguments, just use those column names in your INSERT
Are you using DB much?
Yes. Care to explain? INSERT INTO table_name VALUES (value1, value2, value3, ...); does work so I don't see the reason for being passive-agressive.
does work Ah... Didn't know and didn't have time to google ^^
Although if I wanted to play by your rules, I should have answered Yes. @smoky halo
INSERT INTO table_name VALUES (value1, value2, value3, ...); cant find this syntax, got a link?
Although, as I have stated earlier, I'm almost always using ORM, tbh
And yes, of course, good practice would be to name the columns while inserting, hence the suggestion to use named arguments (["column", value]), which doesn't require you to do any check either
Nope still can't find it https://dev.mysql.com/doc/refman/8.0/en/insert.html
But it works
That's because square brackets in that link you posted are optional
Meaning INSERT square_brackets_are_optional VALUES (5); is valid MySQL syntax
(didn't even know that INTO was also optional; learned that today by looking at your link)
Yes you can drop it, works without INTO
even on 5.7
VALUES or VALUE both work for multiple insert
INSERT INTO table_name VALUES (value1, value2, value3, ...); cant find this syntax, got a link?
Seems you're not using DB much π
technically this is using the mariadb connector, so we should be using its documentation for reference :)
DB_connection dbExecuteAsync DB_query; 0.0036ms
That's more like it!
Btw don't run 10k async queries that actually do something when you profile.. Your database server will hate you
Build is up https://github.com/intercept/intercept-database/releases/tag/0.4
Connection pool? π
Just one worker thread for now. Per account, with it's own connection in the worker
thanks for the yaml example btw π
Anyone ever created a battle eye whitelisting tool pulling data from a MySQL database? Thinking of using BattleNET
BattlEye Whitelisting? You mean whitelisted?
I mean using battle eye to kick players by checking their guid against a MySQL database. I didnβt word that in the best way π
//
Does anyone here use Atom in combination with the sqf-linter from Lord_Golias? And does findIf throw an error for you or does it work as expected?
I get an error saying that findIf is a variable, when it should say it is a keyword. I have tried reinstalling it a couple times, but with no success.
update your sqflint package via pip
I did that, using python -m pip install -e . in the my local git repo folder of the linter
make sure Atom's implementation is using latest version then
got it fixed. Uninstalled everything, made sure all files related to it were deleted, redid the clone of the repo and installed.
π
hello
I'm new to arma modding
I want to make a tool that can connect to a server and get the scores or kills or something of players on it. Basically, some way of automatically communicating data out of arma
Cool @smoky halo
Noe, what is your question?
New RCon tool? It will be interesting
Just configured the Discord bot https://github.com/Windmolders/Z-Bot-Light/releases/tag/1.0 to interact with my server. I like it. Some features are not working as expected, but it almost that I need .
@nocturne basin Is there anything already made that does that, or anything in that direction? I couldnt find anything by googling
.
Chances are, yes
You probably Look for some ist rcon Tool
@smoky halo would be easier to make server send stats elsewhere at the end of round than connect to the server and query it
Also please do not crosspost
oki, gonna switch here
whats the easiest way to have server do that?
Make an extension https://community.bistudio.com/wiki/callExtension
alright
there's a couple of different tools that log game data
OCAP, R3 AAR etc
we have our own at Anrop, https://aar.anrop.se
the current main release of OCAP has a bunch of backdoors and security exploits so beware of that
@scenic canopy you got that on github?
yep, the current version, not the intercept one
or well, it's also on github but not public π
all of the mentioned above are on github
How much is the gain using intercept?
a lot easier to maintain
oh thats nice
im good at python, so the more stuff i can do outside arma, the better for me
@smoky halo If you're good at python, then here's some shameless self-promotion for you ;)
https://github.com/overfl0/Pythia
I really need to update the readme file, finally, but I'm too lazy to do that
I need to make a bot for discord that awards points based on ingame actions
I'm scouting the grounds trying to figure stuff out
You'd need to be able to connect discord players with steam ids, first.
Then: https://discordpy.readthedocs.io/en/rewrite/ π
(use the rewrite branch!!!)
well, yep, usernames ingame
i know discord bots are py based
im trying to figure out if there is an easy way to do the arma info getting
like, what arma logs
etc
just found out about AAR
so, does it work with mods
like A>CE
i know discord bots are py based
No they aren't :D
There are lots of bots written in discord.js, for example, but since you said you know python, I gave you the link to the python library and suggested the right branch, so that you don't waste your time
sure, ACE emits events, such as unconscious or treatment
just like ACRE or TFAR emits events for radio broadcasts
Oki, gonna take some time to research, a scoring system that works with ace would be a nice goal
@smoky halo this shows kills for ace in debriefing, https://github.com/acemod/ACEX/tree/master/addons/killtracker
thanks :)
Which PBO tools do you guys use? I've used winse pbo manager 1.4 almost exclusively for testing but recently .net broke the right click > pack into pbo options for me. Is there any tool that offers the same ease of use that's also free? Alternatively if anyone has had the same issue and know a fix. I think my .net packages are more recent and somehow not compatible :/
armake(2) and mikero tools
@smoky halo you can simply readd it to your context menu
@native kiln how? Wouldn't the program not know what to do?
does your pbo manager still work by itself? as in, you can run the program via the exe?
Most of the time it works without errors π
so i assume youre just missing the context menu click on folders (make to pbo) and vice versa?
in that case, have you tried just reinstalling pbo manager?
that should re-register the context menu entries
Yep, doesn't work. Since it's an EXE I can't really do much about it. Wouldn't know how to make a context menu addition to work with it neither.
Hm, you can fix it with the registry editor, however I don't know if you feel comfortable doing that
I know enough to not break it. Not sure how you'd fix that though. Feel free to hold my hand if you want π
First website's tools don't work properly
no need for the tools though
I've got my experience with these tutorials telling you what keys to create
most of the time they just didn't work, don't ask me, ask Windows
Β―_(γ)_/Β―
and sadly the helper tools didn't detect all programs correctly
IDK what to do about pbo manager in there though
For future reference pbo manager has a seperate 32 bit installer which properly installs a key. Not sure why 64 bit didn't function for me.
Remembered that was the same issue for me some months back π
pboManager is an excellent, intuitive, and easy-to-use tool >for missions<. It can't realistically be used for (most) addons because there's no facility in it for the pbo prefix. It's able to read the prefix, but cannot create one.
extractpbo (gui) is similar to pboManager in functionality, but a little more complex due to the fact that it does cater for prefix.
the other problem with the tool you like is it cannot binarise/unbinarise configs,. missions, or rvmats so is somewhat useless (especially for extraction)
I don't think Armake has a gui that's suitable for you, but if it does, use it. Unlike bis, if you discver a bug in Armake, it's likely to get fixed.
You can create a prefix with pboManager, it's just not intuitive at all.
Does someone know whether the game performs more than just packing a mission as pbo when exporting it in the editor?
Because I tried to manually pack the mission folder as a pbo via armake (no additional includes or anything) but the resulting mission-pbo just doesn't work properly...
the exported mission.sqm is plain jane text, nothing wrong with that, but binarise is better (and I imagine armake would do that automatically)
it's more likely to be something you've done wrong/missing with the description.ext
During export? I left armake with the default settings - not quite sure whether that does anything with the description.ext
So I only used armake build <MissionFolder> <pboName>
And without chasing anything in the mission it works when exporting from the editor π€·
@sick verge did you compare the resulting pbos (extracted to source again without derap)?
not yet - but I gues I should do that. Just thought this was kind of a known problem or something like this
Well the mission.sqm I am using is binarisied already so that shouldn't make any difference
well apart from the sqf code, what's so special about a mission? even addon breaker can make them. so why would armake or even my tools be needed? perhaps you should try pboManager first which lets you 'make' a pbo that is a mirror image of your current folder.
Will try
@sick verge armake might try to binarize the description.ext by default which is kinda wrong
Or could you explain what you mean by "doesn't work properly" ?
armake works fine for packing missions, used it quite a bit
Interesting - "Doesn't work properly" means that either
- When starting the mission (built on Stratis and saved with the respective extension) I suddenly stand in the middle of Tanoa's jungle (all items are correctly placed around me though - so it appears to be just the map)
- Or: I start the mission and it immediately ends the mission as failed
Seems very odd me. Both times the issue went away when exporting it from ingame π€·
Maybe I should add that I am using a Linux-server - this could make a difference too
is the filename correct then? mission.stratis.pbo?
yeah that's what I meant with "proper extension"
anyways - I will compare both versions and see if I can find any difference when unpacking them again
and saved with the respective extension Ah I overread that
Interesting, I was using my own build, so it could become broken on later ones
If you can't find the difference just send me a working and non working pbo. I'll find it
Alright thanks π
https://s.sqf.ovh/chrome_2019-01-22_18-29-28.png New frontend for my profiler incoming.
I also now know how I could display scheduled scripts too. Even though their data wouldn't be that useful.. cuz you know.. scheduled
Next up is implementing support for "Tracy" profiler.
Which means live-capture over network, and memory efficient enough to probably be able to record a whole hour of session.
Also if you have a dokanPbo or normal P drive you should be able to open source-files belonging to the "zones" directly.
https://www.youtube.com/watch?v=fB5B46lbapc Here is a introduction video to Tracy.
This will be the next evolution of the profiler.
Maybe I can even add the Arma profiling build engine profiling to that. That would make it REALLY powerful.
Tracy also let's you directly compare old and new captures so you can easily see if your changes actually improved performance https://s.sqf.ovh/firefox_2019-01-22_19-07-50.png
This is literally making me π€€
Dammit dedmen, you crazy! but i love it!
I could add things like current number of vehicles or AI groups and such to that..
Make it be like arma server monitor just alot more overkill :D
Object count would be useful for diagnosing the terrible FPS drop I had in last mission when the cold breath script left like 20k particle emitters floating around..
Though if I add engine profiling that would also show up in there.. I hope
could you add a headless client watcher to see the effects headless client has on the server
anything to help debug is helpful
what would it watch?
It can already profile scripts on dedicated clients.
But how would it see if HC has positive effect?
Besides the server fps being higher.. But that's way easier to see by just using the #monitor chat command
It will tell you where your script bottlenecks are tho. And you might be able to figure out yourself that you can move that stuff from server to HC to get better perf
yes but a server monitoring can show the fps being 50 but the AI is de-syncing all over the place,
It be nice to see the HC is having a positive affect, especially when units are being spawned in plus if blacklisting units from HC is beneficial or not
Don't really know how.. But then.. Most of this stuff is about things that people never thought of doing previously sooo... π
hey bud thats what its all about. It doesn't matter if you cant i was just spit-balling random crap.
Plus you're doing gods works. Finally being able to see what is killing performance instead of blaming BI plus finally be able stop all the arguments about what is the best method for doing certain things.
Hah π The second part is why I originally started with this π
use private keyword bois!
but the second part was doable before, it just had to be much more granular
i like to go with my method is best the bad performance is BI, dont @ me about doing everything in PFM.
sidenote does this have any benefit to modders with LOD and models.
yes but who has time for that when you can blame BI?
The first part too with profiling build.
Just alot more granular if the cause of problems were scripts
no this does nothing for modeling and stuff.
also your script could be being blocked by something else
This is 99% scripting
i thought so, just checking
If you are interested in modelling stuff you could get a real GPU profiler like NView thing from Nvidia.. Not sure what the exact name is, but I have it... Nsight! right! Nvidia Nsight.
I could probably add more fine grained engine profiling to for example log how long each model takes to draw... But... I have no need for that and few people do. So I probably won't do that.
me, modelling lmao. im a programmer if its anything more than a block with a flat single texture for testing it aint happening, I was just wondering for performance testing of mods
i'll leave that to the artist of this community
Well if there are script problems in mods it will light up bright red :D
Found many ACE/TFAR problems (and one huge bwmod one) with that already ^^
soo much easier but not as flashy in end compare to a tank or jet
but i was more on about textures and models
for example some weapons packs love to eat fps
Can't wait for semester to finally be over lol
Find some stupid performance eaters
But I am saying that now because I don't want to study, and after I won't have to for a bit, I'll even be too lazy to profile stuff
I used Nvidia Nsight before to profile Arma and it confirmed a few useful things generally like the drawcall count and overhead of doing so is relatively low but it didn't give me a great deal of information beyond that without the source code for the game.
I can see it might be useful for something like model testing though if you can compare scenes with and without the models you have added, but I don't recall getting the sort of granularity that you could use for directly attributed the time your thing does (but I wasn't admittedly using it for that, I was trying to ascertain if DX12 would have any chance of improving Arma performance after they announced they were trying it)
Finally being able to see what is killing performance instead of blaming BI
This is the 2nd level meme though
There's still tons of things where you can 100% blame BIS for performance
Particles being one of them
Smaller cell size terrains
I think Particles is now the big problem we see, but I also think that is also being impacted by ACEs cookoffs and if you add blastcore and such that gets way worse. The profile build doesn't really show it up very well either. I think there is a leak of particles that grows over time but I haven't yet gathered sufficient evidence to point directly at it
Also when can I get my hands on this amazing profiling tool? You know I want it!
i think everyone wants its, even bi
but they probably have their own inhouse one
and as for it being a 2nd level meme i know.But at least for me a lot of stuff i see is normally cause by people doing really dumb shit and blaming BI. But other times its BI fault and its just, work around it or deal with it
If you want a beta tester I am happy to help as always. The last version I still use to test my scripts, just a shame it never directly tracked down that antistasi issue but I think whatever that is seems to be entirely with BI and we don't quite enough information on what could cause it
Terrain cell size and other quality stuff like that will always be a tradeoff between performance and quality though
Certainly need to have a look into the CF_BAI/detect routines, 30 v 30 is taking way too long currently despite all I have done to reduce calculation and cache results.
We reject quite a few terrains that just run too poorly, they look lovely in images but when you don't get good frame rates on an empty terrain there is no way people are going to enjoy it when its pull of enemies and the fps is even lower. I can see why a maker makes that trade off but I think performance is a really important part of what people look for in terrains at a minimum level of quality.
yeah i agree, i'd rather play on a a1 map with 60+ fps then a lot of maps with 20
its hard to enjoy the scenery when im looking at it in a powerpoint
Terrain cell size and other quality stuff like that will always be a tradeoff between performance and quality though
Sure, but BIS one isn't really on the high end there π
Enfusion rumors are better there
Like you get people blaming BIS for everything, but also thinking they're holy and vanilla FPS is amazing
which really it's not either, it's very easy to get bad performance in arma. Heck look at Argo, performance is trash in it and it's fully within BIS own control
nah, have you been in kavala on a summers day
Kavala performance has improved quite a bit from where it was a few years ago. Still the worst performing point on Altis but above 60 there is now consistent everywhere.
but i also agree a lot of hate towards bi is down to bad mods and mission makers being like 100+ ai.
i would like to see improved core utilisation but from what i know and read thats more an engine issue
I am not saying BI isn't to blame, just stating the obvious
Also BIS is not BI
you still know what i mean, it doesnt matter for an extra letter
im so used to saying bohemia interact studios
You can even run 200 AI if you know what you are doing and get good performance
It's just that most people simply don't know how any of it works, and there are a lot of people spreading lies
So more people read those and follow without thinking
i know about that but still having 100+ ai all in active combat near a player is a no no and some people blame bi for that.
putting some dynamic simulation with some manual simulation with syncing groups can allow for much greater numbers on preloaded AI along with HC
but how many of the arma playing base know about all the tricks to improve mission performance.
im not sure but i think this is getting off topic
tricks to improve mission performance.
The tricks BI doesnt evne use in their own missions
Not many, and that's a problem
Like I know there's a ton of tricks, but a lot of pure vanilla stuff isn't great
And yes, offtopic :p
Smoke can be optimized quite a bit (Both in actual usefullness, lol at vanilla rubbing values)
But.... it's the usual arma thing of relying on the community to fix problems
well lets wait and see what A4 has to offer
Good joke
Well at least for now dayz performance is quite a lot better
More off topic comments but when people remember OFP and even ArmA 1 we could have a ton of AI and performance was not as degraded as it was in A2/A3 but of course with much lower quality AI processing. We could have tons of mods in OFP and it impacted performance to a much lesser degree probably because of the simplicity of all the assets and the general effectiveness of the engine. (at least on a fast computer) That was one of the big innovations of both Source and RV... they were efficient enough to allow novice scripters to use that performance for their mods, and it is no surprise they have large modding communities. Hopefully Enfusion can be efficient enough to give us plenty of frames for mods to use for useful things, it should be a high priority. π
you have a point there, that's what happens when you use the same engine but don't or can't update it enough to use newer hardware as efficiently as it did when it was new
It is one of the reason I want to get access to more cores with the next engine. I want to be able to explicitly utilise threads. Since the entire world of CPUs is clearly heading towards more cores, and it is vastly cheaper to add cores than it is more clockspeed or IPC this is what a future architecture requires. The core game might not utilise those ores but as a modder I can often be very parallel and we could do a heck of a lot more if we had that ability with Arma 3. As is we are so constrained by how little performance is left that it diminishes what is possible while having most of everyones CPU sitting idle doing nothing
@smoky halo Also when can I get my hands on this amazing profiling tool?
https://github.com/dedmen/ArmaScriptProfiler/ Current version supports Brofiler or Chrome. The new Tracy stuff is only coming today.
but they probably have their own inhouse one Jup. It's called diag_captureFrame And we happen to have access to that one too.
Btw didn't notice any particle problems. Besides that script that spawned thousands of emitters last mission, but the problem cause was the thousands of emitter vehicles, not the particles.
Woah nice.. Tracey also captures crashes, combined with engine profiling you could see in which region the engine was when it crashed. If it was in model loading or rendering you know something is probably wrong with a model.
That will be nice if that really works. Not ultra useful, but a nice extra.
Can also display diag_log calls in the trace, so you can see which function called diag_log at what time..
Don't think I wanna do that for engine RPT logging too, too much work. But I could.
How about a memory allocation/useage graph? that is fairly "trivial" to do. Don't know if that would be really that useful. But if you see that your script is allocating tons of memory that would be very useful. Could help to detect memory "leaks" caused by scripts.
Okey it seems I have the basic Tracy implementation done, was easier than expected.
Tracy also has a command line application that just records data to a file on disc if you don't wanna view it live. Man I need to write a wiki page for this.
Holy macaroni.. My hype levels have reached the 9000 mark.
All that is running from my Home PC to my work PC over a Teamviewer VPN.
statemachine checks are exactly what I am excited to use with that tool when its ready, great job
After 11 minutes the ram usage is at 85MB.
Want to see what functions take the most time, over a long period session?
Sure! here you go!
This is literally the best thing ever
Currently it doesn't log _this arguments. I had that in the Brofiler version, But that really has no place in a profiler so I won't re-add that for the Tracy frontend.
Clockwork really hits it off in this one π
Senfo - 2019-01-23 03:27 -08:00
Clockwork really hits it off in this one :sweat_smile:
I accept the challenge of making a clockwork iteration be the most intensive. I'm converting this to statemachine
https://i.imgur.com/BZWvG7z.png
I wonder what happens when I enable instruction level profiling π€
I had to disable that for brofiler because it just lagged it to death.
CBA statemachine was (IIRC) designed so it will always have pretty much constant workload no matter how large the statemachine is
the statemachine handling itself of course, not the subfunctions
Instruction level profiling works splendidly.
compileFinal is calling compile because the profiler redirects it. And the gap between end of compile and end of compileFinal is the profiler inserting instrumentation instructions into the compiled code.
I have no doubt that the release of this new version is really going to help the community develop better scripts because there is a darn good chance we will find what is going slowly over the longer term. Looking incredible!
That stuff was already possible with the previous versions. Just not that feature rich and easy to use
Better scripts? Doubt it very much, people who write shit scripts will continue to do so. The only thing this would help is to people like Dedmen to identify where BI fucked up
Want to know how much impact retriving variables has? Easy! Just click on the getVar instruction!
Man I'm so hyped..
So far getting a local variable seems to be about 300-500ns
but a global variable can be up to 5us.
Try object namespace for comparison
Not the getVariable command.
the get variable instruction.
Commands are all >1us
Does setAmmo immediately broadcast ammo change of a unit or there is a scheduled update packet?
All packets are pushed into the queue immediately. The queue will be processed "later" like.. a couple milliseconds later maybe
So if you setAmmo each frame you will have a train of packets?
Position sync has a scheduled update
Arma might batch them together as it sees fit. But if you didn't get close to the bandwidth limit it will just send them out
I was playing with concurrency analyzer for visual studio, and it has nice API for adding flags/spans/messages/whatever with custom text to the graph. I guess you can easily add similar SQF commands to your profiler which would interface with this Tracy program? π€
Already have SQF commands for the profiler.
You can dump messages and set counters so far.
Don't know what else I could add. measurement zones, messages and counters is about everything
Then it's great π
I thought it only plots stuff. Never tried yet because so much of my stuff is scheduled
I was looking through chat... somewhere you said that you can add profiling of scheduled scripts... can't find the exact message
I'd really love to see that. Is it mega-hard to do? I guess you'd just plot every spawned script as thread π€· Maybe add indication when arma scheduler suspends my scheduled script because it took all the time interval and suspends it, I don't know
It plots all script functions. And you can add your own mid-function measurements if you need.
Plotting every spawned script as thread is the easy solution yeah.
Finding out when it's actually being executed is a little harder. Still quite easy for my standards ^^ Just alot of work
Why, what would be the use of it?
I work on the stuff that I find useful. And I don't care about scheduled so it's not high on my list
And I don't think the frontend would properly display that stuff either.
It won't be useful for performance analysis I'd say. But it would be useful to see what's going on right in that moment.
I'd say if I develop my stuff with scheduled scripts, I already abstract away the fact that arma stops it and suspends it when it think it's ok. I don't really care about that. What I care is how much it takes my thread to perform a task, irrelevant of FPS.
Donβt understand
Hmm... I spawn a script as a sort of worker thread abstraction. I push messages to its queue to make it do work. I'd like to see how long it takes to process messages and plot that stuff. If arma suspends it in the middle of processing a message and resumes a few frames after that, I don't really care.
So, let's say I can start a span (this rectangle in the profiler) when I start executing my code in scheduled and stop it when I'm done. If the profiler figures out that the start_span was called from one script (thisscript), it should place this span into the proper horizontal line which corresponds to this thisscript, that's what I mean π€·
Iβm afraid your script wonβt resume in a few frames it could take much more than that in scheduled
But we don't care about that if it's scheduled, it's normal, all scheduled scripts do that π
Sorry you are talking about profiler presentation?
Ok not what I asked though
?
Was curious how useful this could be for writing scheduled scripts. We already know why suspension happens and when, how seeing it drawn on graph would help?
Hmm... IMO profiler is good because it lets you show how the state of your program varies in time. And suspension is an important program state. So I think it would make sense to plot it. π€
@glossy inlet Where can I see what SQF commands your ArmaScriptProfiler provides?
The 3ms is hardcoded if it was variable depending on FPS I would agree with you but it is a constant
Yes but you would see that your spawned script is definitely suspended now, and not just stuck/doing nothing. I guess having some sort of indicator when arma switches scheduled scripts should be useful for that. But even if there is no such indicator, being able to profile scheduled would be great.
https://community.bistudio.com/wiki/ArmaScriptProfiler
There is a profilerSetCounter command that's not documented "name" profilerSetCounter _number
And all the capture/trigger commands are for the diag_captureFrame frontend, which is garbage
The profiler would show the difference between a single scheduled script running the full 3ms and then being force suspended. Or it exiting early because of waitUntil or sleep or similar.
Could help identify while true garbage without sleep
Maybe you could add commands to create a line with specific name in the profiler plot, and to start/stop a span (this horizontal rectangle in the line... how is it called >_<) in a specific line? Then I'd integrate the profiler into my SQF code easily π
already exist...
create a line with a message profilerLog.
start/stop createProfileScope
So, I create a scope with createProfileScope, then the script suspends before the returned ProfileScope variable is destroyed. How will the profiler draw it?
How about sleep [time, count] command that returns bool especially for while loop garbage? So time is sleep time, count is how many times this command will return true before it returns false. -1 always returns true
wat
why not just use a for loop if you already know how many iterations you want. And then just place a sleep inside it?
Just throwing some garbage ideas around
That's what I mean... If I could have an SQF wrapper API for drawing stuff in the profiler visualizer program, I'd easily profile my scheduled code, because the lines/spans/scopes would be made by me
You can do that of course but where is fun in that?
I would see what's happening in my code easier... currently I have a few threads running and they dump stuff into the rpt, which is getting hard to read
if !(sleep [1, 10]) exitWith {};
"threads"
If it behaves like a thread then I can call it a thread >_<
but it doesn't -.-
it behaves like a thread on a single core cpu
I could argue that there are no threads on a single core CPU, come on
if this can log stats, then you could gather useful info on scheduled code
stats?
Man.. I had literally one byte too little space to plug in for the engine profiling..
So I had to write new hooking assembly that is now 3 2 bytes smaller than what I was previously using.
Revolutionzing my other projects while doing this :u
Also I would've had to leave 3 minutes ago to catch my bus... Guess I'll stay a little longer then π
So do my profiler visualizer wrapper functions make any sense or nah? π
Maybe... But they won't work in scheduled.
And if I make them work in scheduled then.. We already have all that stuff..
Why won't they work? An sqf command asks Tracy to register a line where it will draw rectangles, and it just does it? Then SQF asks Tracy to draw this rectangle, etc. Or is it not how Tracy and your other profiling visualizers work?
Ah now I understood
yeah I can enable profilerLog command in scheduled. I think it already is enabled
that's not really how tracy works no.
I don't tell tracy to draw. I tell tracy when a zone starts and when a zone ends
I think I got engine profiling working. But I gotta catch my bus now.. Cannot test. Foof
Yes, what if I could tell tracy when a zone start and ends through SQF, that's what I am trying to explain π
Even if. Scheduled.. You have 0 control
I already have a solution.. Will probably be easier
Welp arma got to main menu without crashing.. Engine profiling probably works.. I'll present actual results when I'm home in 30
stats
total number of executions
executions per timeframe or specific time box
"parallel" executions
or stuff like execution tree
what does execution mean?
call/spawn (etc?) of a function
in simple terms of how often the code is ran (total/per timeframe/per timebox)
similar would be useful for network calls (pV, setVar public, remoteExec[Call])
could already enable instruction level profiling.
Atleast for remoteExec the command executions will show up. Also in scheduled scripts
https://vid.pr0gramm.com/2019/01/18/a3923b4e83e9f353.mp4
I got this running in a loop. Really helps me progress faster
someone make me a perfect loop so that I can work even faster π
But I can already see the finish line anyway. So maybe not worth it.
Gonna go full speed now! nobody gonna slow me down! o no arma crashed! I got to keep on movin!
https://s.sqf.ovh/Tracy_2019-01-23_18-48-42.png sooo close.. Zones don't exit when they should.
@glossy inlet You remember me complaining about missions being packed with armake not working? You were right with your suspicion that armake binarises the description.ext. So I guess that is the issue
I remember commenting on it that it binarizes everything that ends with ext which is plain wrong, if at all then only description.
But I don't remember ever seeing a binarized description.ext in a mission pbo
Pack it with armake v0.6.3 and you'll see one π
Fixed in armake++ ^^ (Don't build p3d's with this)
Alright thanks π
What is armake++ though? A c++ port of the original? π€
Alright apparently the binarised description.ext was not the cause of the mission being faulty - the search continues...
yep
As I said. Send me working and non working pbo and I'll find the difference ^^
preferably tomorrow. Wanna finish the profiler stuff first
Will do as soon as I actually validated that the "working one" is actually working ^^
It's done!!!!
The sad thing about this is... I'm VERY sure I now have better profiling tools than even what BI uses internally...
Better stuff than diag_captureFrame?
Yes?
If only the modders could have access to that π
Well now we atleast have a alternative..
A VERY ram hungry alternative :D
3GB in 5 minutes with engine stuff enabled
@glossy inlet ffs
a friend of me spammed me that link a dozen times because hes so hyped about it
and now you post it too

which link? π
the pr0gramm link
he even used it as his avatar https://s3.eu-central-1.amazonaws.com/trski-storage-public/ShareX/2019/01/2019-01-23_ivlRhaRcuoTTJqEbMi6.png but ill shall stop, too offtopic π
Profiler build is out
https://github.com/dedmen/ArmaScriptProfiler/releases/tag/1.0.28
with professional wiki page https://github.com/dedmen/ArmaScriptProfiler/wiki
Now It's time to lean back and do nothing for a couple days πͺ
I wont look at it until tomorrow at the earliest so no bug reports rom me today at least.
I sure hope so.. I wanna go to bed and sleep well now..
Don't give me nightmares now
First performance optimizations being done using this shiny new thing
You can let the live recording run in the background. While you compare a old saved recording with the live one.
Red is old, yellow is new.
500us average down to 161us
Next feature, capturing diag_log messages and displaying them in the trace.
Can just click onto the log message to jump to it in the trace.
Don't know where a certain very cryptic RPT message comes from? if it comes from a script then the profiler will show you from where. (assuming the script itself also shows up in the profiler..)
I'm looking at Tracy...
void SetThreadName( std::thread& thread, const char* name );
void SetThreadName( std::thread::native_handle_type handle, const char* name );
I think we can't make it draw fake threads per every spawned .sqf script then, because Tracy is supposed to be attached to a real Windows thread... Am I right? :\
Unless we make windows create a thread, and then it will be dumping logged data into Tracy file
Why would you want to?
Scheduled scripts are still executed linearly in one thread
Showing it as multiple would be confusing
Yes we discussed it above... it would help me visualize states of my multiple spawned scripts with the help of tracy functionality, although they are inside one thread
You'll have a lot of rows π
And?
And nothing
Allright, let me explain @fallen stone
I have this huge CTI thing I am making... it has a 'thread' for handling AI, another thread for handling spawning/despawning things, there is also garrison level AI, group level AI, and unit level AI, groupped into different threads... I want to see better what's each thread is doing, even if it's essentially one thread. It'll just be easier for me to see debug info in a time plot than in an .rpt file, at least I hope so. Does it still make no sense in your opinion?
To me, yes, it's going to be hard to have a proper timeline of events if you have god knows how many rows
Unless Tracy has a neat way to filter things
Hmm... no, I have like 3 'threads' actually, not so many
I can probably detect when a VM ends, and just re-use the threadid then
And I don't think you generally have hundreds of threads in a generic program... might be wrong, i'm not sure
No, but you have a lot of scheduled things running over time
The number of threads will only be the max number of scheduled scripts that are running "in parallel"
which could be many.. But in that case you know which mod to remove, or where you have to fix your own shitcode
No, really I have a few 'threads'(below 5)... I don't spawn a scheduled script every time I want to do something π
Your code isn't the only code running though
But let me correct myself, i was really talking about exposing tracy API for drawing stuff to SQF in Dedmen's addon, not making Dedmen's addon draw every spawned script by default
So I'd add tracy calls into my sqf scripts... and help me visualize stuff with it
where I need it
I could disable automatic scopes for scheduled, but leave the scope script commands open
That would be better by the sounds
Would be cool if the profiler could define global macros so that you don't need to manually enable/disable the stuff
That's what I call a lot of rows π (not my screenshot)
https://www.microsemi.com/images/soc/polarfire/Modelsim.png
These profilers remind me of my Verilog attempts so much
Hmm... you are talking about defining a macros in SQF file? like you can do with a C compiler...
The global macros in the compiler settings yeah.
My debugger had that for a while
[100%] Linking CXX shared library ArmaScriptProfiler.so
[100%] Built target ArmaScriptProfiler
Oh dis gon be gud
https://s.sqf.ovh/putty_2019-01-25_16-38-31.png Linux server profiling is a go! Even found a linux bug in Intercept π
Though who could expect that BI disables useful optimizations on Linux...
Disables or not enables?
@glossy inlet is that an real server monitor/profiler or is it your script profiler? π€
the script profiler
k
subscriber only updates:
pboProject
deRtm
extractPbo (gui)
How to make .wrp binarized ?
pboProject uses bis binarise to achieve that miracle.
best off continuing in the terrain makers channel @spice hawk , they can help you far better than me, BUT
+your panels look fine
+your free version is way way out of date, a free update is available
ok tahank you 4 answer @dawn palm
Does anyone have a copy of (or mirror for) the T_D tools?
@small sluice what are you looking for/want to do?
I want to see the named selections and texture files used in a model
Thanks, are they an object I can get the position of?
well in a way but the selection position would be the average center of all the verticles in selection
why do you need them
if you are doing retextures you can only do them with things that have hidden selections configured into them
those you can also see from the config viewer
@small sluice
Thanks
https://i.imgur.com/ZA9wOPn.png
Successfully published
it always defaults back to 'Friends' I have no idea why and I can't select public in workshop either
@silver carbon have you agreed to the latest workshop terms & licenses? I've had to fix that sometimes before we could use the workshop publishing stuff correctly
it's a small hidden banner when you visit your published workshop items, or something like that
No small banners anywywhere on workshop
The account also has β¬5 in the wallet
(Its not marked as limited account)
What adanteh said
Turning on Steam guard did it (Whicvh is annoying as fug because we share the account, seeing workshop doesn't support multiple authors publishing updates)
Ofcourse there is absolutely no indication on this anywhere and steam's support page on limited accounts doesnt show it either
You always wanted to see how it looks like when a client joins your linux dedicated server and starts a mission? Well you are in luck!
(Linux server engine profiling support for profiler)
Disabling just two zones (evwfGet, evGet) reduces the capture size from 1,8GB to about 400MB
The zone seem kinda useless for profiling and got like 10 million call count :U
Oh this is useful...
In general after disabling the spammy and mostly useless scopes, engine profiling becomes alot more useful as the traffic it generates isn't that big anymore.
really cool!
CBA statemachine is wasting 1/4th of frametime doing nothing π€
I guess I broke something π
Well... Googling around, working on profiler, reading stackoverflow.. Ah a reply by Suma.. Wait.. Wat. Oh. Hi Suma.
https://stackoverflow.com/a/173925
π¬
That guy is everywhere
He's alive! https://stackoverflow.com/a/54207158/8746007
Which functions of your huge mod take the longest to compile? I have the answer!
(Special handling of calls to CBA_fnc_compileFunction)
at least that one actually looks more like "questions nobody ever asked" to me
With the help of the profiler and 8 hours of work. I just about halved the mission preInit time with my modset.
With my ACE/CBA pull requests everyone will profit off of that in a couple weeks. With just ACE/CBA you can expect 1 to 2 seconds faster preInit :3
So what was slowing it down?
Did you manage to work out how to improve the per frame cost of the event handling in CBA?
There were functions compiled at preInit that should instead be compiled at preStart. Or config parsing done at preInit that should be at preStart.
Or my last change the eventhandlers are defined in config, and many are just
call compile preprocessFileLineNumbers "file"
So when it fires that event and executes that code, instead of just executing file it would always preproc and recompile the file before the actual EH code runs.
I added detection for that pattern and made it directly redirect to file when the eventhandlers are compiled (which I also moved from preInit to preStart)
So TLDR moving stuff from preInit to gamestart, and removing a stupid nested compile.
So you made game start slower?
yeah. Game start slower once, instead of every mission start slow, besides the preprocess thing, that is just generally faster, not transferred to preStart
If you had world loading enabled at game start (menu bg world) then it should be same. Shouldnt it?
Because it was compiling the stuff anyway just not caching it.
Or is menu bg mission not firing preInit stuff?
It would cache to missionNamespace, which is reset before next preInit. So that wouldn't help much
https://s.sqf.ovh/Tracy_2019-02-08_17-46-48.png everything that lights up besides cba_ui_init is just gone after my fixes are merged.
CBA_ui_init stuff is moved to preStart
70% of cba common xeh_preInit is moved to preStart
500ms of ASR AI stuff is moved to preStart (not displayed on here)
https://github.com/CBATeam/CBA_A3/pull/1056#issuecomment-461842676 here is a summary of everything I did
The beautiful fixes are things like these:
https://github.com/acemod/ACEX/pull/169
https://github.com/acemod/ACE3/pull/6799
Stuff that has been in for 3 years and noone ever noticed that it's wrong.
@smoky halo can you explain? Do you mean the custom eventhandlers that CBA add's Like weapon changed and such?
CBA eventhandling itself has no per frame cost
I seem to recall you saying that the per frame cost of CBA by default was quite high a week ago or so
because the player EH's are added always if you run ace I guess
a week ago definitely not, atleast I don't remember it
Dedmen, for the interceptdb do connections persist on mission end in dedicated environment where server isn't restarting arma? Or does it close down connections on mission end and start back up with mission start?
and I'm wondering how to validate connection is still active, I like to verify connection status regularly and flip a flag if connection to DB is lost for some reason so we no longer run DB calls
and do I use dbExecute instead of dbExecuteAsync to wait for query to execute before continuing? Or does dbExecuteAsync do that normally?
@glossy inlet
Connection should end when the SQF variable that stored the connection goes out of scope. So they should end at mission end. Unless you store the variable in uiNamespace or similar.
Connection is closed when there are no more references to the connection. If you have async threads running then the connection might only close 60 seconds after mission end, as the worker threads disconnect themselves 60 seconds after their last task.
dbExecute waits for the answer yes. dbExecuteAsync returns a "async result" that you can either wait on using dbWaitForResult or you can bind a callback to it dbBindCallback [{params ["_result","_arguments"]}, arguments]
cool. Is there any way to validate connection? say the DB goes down and all the queries start failing?
If you str _connection it tells you whether it's connected
ahh, cool
Either
<no session> or <not connected> or <connected to database: xxxx>
although no session should never happen π€
i am getting a file not found error
for which file?
"Database config error File not found: The operation completed successfully.: "#InterceptDB/config.yaml"
is the first line on loading up editor
yea, moving it locally fixed that
well, i managed to crash arma
lewl
https://github.com/intercept/intercept-database/blob/master/src/config.cpp#L29
Should be @InterceptDB mod folder in Arma directory. Just like every other mod... Unless you have a mods subfolder I guess
If you have a mdmp put it in a zip archive and throw it at me
If you don't use the config you can ignore that error btw
lemme check to see if im doing something stupid first
Well my stuff should be stupidproof too
mmm
i might just be totally misusing it lewl
im just checking where it f's up
DB_Connection = dbCreateConnection "maindb";
DB_Connection dbExecute (dbPrepareQueryConfig["newgame", [worldName]]);
That should be correct yes?
yeah. Don't see anything wrong. Maybe there is something wrong with the config? but then it should tell you and not crash
yea, seems to crash on running DB_Connection dbExecute (dbPrepareQueryConfig["newgame", [worldName]]);
lemme pack
A breakpoint was encountered. whoops π
https://github.com/intercept/intercept-database/blob/5b5eacc286eed729cdfd1b880335a22d969b1107/src/connection.cpp#L193 there it is.
Question is why that fails π€ I'll add logging, gimme a minute
lol
ahhhh, ok i see error now
auth level on db user, forgot to add execute
does dbCreateConnection not wait for connect to complete or fail?
ahhh, ok
if first query attempt fails to connect, will it throw error and break script?
kk
yay, its connecting
i do have the problem of it always saying <not connected> when i check it
but it does apparently connect on queries
so not something I can use to validate if connection succeeded
i guess i'll just have to validate every return and use that
oh.. Right. Because it creates a copy of the connection in the worker thread
You could just make a ping query I guess ^^
yea pretty much what ill do
I'll come up with a fix for that when I have time to work on it.
Currently working on making missions load 8 seconds faster :U
i have a loop for server details every so often, ill check there so silent errors wont last long
I could build something like.. You define eventhandlers on a connection. And when an error happens the eventhandler will be called. That would be good right?
Feel free to make feature requests on the github with whatever comes to your mind
https://github.com/intercept/intercept-database/issues
i think so if i understand right, i just want to flip a flag I use before entering DB related code
set it to false, so DB code doesnt get entered
no point in any loops or pulling information to send to DB if DB has no connection
I could make a ping command that makes sure it connects and that it can query. Basically shortcut for SELECT 1 and checking if it returns 1
yep
would work for me
moving this mission over today, test through tomorrow, maybe have live for this week
see how it runs through extended use
The profiler just paid for itself. Two days of work + profiler.
Before is CBA and ACE on latest release, plus my default modset (RHS, CUP Terrains, NiArms, 3CB and some misc stuff).
After is CBA and ACE on master branch and all my PR's merged.
Before:
preStart: 21.92s
preInit: 7.77s
postInit: 11.61s
After:
preStart: 32.04s
preInit: 2.52s
postInit: 1.84s
Totally worth it.
>15 seconds faster mission start for 11 seconds longer game start
only ace,cba
Before
preStart: 15.72s
preInit: 4.06s
postInit: 5.10s
After
preStart: 19.89s
preInit: 1.36s
postInit: 1.19s
π
Great job!
is it possible to upload arma mods to workshop without steam running?
or stop steam downloading anything from workshop
@vague shard just set a download speed to possible minimum, upload what you want, and remove the Steam
In my case - my mods installed on a main PC are downloading already a few weeks in the line on my second PC. I don't need mods there currently.
π
speed limiter is an interesting idea indeed
@vague shard you can use steamcmd to upload without having steam installed or running
