[VM] Advanced Technical Matters

Librarian: HexCode
Post Reply
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

[VM] Advanced Technical Matters

Post by HexCode »

CONTENT LINKS
==============

Introduction
viewtopic.php?f=100&t=536#p8929

Establishing True Causation
viewtopic.php?f=100&t=536#p11357

Settings: Accessibility, Role & Scope
viewtopic.php?f=100&t=536#p12053

Limitations Typology
viewtopic.php?f=100&t=536#p8930

Data Errors: "Interpret" or "Crash" ?
viewtopic.php?f=100&t=536#p8931

Hex-Editing... Dialog
viewtopic.php?f=100&t=536#p8932

Hexadecimal Code... Surgery (Part I)
viewtopic.php?f=100&t=536#p8933

Hexadecimal Code... Surgery (Part II)
viewtopic.php?f=100&t=536#p8934

Engine Hexadecimal Character Strings
viewtopic.php?f=100&t=536#p8935

Variable Names Are Case Sensitive
viewtopic.php?f=100&t=536#p11309

Play System Features Subject To Randomization
viewtopic.php?f=100&t=536#p10951


===================================================================

The topic's contents may be modified or progressively added upon as time goes by.

===================================================================

INTRODUCTION
==============

This topic should be of interest to Veteran Modders (VMs). It is assumed that the reader is already intimately familiar with the information featured here:

[NP] Introductory Documentation
viewtopic.php?f=100&t=531

Also, kindly review:

Introduction
viewtopic.php?f=100&t=535#p8923

VMs mightily depend on PGF's Veteran Modder Interface (VMI). PGF's VMI comprises PGF's NMI in its entirety and much more.

VMs seldom run out of new technical discoveries and design "tricks". PGF's VMI is essentially open-ended and constantly enables technical novelties applicable to "ambitious" custom content design, including the judicious hex-editing of PGF's binary files.

Most VMs can be described as computer "power users".
Last edited by HexCode on 2021-12-02 14:40, Thursday, edited 9 times in total.
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

LIMITATIONS TYPOLOGY

Post by HexCode »

LIMITATIONS TYPOLOGY
=====================

Every wargame title sports all kinds of limitations. PGF is no exception.

Visual Presentation Limitations

This is the easiest limitation type to spot. In general, what one sees is not necessarily accurately reflective of the... truth.

Take a unit's Experience Level (i.e., "Stars"), for instance. PGF's User Interface (UI) provides us with five (5) stars which are subject to being appropriately turned on. However, a unit's custom specification certainly allows for more than 599 Experience Points. These points are readily visible to the user via invocation of the unit's information panel.

Memory Buffer Limitations

Software memory buffers are finite. Therefore, it is always possible that some... overambitiously "large" specification will breach the buffer and cause the software to ignominiously crash.

I have not yet (?) experienced PGF crashing due to this sort of limitation.

Quantitative Data Encoding Limitations

PGF accommodates a mixture of 8, 16 & 32-bit quantitative data encoding formats. Therefore, depending on the particular encoding format, the following ultimate upper limits apply:

Code: Select all

Encoding     Upper Limit      Upper Limit
Format       Hexadecimal      Decimal

 8-bit             FF                255
16-bit           FFFF              65535
32-bit       FFFFFFFF         4294967295
Take PGF's Nationality Ownership index, for instance. The relevant SSI encoding format "borrowed" by PGF's Programmer is 8-bit. Therefore, the index can never assume values higher than (decimal) 255.

Hard-Coded Data Limitations

Software programming is not picture perfect. Invariably, all kinds of data are hard-coded in executable(s); hence, limitations...

Take PGF's Underlying Terrain typology index, for instance. Its... gory details are hard-coded in PGF's executable. Therefore...
Last edited by HexCode on 2021-06-01 02:12, Tuesday, edited 1 time in total.
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

DATA ERRORS: "INTERPRET" OR "CRASH" ?

Post by HexCode »

DATA ERRORS: "INTERPRET" OR "CRASH" ?
=====================================

