Gleeok wrote:I'm still against moving c++ code to scripts just on principle alone. If you think guys are a pain to debug or work with now, just wait until you have no debugging support whatsoever. My argument is that built-in enemy (i.e., editor edited or legacy) behavior should be a separate code path from customized (scripted) behavior.
That was my original plan. Add an npc type, 'Scripted', and that type (and all offshoots) use scripted behaviour. The other internal npcs are preserved as-is. Thus, any new npcs that we add after that point, would all be scripts that the user can edit. This is a bit forward of the present formulae.
jman2050 wrote:In general I think that compartmentalizing the scripting environment into various arbitrary categories is a mistake. That was never the intent of ZASM/ZScript in the first place and really the distinction between stuff like "global" scripts and "FFC" and "item" scripts only really exists to tether specific programmable functionality into specific use cases as already defined in the engine itself. i.e. the only reason you'd use an item script over an FFC script is that you want whatever stuff you've programmed to happen to occur specifically when using an item as defined in the ZC engine itself. You could just as well make an FFC script with the exact same functionality and design in what way it's activated yourself. In the same way while the ability to attach scripts to enemies defined in the enemy editor directly would be convenient, that doesn't stop people from programatically making Fire enemies with custom attributes and custom behavior on their own terms without worrying about ZC's enemy code at all.In general I think worrying about how any advancements in the scripting environment will clash with legacy code is a pointless exercise. The legacy code has to exist in some form because it's used in every quest. Whether it's the same kludgey spaghetti code we've had for 10+ years or refactored to be easier to manage and integrate with future changes or even converted to scripts entirely is immaterial to the end user and becomes merely a question on which will be easier to manage on the development end. Rather than trying to further entrench the scripting environment into the legacy code (or vice versa) I think the setup we've had up to this point is perfectly fine. ZC behavior will be ZC behavior and scripting will be an open sandbox that allows users to extend or even outright replace ZC's functionality with their own. Not that I'm saying things can't be improved in areas where the legacy code remains a rigid restriction, but those improvements should primarily be focused on improving the end user's ease-of-use and freedom. Stuff like making scripting more modular so scripts can act more independently of each other, better ability to use generic scripts without modification, improvements to the language itself, and even improvements to ZC's engine to accommodate ambitions that are otherwise difficult or impossible to accomplish. Allowing scrolling and rooms not conforming to the same 16x11 play area we've had since 1999 to state one example, or finally moving away from the limitations of 8-bit palettes.
I guess this is more just a random hodgepodge of thoughts relating to the direction of ZC rather than a direct response to the topic at hand, so sorry for that. In general I'm not against exposing more of the engine's properties to user editing but DarkDragon has already clearly laid out the dangers of doing so. The good part though is that as long as you guys don't actually release anything, you don't have to worry about those consequences for the time being! :P
Whle I agree with most of this, I feel that segregating things into class/pointer format makes it a bit easier to remember, rather than dumping everything at the global level. It makes far more sense to have Graphics->Draw, for what we will be doing, and Graphics->Palette, than splitting these between screen and game, IMO. If a function is attached to a script type that is associated with a pointer, and therefore has a 'this', pointer, then it belongs in that class. Otherwise, I would, as a scripter, rather know that all the audio functions are under Audio->, rather than Game-> and (global)->.
Hell, I would rather that the extant stuff was categorised, as it is easy enough to trip yourself up on the pointer type for some of this stuff. It will also make things a bit cleaner when reading them, as the pointer type illustrates the purpose of a function in a broader scope, so the script code itself is cleaner as a result.
You know, [MENTION=61126]Dimentio[/MENTION] mentioned something about you having previously worked on some kind of engine modification to modify screen dimensions, permit pseudo-scrolling, or some such thing. Is there any fact to that, and if so, does any of that still exist, or would it be pertinent to the 2.6 process? I was considering working on a way to modify the screen draw dimensions, adding boundary points that can be modified (for smaller output, or custom scroll zones), and adding boundary points for all weapons, at which they automatically die; these set by quest data, or modified by script.
These are some examples of 'rules' that would be in the FFScript class, [MENTION=1]DarkDragon[/MENTION]. WeaponLeftBoundary, WeaponRightBoundary, and so forth, as these are linked both to ZQuest, and to ZScript, and thus it seems logical (to me), to centralise them in FFRules[]. You can call them BananaRules[] if you want, but the point is to put anything that both the engine, and the script engine routinely access in there, unless it belongs as part of a class/struct, say, for weapon behaviour (other than global boundaries and such nonsense), or item animation (as part of the itemclass struct, on a per-item basis.
This would mean setting these flags by default for old quets based on the old QRs, and reading the class bits instead of QR bits on a per-item basis, or per-npc basi, or what-have-you, when determining how they work. That allows the same level of compatibility, with far more flexibility in the mechanics, and it (in theory) makes it easier to later integrate these things into scripted behaviour for weapon, and npc scripts.
DarkDragon wrote:Tried to post this last night but was blocked by some server issues; I think I already mentioned all of this to you in chat but I'm pasting it here for the record.These function the same as Game->LoadItemData, right? Why not mimic its syntax?
Sure, I likely will, when these things are better defined, and they need a 'this pointer. For the moment, I need to determine what the actual results are of doing any of these things, to see what works, what does not work, and what requires sticky tape on the windows.
That is why they are all in their own branches.
Regarding the ability to write to the buffers during the game: some values in the buffer are read when enemies are created, and will not change if you write to the buffer after the enemy is already on screen. Others are read when enemies move, are hit, etc. It's a random hodgepodge of behaviors based on the particular way each enemy is coded up in guys.cpp. Exposing the internal .qst file buffers with write access permanently locks in the current behavior of every enemy, since there will be no other way to ensure that scripts continue to function in the future. This may (or may not) hamper future attempts at making enemies more customizable or scriptable, so think carefully before opening that bottle, because it won't close again. At a minimum, all developers need to be made aware that the guys.cpp behavior can no longer be changed, and quest authors need to understand the dangers of writing to the buffers while enemies are using those values dynamically (best would be full documentation of how every enemy uses the buffer values during play, but that may not be feasible). All of the above also applies to combos etc.
Also it should be made clear in the documentation that changes to any .qst file buffers do not persist across quest save/load or reset. You might think that's obvious, but I've gotten related questions about why scripted changes to the ZC GUI do not persist... 😉
I have in fact, considered adding two forms of work-arounds.
1. FIx the refresh cycle so that if any of these facets are changed, all of the elemts that are on display are also changed (on the enxt frame).
2. Add a Refresh() function to each of the pointers, so that the user cna direct them to redraw, refresh, or reload.
Some things, such as npc->SeHP() could be written so that the engine checks this, and if it changes, to do npcptr->HP = min(currentHP, npcdats->HP) for all npcs that exist of that type.
I'm not sure if this is desirable default behaviour, or if it should be called on a per-npc instance by the user.