diff --git a/scores.csv b/scores.csv
index 71c59b0dba547a3654af6140e251f6aaee7a1528..04008fa624119ca025fb3dd1127ea9e6e7e4b12a 100644
--- a/scores.csv
+++ b/scores.csv
@@ -1,3 +1,4 @@
 BugBuster;264;EASY
 ClusterChampion;127;MEDIUM
 BugBuster;264;EASY
+BugBuster;2640000;HARD
diff --git a/src/main/java/lab/MyEdit.java b/src/main/java/lab/MyEdit.java
new file mode 100644
index 0000000000000000000000000000000000000000..07b46a578c37fea172e98f2dcb3e3d94c6d08755
--- /dev/null
+++ b/src/main/java/lab/MyEdit.java
@@ -0,0 +1,13 @@
+package lab;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface MyEdit {
+    public boolean readOnly() default false;
+    public boolean visible() default true;
+}
diff --git a/src/main/java/lab/data/Score.java b/src/main/java/lab/data/Score.java
index 2be798381f3f0f0634acc64df29fa574b38e4ee7..c4b003bd511d1233f05a04be66774ae74d68d5fe 100644
--- a/src/main/java/lab/data/Score.java
+++ b/src/main/java/lab/data/Score.java
@@ -8,6 +8,7 @@ import jakarta.persistence.Enumerated;
 import jakarta.persistence.GeneratedValue;
 import jakarta.persistence.GenerationType;
 import jakarta.persistence.Id;