Modding under PGF is unavoidably data intensive as well as extensive. This is particularly the case with quantitative data. Unsurprisingly, errors do occur from time to time. We are all human after all...

PGF's Engine "Interprets"

There are many types of data errors which PGF's engine "usefully interprets" and, thereby, "happily" continues with the game.

Take PGF's Underlying Terrain index, for instance. If PGF's engine comes across an index value higher than (decimal) 39, it immediately "interprets" it to "mean" (decimal) 0.

PGF's Engine "Crashes"

Well, sometimes, PGF's engine gets... "angry" and crashes the game. In other words, there are error types which PGF's engine is not inclined to... "forgive".

Take the unit specifications in some scenario-specific file *.PGSCN, for instance. If PGF's engine comes across an index value higher than the one corresponding to the last equipment entry in file EQUIPMENT.PGEQP, it promptly crashes without offering much of an... explanation, let alone, some "apology". :)
Last edited by HexCode on 2021-06-01 02:13, Tuesday, edited 1 time in total.
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

HEX-EDITING... DIALOG

Post by HexCode »

HEX-EDITING... DIALOG
=====================

I wanna do X.

Can't X be done at the Scenario / Campaign Specification level ?

I'm afraid not. I've tried and tried...

Did you try FPGE ?

Yes, I did. No dice.

Ok, can you handle a hex editor ? I hope you can !

Yeah, no problem.

Cool. Are you reasonably familiar with binary file Y's internal structure ? I do hope you are !

Yeah, I sort of know my way around it...

Super. Just pinpoint the applicable code bytes (if any) and let your modding... rip ! :lol

Ok, I'll try.

Look, I know. This is quite tedious, technical work. It all depends on how much trouble you're prepared to go to to try accomplishing X, right ?
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

HEXADECIMAL CODE... SURGERY (Part I)

Post by HexCode »

HEXADECIMAL CODE... SURGERY (Part I)
============================

Passive vs. Active Code

Content definition binary files such as *.SET, *.STM and MAPNAMES.STR contain passive code. On the other hand, PGFOREVER.EXE contains lots of active code and some passive code as well. It is the active code that does all the processing. The purpose of the passive code is to be selectively accessible by the active code in support of the latter's processing.

Passive Code Externalization

Content definition binary files are sometimes referred to as "external". The idea here is to effectively separate the active code present in PGFOREVER.EXE from all passive code. Ideally, all passive code should be "externalized". That said, PGFOREVER.EXE does contain quite a bit of passive code. There is no need to speculate why PGFOREVER.EXE is anything but... "ideal" !

Code Fragments vs. Code Subroutines

A code subroutine is an active code fragment that is "self contained" in a processing sense. On the other hand, a code fragment is just that, a... fragment !

Integer Constants

From a hexadecimal code... surgeon's perspective (i.e., "learned" hacker :) ), hex-editing integer constants is an entry level job. :) PGF's hexadecimal code sports three (3) hexadecimal representation formats (in bytes) of such constants:

Code: Select all

 8-bit Format || "ST"          meaning  STh
16-bit Format || "ST UV"       meaning  UVSTh
32-bit Format || "ST UV WX YZ" meaning  YZWXUVSTh
where "h" means "hexadecimal" number.

Examples:

Code: Select all

"0F"          ==> 0Fh       ==> Fh (15d)
"0A 21"       ==>           ==> 210Ah (8458d)
"05 0B 01 00" ==> 00010B05h ==> 10B05h (68357d)
where "d" means "decimal" number.

Windows' Calculator is fully capable of converting hexadecimal numbers to decimal numbers and vice versa.

As can be surmised by the preceding examples, when hexadecimal numbers are expressed in their standard mathematical format, leading zeroes can be dropped. It is important to remember though that, as encountered in PGF's hexadecimal code, integer constant specifications always appear in reverse byte order.

Dumb Text

Once again, from a hexadecimal code... surgeon's perspective, hex-editing dumb text is an entry level job as well. :) Invariably, dumb text is embedded into binary files for the purposes of User Interface (UI) or Modder Interface (MI) display. PGF's binary files contain quite a few dumb text entries.

Two representative examples:

