ProjectsWhat's NewDownloadsCommunitySupportCompany
Forum Index » S.T.A.L.K.E.R.: Shadow of Chernobyl Forum » Mod discussion
Packets and cse_abstract_properties

Posted by/on
Question/AnswerMake Newest Up Sort by Descending
  06:02:08  23 December 2012
profilee-mailreply Message URLTo the Top
NatVac
Senior Resident
 

 
On forum: 06/15/2007
Messages: 4302
>> The packet utility functions I use are irrelevant and work.

They are also undefined from a code review perspective. This kind of statement bothers me a little bit; 90% of folks who say this have an error in code or assumption, but you usually know your stuff, Alundaio.

>> This altered STATE_Write function works 100% with no errors but the properties aren't saved.

Well, they don't seem to be in what you've shown. You've taken the data from the object and put it into a packet for manipulation via STATE_Write(), but there is no corresponding STATE_Read() to put the changed data back into the object. Or at least it is not visible in the function you've posted.

My guess is that this is not the function of interest. You've just put the manipulation into the function that extracts the data from the object. What does the function that updates the object with the modified data look like?

I vaguely recall that there were some differences between SoC and CS/CoP on packet manipulation, though.
  19:31:52  24 December 2012
profilee-mailreply Message URLTo the Top
NatVac
Senior Resident
 

 
On forum: 06/15/2007
Messages: 4302
I see the necessary lines including the STATE_Read() now.

Okay, we have several areas that could use some clarity. I'm not known for my ability to communicate what I know (or think I know), but here's an attempt:

A lot of this you already know, Alundaio, but others might benefit. In the comments below, "you" represents a generic modder or programmer.

Lua is the script engine. The game engine is written primarily in C++. There is a Lua C/C++ API used by the game engine to "talk" with Lua. C++ data structures are called userdata by Lua, and Lua cannot modify this data directly.

Game objects are userdata. This means you cannot modify these objects directly via Lua. To change a userdata variable, you have to use a C++ function.

For file and network I/O, the game engine uses net_packet, a data streaming class. The reader class is a subset of net_packet with extensions* that emulate the file/stream I/O functionality familiar to many C/C++ programmers like seek, tell and eof.

The game uses these packet structures to read/write save files and for multiplayer support over the network.

When you modify a "packet", you are actually using an instance of the net_packet class, a structure with associated member functions to read/write/update itself. But the packet is a different form of the data it represents, a form suited to storage and transport. It is NOT the game object; modifying the packet will change it on disk (assuming the packet data is eventually flushed via a "save" action) but will not change the game object at that time. (Save/load might work.)

By their names, STATE_Write() and STATE_Read() help you understand what is going on. You use STATE_Write() to write the state of a game object to a packet, and STATE_Read() to read/define the state of a game object from a packet.

This allows you to obtain the otherwise-untouchable userdata by writing the info to a packet and seeking/streaming the data from that into variables/structures that Lua can modify. Writing the updated info back to the packet is part of the update process, but the object itself is not changed until the STATE_Read() call.

Now, here are a couple of thoughts regarding your particular issue, Alundaio.

A while back some folks tried to use the ZRP dynamic level changer code for SoC to add LCs to CoP. But it didn't work. I speculated that it might be due to a difference in how CoP read/wrote the data. I think it was mnn who determined what that difference was: the starting offset was different between read and write, or something like that. This might be a factor in making changes, even after you use STATE_Read(). You don't know what the engine is doing under the covers.

Also: While Lua coroutines take turns, there is no guarantee of C++ thread safety, no locking, no semaphores, no nothing between Lua and C++. You have to provide it. I am not sure the devs have anything in place for this.

So while you are updating your packet, C++ can be updating your game object. That dog just touched an anomaly, or that NPC just switched weapons or reloaded or maybe even died, so the weapon is no longer his.

When you write back the packet, you may be greeted with a single line: "Stack trace:"

---QUOTATION---
Do you know if it is indeed possible to alter abstract properties? It seems they are overwritten but Mnn claimed you could do it during STATE_Write.
---END QUOTATION---


I have no idea. I've not attempted to do so, and such attempts are the primary teaching method at my school-of-hard-knocks. The fact that there is a discrepancy between reads and writes in CoP is not encouraging.

__________
*The SoC lua_help.script file is a generated file (and very outdated with both missing and erroneous data; it might be based on retail 1.0) that might only output what was used by the game, so the extensions might be a normal part of the net_packet class.
  08:44:48  15 January 2013
profilee-mailreply Message URLTo the Top
Vintar
a bit of this and a lot of that
(Resident)

 

 
On forum: 08/08/2008
Messages: 6349
Interesting stuff but not sure what thia has to to wit SOC.
  00:59:13  9 February 2013
profilee-mailreply Message URLTo the Top
NatVac
Senior Resident
 

 
On forum: 06/15/2007
Messages: 4302

---QUOTATION---
@NatVac: It turned out I was correct in my assumption to not use STATE_Read. Apparently I wasn't writing the altered abstract data to the packet before I called STATE_Write.
---END QUOTATION---