+import lab.MyEdit;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.EqualsAndHashCode;
@@ -30,13 +31,20 @@ public class Score {
 	
 	@Id
 	@GeneratedValue(strategy = GenerationType.AUTO)
+	@MyEdit(visible = false)
 	private Long id;
+	@MyEdit(readOnly = true)
 	private String name;
+	@MyEdit
 	private int points;
 	@Enumerated(EnumType.STRING)
+	@MyEdit
 	private Level level;
 	
-	
+	public String getVirtual(){
+		return "aaaa";
+	}
+
 	public static Score generate() {
 		return new Score(null, getRandomNick(), RANDOM.nextInt(50, 300), Level.values()[RANDOM.nextInt(Level.values().length)]);
 	}
diff --git a/src/main/java/lab/gui/EditController.java b/src/main/java/lab/gui/EditController.java
index 2d386b3c6a0268c3f8b53ef38bf856223cb40bc8..815f2da8480b4642188a3c2e20715394b22a05c7 100644
--- a/src/main/java/lab/gui/EditController.java
+++ b/src/main/java/lab/gui/EditController.java
@@ -1,7 +1,14 @@
 package lab.gui;
 
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.ResourceBundle;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -14,6 +21,7 @@ import javafx.scene.control.Label;
 import javafx.scene.control.TextField;
 import javafx.scene.layout.GridPane;
 import javafx.stage.Stage;
+import lab.MyEdit;
 import lab.data.Score;
 import lombok.Setter;
 
@@ -50,7 +58,50 @@ public class EditController {
 
 	@FXML
 	void btnOkAction(ActionEvent event) {
-		//TODO: add code to read values from text fields
+		try {
+			BeanInfo beanInfo = Introspector.getBeanInfo(data.getClass());
+			for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
+				try {
+					String name = propertyDescriptor.getName();
+					Field field = data.getClass().getDeclaredField(name);
+					MyEdit myEdit = field.getAnnotation(MyEdit.class);
+					if(myEdit == null || !myEdit.visible() || myEdit.readOnly()) {
+						continue;
+					}
+					TextField textField = nameToTextField.get(name);
+					String stringValue = textField.getText();
+					Object value = null;
+					if (propertyDescriptor.getPropertyType() == String.class) {
+						value = stringValue;
+					} else if (stringValue == null || stringValue.isBlank()) {
+						value = null;
+					} else if (propertyDescriptor.getPropertyType() == Integer.class
+							|| propertyDescriptor.getPropertyType() == int.class) {
+						value = Integer.parseInt(stringValue);
+					} else if (propertyDescriptor.getPropertyType() == Long.class
+							|| propertyDescriptor.getPropertyType() == long.class) {
+						value = Long.parseLong(stringValue);
+					} else if (propertyDescriptor.getPropertyType() == Double.class
+							|| propertyDescriptor.getPropertyType() == double.class) {
+						value = Double.parseDouble(stringValue);
+					} else if (propertyDescriptor.getPropertyType().isEnum()) {
+						for (Object enumConstant : propertyDescriptor.getPropertyType().getEnumConstants()) {
+							if (enumConstant.toString().equalsIgnoreCase(stringValue)) {
+								value = enumConstant;
+								break;
+							}
+						}
+					}
+					if (propertyDescriptor.getWriteMethod() != null) {
+						propertyDescriptor.getWriteMethod().invoke(data, value);
+					}
+				} catch (NoSuchFieldException e) {
+					log.warn("property {} has no field", propertyDescriptor.getName());
+				}
+			}
+		} catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
+			log.error(e);
+		}
 		
 		gameController.updateData((Score)data);
 		stage.hide();
@@ -71,7 +122,32 @@ public class EditController {
 		log.info("data set {}", data);
 		content.getChildren().clear();
 		
-		//TODO: code to detect properties and add rows to dialog  
+		ResourceBundle msg = ResourceBundle.getBundle("msg");
+		try {
+			BeanInfo beanInfo = Introspector.getBeanInfo(data.getClass());
+			int row = 0;
+			for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
+				try {
+					Field field = data.getClass().getDeclaredField(propertyDescriptor.getName());
+					MyEdit myEdit = field.getAnnotation(MyEdit.class);
+					if (myEdit == null) {
+						continue;
+					}
+					if (!myEdit.visible()) {
+						continue;
+					}
+					String name = propertyDescriptor.getName();
+					Object value = propertyDescriptor.getReadMethod().invoke(data);
+					String localizedName = msg.getString(String.format("%s.%s", data.getClass().getSimpleName(), field.getName()));
+					addDialogRow(row, name, localizedName, value != null ? value.toString() : "", !myEdit.readOnly());
+					row++;
+				} catch (NoSuchFieldException e) {
+					log.warn("property '{}' has no field in class '{}'", propertyDescriptor.getName(), data.getClass().getCanonicalName());
+				}
+			}
+		} catch (IntrospectionException | InvocationTargetException | IllegalAccessException e) {
+			log.error(e);
+		}
 	}
 
 	private void addDialogRow(int rowNumber, String name, String descriptionName, String stringValue,
diff --git a/src/main/resources/lab/gui/application.css b/src/main/resources/lab/gui/application.css
index 7f0e980478ac54ba9285d55c081a99e94305ece5..b317217cccab60767843f4b7503af00c6f62d474 100644
--- a/src/main/resources/lab/gui/application.css
+++ b/src/main/resources/lab/gui/application.css
@@ -22,7 +22,7 @@ Label {
 	-fx-background-color:RGB(0.0,0.0,100.0);
 }
 #menuPanel {
-	-fx-background-image:url("lochness-background.jpg");
+	-fx-background-image:url("game-background.jpg");
 	-fx-background-size: stretch;
 }
 