PGFOREVER.EXE : Its dumb character content is discussed here:

Engine Hexadecimal Character Strings
viewtopic.php?f=100&t=536#p8935

MAPNAMES.STR : Its file Format has been "borrowed" from SSI.

Starting at the third (3rd) byte, this file Format accommodates records appearing one after another, in strict sequential order, without any gaps. Each such record is housed within a twenty (20) byte long array dedicated to it. In contradistinction to PGF's engine where characters are expressed in 16-bit Format, all records encountered in file MAPNAMES.STR are expressed in 8-bit Format. Consequently, the NULL character is represented by an 8-bit "code unit" in which all of the bits are set to 0 ("00"). NULL termination works exactly like in the case of 16-bit Format character strings.

To illustrate:

Code: Select all

46 6F 72 74 69 66 69 63 61 74 69 6F 6E 00 00 00 00 00 00 00
accommodates the (alphanumeric) character string "Fortification". The hexadecimal code reflects the usual ASCII Character Set conventions. In other words, each byte unambiguously corresponds to some specific alphanumeric character. The right hand tail comprising a number of adjacent "00" (i.e., NULL) bytes is just ignored by the software.

More to the point:

Code: Select all

46 6F 72 74 69 66 69 63 61 74 69 6F 6E 00 4D 61 6C 74 61 00
still accommodates the (alphanumeric) character string "Fortification". Upon encountering the first "00" byte, as the software serially "reads" bytes going from left to right, "reading" immediately stops (i.e., Null Termination). Therefore, code fragment

Code: Select all

4D 61 6C 74 61 00
is never "read". Sometimes, "geeks" justifiably refer to such code fragments as... "garbage".

Smart Text

From a hexadecimal code... surgeon's perspective, hex-editing smart text is not always an entry level job. :) Invariably, smart text is embedded into binary files for all sorts of processing purposes. PGF's executable contains quite a few smart text entries. A very common type of smart text is a variable's Alphanumeric descriptor.
Last edited by HexCode on 2021-06-01 02:17, Tuesday, edited 3 times in total.
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

HEXADECIMAL CODE... SURGERY (Part II)

Post by HexCode »

HEXADECIMAL CODE... SURGERY (Part II)
============================

Rewriting Subroutines

This is the ultimate hex-editing challenge, of course. Such hexadecimal... surgery is not for the faint of heart ! Hex-editing constants and dumb text are one thing, for sure; hex-editing live code is quite another...

Hex-editing live code can never be subject to precise rules and approaches. It is more like a digital... art form. Nevertheless, the following general guiding principles may be worth mentioning:

1) One picks his target subroutine carefully by making sure that the code that lies outside the target subroutine never directs code execution flow to offsets situated inside the target subroutine (CALLed subroutines excepted).

2) One makes absolutely sure that when he is all finished and done with the... surgery, the target subroutine's length (in bytes) remains unchanged.

3) If the target subroutine contains code which, upon execution, may direct the flow to offsets situated outside the target subroutine, one makes absolutely sure that the pertinent location references are rewritten to reflect the target subroutine's new, internal, hexadecimal realities.

4) Goes without saying, one better ensure that the code's modified logic internal to the target subroutine is robust, especially when it comes to code jumps internal to the target subroutine.
Last edited by HexCode on 2021-06-01 02:18, Tuesday, edited 1 time in total.
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

ENGINE HEXADECIMAL CHARACTER STRINGS

Post by HexCode »

ENGINE HEXADECIMAL CHARACTER STRINGS
======================================

Any VMs curious to "look inside" and, possibly, modify PGF's engine need to know a couple of technical things.

PGF's engine contains a plethora of character strings. A 2-byte "widestring" consists of two consecutive bytes (16-bit format). 2-byte "widestrings" (UTF-16, technically) constitute the native string format of fairly recent vintage MS-Windows OS's. Consequently, such "widestrings" are all around the place...

UTF-16 is a character encoding of the Unicode character set. In UTF-16, each Unicode character is represented by one or (occasionally) two 16-bit “code units” (by comparison, a byte is an 8-bit “code unit”).