Yes, you were able to directly manipulate the object itself via its properties and methods. It's been my (inexperienced) experience that SoC items instantiated via alife():create() were not immediately modifiable, so the STATE_Read was useful.

And as you found out (heh, STATE_Read is called before STATE_Write)*, you needed to do some additional testing in CoP to know when you could actually make the change you wanted to make, as the packet size would change, at least for the actor object. "The fact that there is a discrepancy between reads and writes in CoP is not encouraging." That sounds like this kind of design discrepancy was contributing confusion while you looked for the root cause of your issue.

I'm under the impression that the developers who took over when the initial engine team left got a lot of direction from modders of the original game. CS and then CoP seem to reflect several design philosophies for the same entities.

It is good you got your problem resolved, but I think Vintar was asking because folks have been accessing abstract properties in SoC objects via barin's packet_utils.script for at least three years, so this really was a CoP problem. You were asking here to see if anyone here could help. In the end you did it the way most of us do: you figured it out yourself.

__________

---QUOTATION---
*"se_actor:STATE_Write and STATE_Read corruption":
https://www.gsc-game.com/main.php?t=community&s=forums&s_game_type=xr3&thm_id=5771&sec_id=18
---END QUOTATION---

  12:10:45  18 February 2013
profilee-mailreply Message URLTo the Top
NatVac
Senior Resident
 

 
On forum: 06/15/2007
Messages: 4302
Thanks for your patience, Alundaio.

---QUOTATION---
Packet_utils has no ability to alter cse_abstract_properties unless you know the steps I've provided here.
---END QUOTATION---


It might not have the ability even if you follow those steps, as there is no corresponding write_abstract_properties() function in the three-year-old copy of the script I have and read_abstract_properties() just prints debug info. That's why I said "accessing", not "manipulating" in my reply above. It is quite possible those capabilities were added later, though.

Let's assume we have that functionality or have added it. There would also be a step 0:

0. Add this block to the se_*.script for the object class you are interested in manipulating, just after the function se_*:STATE_Write(packet) line:
__________
	if (self.repack) then
		local data = packet_utils.read_abstract_properties(packet)
		if (data) then
			for k,v in pairs(self.repack) do
				data[k] = v
			end
			-- note order of parameters here; change if needed
			packet_utils.write_abstract_properties(packet, data)
			self.repack = nil
		end
	end

¯¯¯¯¯¯¯¯¯¯

---QUOTATION---
You can only read/alter the cse_abstract_properties within the script version se_*:STATE_Write function before calling the base class STATE_Write.
---END QUOTATION---


That's not strictly true, at least in SoC. All accessible (i.e., script-based) SoC se_*:STATE_Write() functions start with a call to the corresponding cse_*:STATE_Write() function with the same packet that was passed in to the function. If we have the packet -- and we usually do at the point where we are modifying the abstract data -- we could conceivably skip step 0 above, and change step 2 as follows:

2. Update the abstract info

local data = packet_utils.read_abstract_properties(packet)
if data then
	data.direction = vector():set(0,1,0)
	packet_utils.write_abstract_properties(packet, data)
end


This avoids having to modify any se_*.script directly for a limited-use function.

And it would be quite limited-use for me. I can see the value for this in modifying smart_covers, but SoC doesn't have them. Setting direction via packet on script-spawned NPCs may not be that useful; one needs to add logic anyway or they will wander off. As for the rest of the abstract data info, it really is abstract data. The name is not something a player would directly see (that's character_name) and the developer can use the original name as is. (Strange that you can't change it, though.)

This might explain why no one doing SoC-only script-spawning has complained about any abstract-data limitations of packet_utils.script.
  13:37:09  27 November 2013
profilee-mailreply Message URLTo the Top
Alundaio
Sad Clown
(Resident)

 

 
On forum: 04/05/2010
Messages: 2230
Does anyone have a copy of Red75's fake_net_packet.script? If so, can you pastebin it for me?
  14:22:21  27 November 2013
profilee-mailreply Message URLTo the Top
SacriPan
Senior Resident
 

 
On forum: 09/20/2009
Messages: 319

---QUOTATION---
Does anyone have a copy of Red75's fake_net_packet.script? If so, can you pastebin it for me?
---END QUOTATION---




Hi,

From Oblivion Lost 2.2:
http://rghost.net/50480441
  14:53:16  27 November 2013
profilee-mailreply Message URLTo the Top
Alundaio
Sad Clown
(Resident)

 

 
On forum: 04/05/2010
Messages: 2230
Thank you very much.
 
Each word should be at least 3 characters long.
Search:    
Search conditions:    - spaces as AND    - spaces as OR   
 
Forum Index » S.T.A.L.K.E.R.: Shadow of Chernobyl Forum » Mod discussion
 

All short dates are in Month-Day-Year format.


 

Copyright © 1995-2021 GSC Game World. All rights reserved.
This site is best viewed in Internet Explorer 4.xx and up and Javascript enabled. Webmaster.
Opera Software products are not supported.
If any problem concerning the site functioning under Opera Software appears apply
to Opera Software technical support service.