diff --git a/src/main/resources/lab/gui/game-background.jpg b/src/main/resources/lab/gui/game-background.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1875d2d18f49694c7e07858ffc4bf2eece5c1e39
Binary files /dev/null and b/src/main/resources/lab/gui/game-background.jpg differ
diff --git a/src/main/resources/msg.properties b/src/main/resources/msg.properties
new file mode 100644
index 0000000000000000000000000000000000000000..d0655f9afcee79b8fb8c5a4087d2d2b38292a47d
--- /dev/null
+++ b/src/main/resources/msg.properties
@@ -0,0 +1,5 @@
+
+Score.id     = id
+Score.level  = level
+Score.name   = name
+Score.points = points
diff --git a/src/main/resources/msg_cs.properties b/src/main/resources/msg_cs.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e397613b223ead974bf36a1be69512c88c897149
--- /dev/null
+++ b/src/main/resources/msg_cs.properties
@@ -0,0 +1,5 @@
+
+Score.id     = Jednozna\u010Dn\u00FD identifik\u00E1tor
+Score.level  = Obt\u00ED\u017Enost
+Score.name   = Jm\u00E9no
+Score.points = Body
diff --git a/src/main/resources/msg_cs_CZ.properties b/src/main/resources/msg_cs_CZ.properties
new file mode 100644
index 0000000000000000000000000000000000000000..73f926b653417019db394ae6ac1b0e5a9d5a56ae
--- /dev/null
+++ b/src/main/resources/msg_cs_CZ.properties
@@ -0,0 +1,4 @@
+#Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/)
+
+Score.id     = Jedine\u010Dn\u00FD identifik\u00E1tor
+Score.name   = N\u00E1zev
diff --git a/src/main/resources/msg_en.properties b/src/main/resources/msg_en.properties
new file mode 100644
index 0000000000000000000000000000000000000000..83da6ab577a70580f3495e7d495641b54b61e490
--- /dev/null
+++ b/src/main/resources/msg_en.properties
@@ -0,0 +1,6 @@
+#Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/)
+
+Score.id     = Unique identificator
+Score.level  = Level
+Score.name   = Name
+Score.points = Points
diff --git a/src/test/java/jez04/structure/test/ClassStructureTest.java b/src/test/java/jez04/structure/test/ClassStructureTest.java
index 710d8d2ea19892f30c4545f6abc453ac83eac19e..2e2be8bd0437f77356df9882a1e0553ec44d8a03 100644
--- a/src/test/java/jez04/structure/test/ClassStructureTest.java
+++ b/src/test/java/jez04/structure/test/ClassStructureTest.java
@@ -17,35 +17,24 @@ class ClassStructureTest {
 	// @formatter:off
 	@ParameterizedTest
 	@CsvSource({
-			"Bullet.java,serialVersionUID",
-			"Bullet.java,@Serial",
-			"BulletAnimated.java,serialVersionUID",
-			"BulletAnimated.java,@Serial",
-			"Cannon.java,serialVersionUID",
-			"Cannon.java,@Serial",
-			"Ufo.java,serialVersionUID",
-			"Ufo.java,@Serial",
-			"MyPoint.java,serialVersionUID",
-			"MyPoint.java,@Serial",
-			"WorldEntity.java,serialVersionUID",
-			"WorldEntity.java,@Serial",
-
-			"WorldEntity.java,transient",
-			"BulletAnimated.java,transient",
-			
-			"World.java,new ServerSocket",
-			"World.java,Socket",
-			"World.java,accept",
-			"World.java,ObjectOutputStream",
-			"World.java,writeObject",
-			"World.java,new Socket",
-			"World.java,ObjectInputStream",
-			"World.java,ObjectInputStream",
-			"World.java,synchronized",
+			"Score.java,@MyEdit,4",
+			"EditController.java,Introspector.getBeanInfo,1",
+			"EditController.java,BeanInfo,1",
+			"EditController.java,PropertyDescriptor,1",
+			"EditController.java,getDeclaredField,1",
+			"EditController.java,getAnnotation,1",
+			"EditController.java,\\.readOnly\\(\\),1",
+			"EditController.java,\\.visible\\(\\),1",
+			"MyEdit.java,@interface,1",
+			"MyEdit.java,@Retention,1",
+			"MyEdit.java,RetentionPolicy\\.RUNTIME,1",
+			"MyEdit.java,readOnly\\(\\),1",
+			"MyEdit.java,visible\\(\\),1",
+			"msg(_.*)?\\.properties,points,2",
 		})
 	// @formatter:on
-	void anotaceTest(String file, String annotation) throws URISyntaxException {
-		assertThat(TextFileContains.getProjectRoot(getClass()), new TextFileContains(file, annotation));
+	void anotaceTest(String file, String annotation, int count) throws URISyntaxException {
+		assertThat(TextFileContains.getProjectRoot(getClass()), new TextFileContains(file, annotation).count(count).useRegExpForName(true));
 	}