By the way, the NULL character in this encoding is represented by a 16-bit "code unit" in which all of the bits are set to 0 ("00 00").

A UTF-16 character string consists of a sequence of 16-bit "code units" and it is a convention of many programming languages that the NULL character marks the end of a character string buffer. In these programming languages, the appearance of a 16-bit NULL will cause the character string to terminate and be defined as such.

To illustrate matters, consider the character string "air". Inside PGF's engine, the very same character string would appear as

Code: Select all

61 00 69 00 72 00 00 00
and be defined as such due to the "terminating" 16-bit NULL character (i.e., Null Terminator).
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

PLAY SYSTEM FEATURES SUBJECT TO RANDOMIZATION

Post by HexCode »

PLAY SYSTEM FEATURES SUBJECT TO RANDOMIZATION
================================================

Preliminaries

PGF's engine utilizes randomization in quite a few cases. Some of the better known such cases are:

Combat Resolution
Weather Determination
Paradrop Air Drift
Submarine Detection & Evasion

Absent the deciphering of the relevant subroutines, it would take quite a bit of statistical analysis to draw solid conclusions.

Pseudo-Randomization Biases

PGF's engine performs pseudo-randomization serially triggered by a "seed" determined by the system clock status at the "initialization" moment. Time honored observations within the context of all kinds of computerized games point to... capriciously frequent and persistent, resultant biases. One can only assume that PGF's engine isn't necessarily... lily-white in this regard !

Formula Types Subject to Pseudo-Randomization

a) A formula which explicitly computes the likelihood (i.e., chance) of a certain event (e.g., Rugged Defense).

b) A formula which contains one or more particular variables subject to probabilistic variability (e.g., Weather Determination).

Predictive Data

In order to "meaningfully inform" the player, PGF's engine often displays predictive data which, upon subsequent pseudo-randomization, may not necessarily materialize as predicted.

Possible Verification Guidance

Sometimes, a formula entailing pseudo-randomization may be known or relatively easy to "decipher". The relative "easiness" derives from the "researcher's" ability to readily inspect the predictive data which PGF's engine is... kind enough to display.

HOWEVER:

There is absolutely no a priori guarantee that the engine's actual, underlying programming conforms to the above mentioned formula...

Unavoidable Trials

Irrespective of whether some verification guidance does exist or not, the statistical verification of outcomes should follow these guidelines:

1) The more the event likelihood (or its complement) deviates from P = 0.50 , the more trials are required. In any case, sample sizes of 50, even 100, trials are statistically insufficient to credibly verify anything !

2) In order to guard against biases usually inherent in an engine serially utilizing the same pseudo-randomization "seed", one should completely close PGF (i.e., "exit", not just "quit") at the end of each trial and start it again to move on to the next trial. In this manner, every trial will (hopefully) be conducted under a different pseudo-randomization "seed".

The Ground May Still Be... Shaky

Even if the statistical analysis results obtained are perfectly accurate, PGF pseudo-randomization's likely biases may just muddy the... battlefield waters; actual play does not consist of... antiseptically separated, repeated trials !
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

VARIABLE NAMES ARE CASE SENSITIVE

Post by HexCode »

VARIABLE NAMES ARE CASE SENSITIVE
=================================

Preliminaries

If one employs a capable hex editor and peeks inside PGF's executable, he is going to come across quite a few references to variable names (i.e., identifiers). Some of these variable names also make an appearance in external support files like *.PGSCN and *.HTM. For example,

*.PGSCN (Part II)
viewtopic.php?f=100&t=562#p9155

features a number of variable name references.

Key Fact

PGF executable's variable name references are case sensitive.

For instance, as far as PGF's engine is "concerned",

Turns per Day
Turns Per Day

are NOT one and the same thing ! :nyet

Why Might This Be Important ?

The importance of case sensitivity manifests itself only in instances where PGF serves as an "ambitious", computerized Content Design & Play Platform (CD&PP). In such cases, PGF's executable is heavily hex-edited to widen its applicability to truly diverse content types. To this effect, hex-editing variable names is par for the course. In addition, all relevant external support files featuring variable name references must be correspondingly and precisely edited as well.
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

ESTABLISHING TRUE CAUSATION

Post by HexCode »

ESTABLISHING TRUE CAUSATION
============================

The Black Box

Whether notes constituting a sort of board wargame specification to underlie PGF's actual coding exist or ever existed is anyone's guess. What is definitely known is a... negative. After ten years or so since the software's "public" release, PGF's source code continues being kept away from the public domain. This renders PGF's play system a black box which, nevertheless, may be "deciphered" (at least partially) and subsequently documented, after all.

"Researching" the executable's active code subroutines (in hexadecimal) has barely gotten off the ground. To this effect, quite a few aspects of PGF's underlying play system are currently opaque and must be "discerned" via controlled experimentation.

Key Conceptual Challenges

By way of an example, consider the following statement:
The preceding "trick" highlights a very important aspect of "advanced" modding know-how. Not everything is necessarily a Unit Class property. It could be, say, a Target Type property in conjunction with "something else" (or not).
So, what is it that makes some "rule" a "property" attaching to "attribute X" ? On top, is the "rule" a "property" or just an "exception" ? This is not a course in... empirical epistemology, of course ! Practically speaking, though, the simultaneous presence of one or more "something elses" circumscribes some concretely observable play system behavior. What about true causation though ?

Detailed Illustration

Let us take the following "foundational" play system Rule:

Units can move first and then attack or vice versa.

A case could be made that the Rule is a Property attaching to PGF's play system in toto. BUT, Artillery and Air Defense Class units which move first cannot subsequently attack. This looks like a couple of Exceptions. Why ? Because all the other Unit Classes appear to conform to the Rule. On the face of it, the "many" may as well dictate the way the Rule is viewed.

However, what is known about the behavior of those "many" ? Apparently, plenty ! Reasonable familiarity with SSI's "flagship" content has directly resulted in the acquisition of the following unsurprising knowledge:

--- All Air Super-Class Units (with the possible exception of self-contained Air Transport Class units) conform to the Rule.

--- All Naval Super-Class Units (with the possible exception of Aircraft Carrier and self-contained Naval Transport Class units) conform to the Rule.

--- All Ground Super-Class Units (with the confirmed exception of Artillery and Air Defense Class units and the possible exception of Structure Class units) conform to the Rule.

At this point, some modder may exclaim: "Who cares ? I'm essentially emulating SSI. Therefore, I don't go for... exotic stuff". Fair enough. The modder focuses on what he likes. Actually, the Librarian does exactly the same. Unlike the modder, he aims for "research" completeness at a minimum.

Now, careful "research" has established that:

A) The Structure Unit Class does follow the Rule.

B) Air and Naval Transport Class units are prohibited from initiating attacks on enemy Targets irrespective of any positive, custom Attack values. Since attack initiation is not possible, move / attack order is a moot point. These are not Exceptions to the Rule. They are more like "abstentions"...

C) The Aircraft Carrier Unit Class also constitutes an "abstention".

Detailed Illustration Rule Characterization

Out of EIGHTEEN (18) Unit Classes, there are:

1) THIRTEEN (13) Unit Classes which follow the Rule.

2) TWO (2) Unit Classes which constitute Exceptions to the Rule.

3) THREE (3) Unit Classes which constitute "abstentions".

SO, the "many" have it. What exactly is it that the "many" have, though ? Well, a Rule that can be viewed as a Property of PGF's play system in toto; and yes, there are a couple of Exceptions to the Rule.

Detailed Illustration Exception Characterization

Imagine an... advocate for one or both Exceptions. He could say:

Ok, gentlemen, some of you Veteran Modders come to me always asking this and that about my beloved Unit Class(es). As far as I am concerned, you are asking about specific Unit Class Properties, not Exceptions. Frankly, I do not give a hoot about PGF's play system in toto. You want a Property dear to my heart ? Here it comes:

Artillery / Air Defense Class units cannot initiate attacks subsequent to their moving.

There.


The challenge remains, though. One has to be very careful about what truly causes what...

SSI "Flagship" Content Players & Modder Emulators

Focusing on SSI's "flagship" content does provide players and modder emulators with considerable familiarity with what they might view as PGF's play system. However, what they might perceive as causation may just be fortuitous correlation.

For instance, enemy unit adjacency which blocks new unit purchases actually checks for Target Type; not for Unit Class. Yet, unless one "experiments", say, with Fighter Class units being assigned a... Soft Target designation, he may never "discover" what the source code is really like in such instances. In other words, a modder who never ventures too far away from SSI's "flagship" content paradigm may keep on happily modding on the basis of his "observed" Unit Class behavior; not his... "problem", of course.

By the way, some experimentation within the context of custom content emulating SSI's "flagship" one is both desirable as well as not particularly difficult to carry out. For example, SSI's content designers kept quite a few unit Attack values at ZERO (0). A lot can be learned and, hopefully, put to good use by specifying positive values and observing the resulting battlefield behavior.

Play System "Researchers"

"Research" in this area is never a walk in the park. It requires patience and a penchant for controlled experimentation. Most importantly, such "research" cannot be usefully pursued unless the "researcher" dissociates his expectations, even prejudices (if any), from his experience with any specific content type playable under PGF.

Earlier under this post, it was stated that Artillery / Air Defense Class units cannot initiate attacks subsequent to their moving in the same half-turn. How was this established ? Well, a number of plausible hypotheses were formulated and tested via very carefully controlled experimentation. For the sake of illustration, here is one of those plausible hypotheses: What if the preceding "asymmetrical" behavior is due to such units "normally" being capable of initiating attacks via ranged fire ? So, what would happen if these units were to be assigned Shooting Ranges with value ZERO (0) ? In this particular case, the plausible hypothesis has been experimentally disproven. However, it is hoped that the reader does get the drift here...

In a nutshell, establishing true causation within the context of a... black box mechanism is always akin to dealing with a very... capricious, beautiful woman ! :)
User avatar
HexCode
First Lieutenant
First Lieutenant
Posts: 923
Joined: 2019-09-30 18:54, Monday

SETTINGS: ACCESSIBILITY, ROLE & SCOPE

Post by HexCode »

SETTINGS: ACCESSIBILITY, ROLE & SCOPE
====================================

File Settings

PGF's settings are contained in:

--- Its Text-Formatted External Support Files (i.e., EQUIPMENT.PGEQP, *.PGSCN, PG.PGCAM)

--- File PGFOREVER.EXE (i.e., PGF's executable)

Settings: Accessibility

It is quite easy to access the settings encountered in PGF's Text-Formatted External Support Files. All one needs is a text editor that "can work" with the UTF-16 Little Endian format (which employs Soft Tab Delimiters).

Explicitly identifying settings in the executable's hexadecimal code is anything but easy. However, one can always logically conclude that the code does feature this or that particular setting "somewhere".

Settings: Role & Scope

There is a major difference in the way one approaches settings encountered in PGF's Text-Formatted files versus those logically residing within the executable's code. The former can readily be experimented with by directly modifying their values and observing the resulting changes (if any). Barring precise, surgical hex-editing, the latter must be taken as immutable givens. To this effect, determining those settings' roles and scope can only be accomplished through careful, controlled experimentation involving sharply targeted modifications to the "test" content.

Experimentation Example

Some time ago, a hobbyist attempted to "construct" an Artillery-like unit capable of inflicting lasting suppression onto enemy units. In order to do so, he assigned the Artillery-like unit to the Level Bomber Unit Class. Upon attempting to test the efficacy of his "construct" he immediately found out that PGF's engine just refused to cooperate. Simply put, the intended bombardment was just not allowed.

Where is the relevant "setting" here ? Clearly, it resides within the engine's code ! However, what exactly does the "setting" control ? Well, the "setting" is a prohibition.

An Air Super-Class unit is NOT allowed to attack a Surface Target unless both of them are collocated ON / OVER the same hex.

The hobbyist's eminently reasonable and definitely commendable experimentation ran afoul of an engine-imposed prohibition of a rather sweeping nature; that is, transcending the Level Bomber Unit Class particularities.
Post Reply